/***********************************
=======================================

File: cookingUtensils.js
Author: Hawkeye King
Date: 03 August 2002

I am a library of cooking utensils.  I include 
things like spatulas for stirring food as it cooks, 
selection tools for selecting SVG objects, moving 
tools for moving selections, and delete functions 
for deleting SVG objects.

=======================================
27 - 8 -2002
Changes by Colm.
mousestate stuff all changed and a load of stuff
put in for rotation.
************************************
=======================================
28 - 8 -2002
Changes by Colm.
bugfix for when the left button is pressed
when rotating.

=======================================
30 - 8 -2002
Changes by Colm.
A few small changes made to the scaling
functions. The transformoffset variable
is now calculated dynamically in the shape
class instead of here.

=======================================
09 - 8 -2002
Changes by Colm.
The eventhandling stuff is changed. The 
mousedown eventcatcher is now gone - everything
works from the click event handler and the
left mouse button to provide more consistency.

=======================================
09 - 12 - 2002
Changes by Hawkeye
I've reshuffled Colms excellent work to make this 
class more orderly.  Specifically all "modes" use a common frame work
where actionSate =  { click0, click1, click2 }, mode methods have been 
assigned a common naming convention of "beginX()", "setX()", "runX()".  Mode
initialization is now performed by "selectToolMode()" and de-activation
is run by "endMode()";

======================================
09-13-2002
Changes by Hawkeye
The select tool drawer now shows up dynamically.

======================================
************************************/


SelectTool.prototype = new EventHandler();
SelectTool.prototype.constructor = SelectTool;
SelectTool.superclass = EventHandler.prototype;

function SelectTool(){
  this.init();
}
SelectTool.prototype.init = function(){
  SelectTool.superclass.init.call();
  this.x = 0;
  this.y = 0;
  this.actionState = "click0";
  this.groupMode = 0;
  this.selectedTool = "dragTool"; 	
}
SelectTool.prototype.drawer = "";


SelectTool.prototype.drawer += '<table border="0" cellpadding="0" cellspacing="3">\n';
SelectTool.prototype.drawer += '  <tr><td><input type="button" value="　　移動　　" onclick="selectTool.selectToolMode(\'dragTool\')"></td>\n';
SelectTool.prototype.drawer += '    <td><input type="button" value="拡大・縮小" onclick="selectTool.selectToolMode(\'scaleTool\')"></td>\n';
SelectTool.prototype.drawer += '    <td><input type="button" value="  回転  " onclick="selectTool.selectToolMode(\'rotateTool\')"></td>\n';
SelectTool.prototype.drawer += '  </tr><tr>\n';
SelectTool.prototype.drawer += '    <td><input type="button" value="グループ化" onclick="selectTool.makeGroup()"></td>\n';
SelectTool.prototype.drawer += '    <td><input type="button" value="部品登録" onclick="savePart()"></td>\n';
SelectTool.prototype.drawer += '    <td><input type="button" value="  削除  " onclick="selectTool.deleteHandler()"></td>\n';
SelectTool.prototype.drawer += '  </tr>\n';
SelectTool.prototype.drawer += '</table><br>\n';



SelectTool.prototype.initTool = function(){
  useCurrentLayer();
  eventCatcher.addEventListener("click", this, false);
  rootElement.addEventListener("mousedown", this, false);
  window.document.getElementById("drawer2").innerHTML = this.drawer;
}
SelectTool.prototype.setGroupMode = function( onOrOff ){
  this.groupMode = onOrOff;
}
// Object has been clicked.
SelectTool.prototype.grabObject = function( evt, obj ){
  evt = (evt) ? evt : ((window.event) ? window.event : "");
 	if (!evt.ctrlKey && !obj.selected){
	  this.deselectAllObjects();
 	}
 	if (!obj.selected){
   	this.selectObject(obj);
 	} else if ( evt.ctrlKey ){
   	this.deselectObject(obj);
 	}
}
SelectTool.prototype.selectObject = function( obj ){
  if ( this.groupMode && obj.group ) {
    for (var i=0;i<obj.group.objectList.length;i++){
      var temp = obj.group.objectList[i];
      var selectGroup = temp.svgNode.parentNode
      selectList.push( temp );
      style = temp.svgNode.getStyle();
      temp.returnStroke= style.getPropertyValue("stroke");
      style.setProperty("stroke", "magenta");
      temp.selected = 1;
    }
  } else {
    selectList.push( obj );
    style = obj.svgNode.getStyle();
    obj.returnStroke= style.getPropertyValue("stroke");
    style.setProperty("stroke", "magenta");
    obj.selected = 1;
  }
}
SelectTool.prototype.deselectAllObjects = function(){
  var k;
  while( k = selectList.pop() ){
    if(k.svgNode){
      k.svgNode.getStyle.setProperty( "stroke", k.returnStroke );
      k.selected=0;
    }
  }
}
// Find an object in selectList
SelectTool.prototype.getIndex = function ( obj ){
  for (var i=0; i<selectList.length;i++){
    if (selectList[i] == obj) {
      return i;
    }
  }  
  return -1;
}
SelectTool.prototype.deselectObject = function(obj){
  var index=this.getIndex( obj );
  if ( index != -1 ) {
    selectList[index].svgNode.getStyle.setProperty( "stroke", selectList[index].returnStroke );
    selectList.splice(index,1);
    obj.selected = 0;
    return 1;
  }
  return 0;
}

