/* 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;

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

/** RotateSceneViewTool is a special RotateSceneViewTool for rotating
    the viewpoint around <b>the center of current selection</b>. */

public class RotateSceneViewTool extends RotateViewTool
{
  /** Should the center of selection be used as center of rotation? */
  boolean respectSelectionCenter;
  
  public RotateSceneViewTool(EditingWindow fr, boolean respectcenter)
  {
    super(fr);
    respectSelectionCenter = respectcenter;
  }
  
  /** Finds the center of all selected objects. 
   The function may return null if there is no selected object or if
   {@link #respectSelectionCenter} is set to false */
  
  public Vec3 findSelectionCenter()
  {
    if (!respectSelectionCenter)
      return null;
    
    Scene theScene = theWindow.getScene();
    Vec3 center = new Vec3();
    ObjectInfo info;
    
    int numSelected = 0;
    int[] sel = theScene.getSelection();
    
    if (sel.length == 0)
      return null;
    
    for (int i = 0; i < sel.length; i++)
    {
      info = theScene.getObject(sel[i]);
      if (info.selected)
	center.add(info.coords.getOrigin());
        numSelected++;
    }
    
    if (numSelected > 0)
    {
      center.scale(1.0/numSelected);
      return center;
    }
    else
      return null;
  }
  

  public void mouseDragged(WidgetMouseEvent e, ViewerCanvas view)
  {
    Camera cam = view.getCamera();
    java.awt.Graphics g;
    java.awt.Point dragPoint = e.getPoint();
    CoordinateSystem c = oldCoords.duplicate();
    int dx, dy;
    double angle;
    Vec3 axis;
    Mat4 m;
    
    Vec3 center = findSelectionCenter();

    
    dx = dragPoint.x-clickPoint.x;
    dy = dragPoint.y-clickPoint.y;

    if (controlDown)
      {
	axis = viewToWorld.timesDirection(Vec3.vz());
	angle = dx * DRAG_SCALE;
      }
    else if (e.isShiftDown())
      {
	if (Math.abs(dx) > Math.abs(dy))
	  {
	    axis = viewToWorld.timesDirection(Vec3.vy());
	    angle = dx * DRAG_SCALE;
	  }
	else
	  {
	    axis = viewToWorld.timesDirection(Vec3.vx());
	    angle = -dy * DRAG_SCALE;
	  }
      }
    else
      {
	axis = new Vec3(-dy*DRAG_SCALE, dx*DRAG_SCALE, 0.0);
	angle = axis.length();
	axis = axis.times(1.0/angle);
	axis = viewToWorld.timesDirection(axis);
      }
    if (angle != 0.0)
      {
	if (center == null)
        {
	  m = Mat4.axisRotation(axis, -angle);
        }
	else
        {
	  m = Mat4.axisRotation(axis, -angle, center);
        }
	c.transformCoordinates(m);
	cam.setCameraCoordinates(c);
	view.updateImage();
      }
    g = view.getComponent().getGraphics();
    view.drawImage(g);
    g.dispose();
  }

}