/* Copyright (C) 1999-2002 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   PARTICULAR PURPOSE.  See the GNU General Public License for more details. */

package artofillusion.texture;

import artofillusion.*;
import artofillusion.math.*;
import artofillusion.object.*;
import artofillusion.ui.*;
import buoy.event.*;
import java.awt.*;
import java.util.Vector;

/** MoveUVViewTool is an EditingTool used for moving the viewpoint in the UV editing window. */

public class MoveUVViewTool extends EditingTool
{
  private static Image icon, selectedIcon;
  private Point clickPoint;
  private Mat4 viewToWorld;
  private Vec3 clickPos;
  private boolean controlDown;
  private CoordinateSystem oldCoords;
  private double oldScale;
  private double minu, maxu, minv, maxv;
  private int vwidth, vheight; 


  public MoveUVViewTool(EditingWindow fr)
  {
    super(fr);
    icon = loadImage("moveView.gif");
    selectedIcon = loadImage("selected/moveView.gif");
  }

  public void activate()
  {
    super.activate();
    theWindow.setHelpText(Translate.text("moveViewTool.helpText"));
  }

  public int whichClicks()
  {
    return ALL_CLICKS;
  }

  public boolean hilightSelection()
  {
/*    if (theWindow instanceof LayoutWindow)
      return false;
    else*/
      return true;
  }

  public Image getIcon()
  {
    return icon;
  }

  public Image getSelectedIcon()
  {
    return selectedIcon;
  }

  public String getToolTipText()
  {
    return Translate.text("moveViewTool.tipText");
  }

  public void mousePressed(WidgetMouseEvent e, ViewerCanvas view)
  {
    Camera cam = view.getCamera();
    UVMappingViewer uvview = (UVMappingViewer) view;

    controlDown = e.isControlDown();
    clickPoint = e.getPoint();
    //clickPos = cam.convertScreenToWorld(clickPoint, cam.getDistToScreen());
    //oldCoords = cam.getCameraCoordinates().duplicate();
    
    minu = uvview.getMinU();
    maxu = uvview.getMaxU();
    minv = uvview.getMinV();
    maxv = uvview.getMaxV();
    
    Rectangle d = uvview.getBounds();
    vwidth = d.width;
    vheight = d.height;

    viewToWorld = cam.getViewToWorld();
    //oldScale = view.getScale();
  }

  public void mouseDragged(WidgetMouseEvent e, ViewerCanvas view)
  {
    Camera cam = view.getCamera();
    //Graphics g = view.getGraphics();
    Point dragPoint = e.getPoint();
    //CoordinateSystem c = oldCoords.duplicate();
    UVMappingViewer uvview = (UVMappingViewer) view;
    int dx, dy;
    double dist;
    Vec3 move;
    Mat4 m;

    dx = dragPoint.x-clickPoint.x;
    dy = dragPoint.y-clickPoint.y;
    //cam.setCameraCoordinates(c);
    if (controlDown)
    {
      if (view.isPerspective())  // TODO(MB) Remove ?
      {
        move = cam.findDragVector(clickPos, 0, dy);
        dist = dy > 0 ? -move.length() : move.length();
        move = (viewToWorld.timesDirection(Vec3.vz())).times(dist*2.0);
      }
      else
      {
	double factor = Math.pow(1.01, dy);
	double midu = (minu+maxu)/2;
	double midv = (minv+maxv)/2;
	
	double newminu = ((minu - midu)/factor) + midu;
	double newmaxu = ((maxu - midu)/factor) + midu;
	double newminv = ((minv - midv)/factor) + midv;
	double newmaxv = ((maxv - midv)/factor) + midv;
	
	uvview.setParameters(newminu, newmaxu, newminv, newmaxv);
        uvview.informChanged(this, ModelEvent.CHANGEDUR_DONTKNOW);
        // view.setScale(oldScale * Math.pow(1.01, dy));
        move = new Vec3();
      }

    }
    else
    {
      if (e.isShiftDown())
      {
	if (Math.abs(dx) > Math.abs(dy))
	  dy = 0;
	else
	  dx = 0;
      }
      double du = (minu - maxu)*dx/vwidth;
      double dv = (maxv - minv)*dy/vheight;
      uvview.setParameters(minu + du, maxu + du, minv + dv, maxv + dv);
      uvview.informChanged(this, ModelEvent.CHANGEDUR_DONTKNOW);
    }
    /*
    m = Mat4.translation(-move.x, -move.y, -move.z);
    c.transformOrigin(m);
    cam.setCameraCoordinates(c);
    view.updateImage();
    view.drawImage(g);
    g.dispose(); */
  }

  public void mouseReleased(WidgetMouseEvent e, ViewerCanvas view)
  {
    mouseDragged(e, view);
    theWindow.updateImage();
    ObjectInfo bound = view.getBoundCamera();
    if (bound != null)
      theWindow.setUndoRecord(new UndoRecord(theWindow, false, UndoRecord.COPY_COORDS, new Object [] {bound.coords, oldCoords})); // (MB) ???
  }
}