// Switch between select tool modes
SelectTool.prototype.selectToolMode = function( toolMode ){
  this.endMode();
  this.selectedTool = toolMode;
  this.actionState = "click0";  
}

// Disable previous select tool mode
SelectTool.prototype.endMode = function(){
  //  debug("ending mode"+this.selectedTool );
  rootElement.removeEventListener("mousemove", this, false);
  rootElement.removeEventListener("mouseup", this, false);
  drawingGroup.removeEventListener("click", this, false);

  if (this.tempLine){
    this.tempLine.destructor();
    this.tempLine = null;
  }
  if (this.tempLine2){
    this.tempLine2.destructor();
    this.tempLine2 = null;
  }
}

////////////////////////////////////////////////
//
// click event handler
//   Powers scale and rotate tools
//
////////////////////////////////////////////////
SelectTool.prototype.click = function(evt){
  if (selectList.length){
    evt = (evt) ? evt : ((window.event) ? window.event : "");
    switch(evt.button) {
    case 0 :					
      switch (this.selectedTool) {
      case "scaleTool" : 
	this.scaleHandler(evt);
	break;
      case "rotateTool" : 
	this.rotateHandler(evt);
	break;
      default :
	this.deselectAllObjects();
	break;
      }
      break;
    case 1 :					
      break;
    default :
      break;
    }
  }
}
//////////////////////////////////////////////////
//
// Mousedown Event Handler
//  Drives the "move" tool
//
///////////////////////////////////////////////////
SelectTool.prototype.mousedown = function(evt) {
  evt = (evt) ? evt : ((window.event) ? window.event : "");
  switch(evt.button) {
  case 0 :					
    switch (this.selectedTool) {
    case "dragTool" :						
      this.dragHandler(evt);
      break;
      default :
	break;
    }
    break;
  case 1 :					
    break;
    default :
      break;
  }
}

///////////////////////////////////////////////
//
// Mouseup and mousemove redefined as necessary.
//
///////////////////////////////////////////////
SelectTool.prototype.mouseup = function(evt){}
SelectTool.prototype.mousemove = function(evt){}

SelectTool.prototype.makeGroup = function ( ){
  //  debug("makeGroup");
  newGroup = new ObjectGroup();
  for(var i=0;i < selectList.length;i++) {
    //  debug("regrouping");
    newGroup.addObject( selectList[i] );
  }
}
////////////////////////////////////////////
//
//	drag functions.
//
////////////////////////////////////////////
// called by click handler
SelectTool.prototype.dragHandler = function(evt){
  if(selectList.length > 0){

    switch ( this.actionState ){
    case "click0":
      this.beginDrag( evt )
      this.actionState = "click1";      
      break;
    case "click1":
      this.endMode();
      this.actionState = "click0";
      break;
    default:
      alert("unknown state");
      break;
    }
  }
}
SelectTool.prototype.beginDrag = function( evt ){
  this.pointFrom = new Point2D(getX(evt), getY(evt));
  // set UI behavior:
  this.mousemove = this.runDrag;
  this.mouseup = this.dragHandler;
  rootElement.addEventListener("mouseup", this, false);
  rootElement.addEventListener("mousemove", this, false);  
}
SelectTool.prototype.runDrag = function(evt){
  evt = (evt) ? evt : ((window.event) ? window.event : "");
	var moveTo = new Point2D( getX(evt), getY(evt) );
	var delta = moveTo.subtract( this.pointFrom );
	this.pointFrom.setFromPoint( moveTo );
	for (var i=0;i<selectList.length;i++)
   	selectList[i].move( delta );

}

/*
SelectTool.prototype.endDrag = function(evt){
  rootElement.removeEventListener("mousemove", this, false);
  rootElement.removeEventListener("mouseup", this, false);
  drawingGroup.removeEventListener("click", this, false);
}
*/

////////////////////////////////////////
//
// scaling functions
//
////////////////////////////////////////
SelectTool.prototype.scaleHandler = function( evt ){

  if(selectList.length > 0){
    switch (this.actionState) {
    case "click0":
      this.beginScale( evt );
      this.actionState = "click1";
      break;
    case "click1":
      this.setScaleLine( evt );
      this.actionState = "click2";
      break;
    case "click2":
      this.endMode( evt )
      this.actionState = "click0";
      break;
    default:
      debug("unknown state");
      break;
    };
  }
}
SelectTool.prototype.initTransform = function(){
  for (var i=0;i<selectList.length;i++){
    selectList[i].initTransform( this.pointFrom );
  }
}
SelectTool.prototype.beginScale = function( evt ){
    this.pointFrom = new Point2D( getX(evt), getY(evt) );
    this.initTransform( this.pointFrom );
    this.tempLine = new Line( this.pointFrom.x, this.pointFrom.y, this.pointFrom.x, this.pointFrom.y, "on", true);
    this.tempLine.tempLine();

    // set UI behavior:
    this.mousemove = this.runScale;
    drawingGroup.addEventListener("click", this, false);
    rootElement.addEventListener("mousemove", this, false);
    //    this.mouseup = this.scaleHandler;
    //    rootElement.addEventListener("mouseup", this, false);

}
SelectTool.prototype.setScaleLine = function( evt ){
    evt = (evt) ? evt : ((window.event) ? window.event : "");
    this.scalex = this.pointFrom.x - getX(evt);
    this.scaley = this.pointFrom.y - getY(evt);
    // stage 2 UI Behavior
    //this.mousemove = this.runScale;
    //this.mouseup = this.scaleHandler;
}
SelectTool.prototype.runScale = function(evt){
  // update line...
  evt = (evt) ? evt : ((window.event) ? window.event : "");
  var moveTo = new Point2D( getX(evt), getY(evt) );
  this.tempLine.update(this.pointFrom.x, this.pointFrom.y, moveTo.x, moveTo.y);
  // Scale object if line is complete...
  if ( this.actionState == "click2" ){
    var delta = this.pointFrom.subtract( moveTo );
    var percentx = delta.x / this.scalex;
    var percenty = delta.y / this.scaley;
    for (var i=0;i<selectList.length;i++){
      selectList[i].scalePlease( this.pointFrom, percentx, percenty );
    }
  }
}
/*
SelectTool.prototype.endScale = function(evt){
  rootElement.removeEventListener("mousemove", this, false);
  rootElement.removeEventListener("mouseup", this, false);
  if (this.tempLine){
    this.tempLine.destructor();
    this.tempLine = null;
  }
}
*/

/////////////////////////////////////
//                                ///
// rotate tool functions          ///
//                                ///
/////////////////////////////////////

SelectTool.prototype.rotateHandler = function (evt){
  switch (this.actionState){
  case "click0":
    this.beginRotate(evt);
    this.actionState = "click1";
    break;
  case "click1":
    this.setRotateLine(evt);
    this.actionState = "click2";
    break;
  case "click2":
    this.endMode(evt);
    this.actionState = "click0";
    break;
  default:
    debug("unknown state");
    break;
  }
}

SelectTool.prototype.beginRotate = function(evt) {
  this.r_angle = 0;
  this.rotOrigin = new Point2D(getX(evt), getY(evt) );
  this.tempLine = new Line( this.rotOrigin.x, this.rotOrigin.y, this.rotOrigin.x, this.rotOrigin.y, "on", true);
  this.tempLine.tempLine();

  this.mousemove = this.runRotate;
  drawingGroup.addEventListener("click", this, false);
  rootElement.addEventListener("mousemove", this, false);
  //  this.mouseup = this.initRotate;			
  //  rootElement.addEventListener("mouseup", this, false);

}
SelectTool.prototype.setRotateLine = function(evt){
  this.tempLine2 = new Line(this.rotOrigin.x, this.rotOrigin.y,this.lineOnePt.x, this.lineOnePt.y , "on", true);
  this.tempLine2.tempLine();
}

SelectTool.prototype.calculateAngle = function(){
	var x = this.lineOnePt.x - this.rotOrigin.x;
	var y = this.lineOnePt.y - this.rotOrigin.y;
	var theta1 = Math.atan(y / x);
	var adeg = theta1 * (180 / Math.PI);
	if ((x < 0) && (y >= 0))    { adeg +=180;}
	else if ((x > 0) && (y > 0)){ adeg *= 1; }
	else if ((x < 0) && (y > 0)){ adeg += 180; }
	else if ((x < 0) && (y < 0)){ adeg +=180; } 
	else if ((x > 0) && (y < 0)){ adeg +=360; }

	x = this.lineTwoPt.x - this.rotOrigin.x;
	y = this.lineTwoPt.y - this.rotOrigin.y;
	theta1 = Math.atan(y / x);
	this.angle = theta1 * (180 / Math.PI);

	if ((x < 0) && (y >= 0)) { adeg +=180; }
	else if ((x > 0) && (y > 0)){ this.angle *= 1; }
	else if ((x < 0) && (y > 0)){ this.angle += 180; }
	else if ((x < 0) && (y < 0)){ this.angle +=180;	}
	else if ((x > 0) && (y < 0)){ this.angle +=360;	}

	this.angle -= adeg; 

	// this is an absolute angle - we need
	// to make it relative to the last rotate
	// - which is stored in global variable r_angle.

	var temp = this.angle;
	this.angle -=this.r_angle;
	this.r_angle = temp; 
}

// mousemove handler.
SelectTool.prototype.runRotate = function(evt){
  if ( this.actionState ==  "click1" ) {
    // DRAW FIRST LINE
    this.lineOnePt = new Point2D( getX(evt), getY(evt) );
    this.tempLine.update(this.rotOrigin.x, this.rotOrigin.y, this.lineOnePt.x, this.lineOnePt.y);
  } else if ( this.actionState ==  "click2" ) {
    // DRAW SECOND LINE AND ROTATE OBJECT LIST
    this.lineTwoPt = new Point2D( getX(evt), getY(evt) );
    this.tempLine2.update(this.rotOrigin.x, this.rotOrigin.y, this.lineTwoPt.x, this.lineTwoPt.y);
    this.calculateAngle();
    for (var i=0;i<selectList.length;i++){
      selectList[i].rotatePlease(this.rotOrigin, this.angle );
    }
  } else {
    throw new Error("INCORRECT STATE INFO IN ROTATE TOOL");
  }
}
/*
SelectTool.prototype.endRotate = function (){
  rootElement.removeEventListener("mousemove", this, false);
  //  rootElement.removeEventListener("mouseup", this, false);
  this.tempLine.destructor();
  this.tempLine = null;
  this.tempLine2.destructor();
  this.tempLine2 = null;
  this.r_angle= 0;
}
*/

////////////////////////////////////
//Deleting functions.
//////////////////////////////////////

SelectTool.prototype.deleteHandler = function(){
  var k;
  var i = selectList.length;
  if(selectList.length > 0){
    while( k = selectList.pop() ){
      k.destructor();
    }
  }
  this.actionState = null;
  this.selectedTool = null;
}
 
///////////////////////////////////////
// Deactivate select tool.
///////////////////////////////////////
SelectTool.prototype.deactivate = function(){
  if (selectList.length){
    //    debug ("deselecting all ..............");
    this.deselectAllObjects();
  }
  if (this.actionState && this.actionState != "click0" ){
    this.endMode();
  }
  // drawingGroup.removeEventListener("click", this, false);
  eventCatcher.removeEventListener("click", this, false);
  rootElement.removeEventListener("mousedown",this, false);
  window.document.getElementById("drawer2").innerHTML = "";
}

SelectTool.prototype.debug = function(){
  debug("selectTool.debug OKAY");
}



selectTool = new SelectTool();


