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

 File: kitchen.js
 Creator: Hawkeye King
 Create Date: 7/31/02

  Why the hell is this thing called "kitchen.js".
    Um, good question...

    Really, it's because we'll be stocking a metaphorical kitchen with all the tools, ovens, ranges, spices, cookbooks, countertops and cuttingboards needed to for an institutional scale madori kitchen.

Can I get an amen?
      Amen brother!

===========================

Modified 8/3 by Hawkeye

I split functionality into four files:

*kitchen.js- provides initialization functions and defines global functions and variables.
*cookingUtensils.js- functions/tools for manipulating SVG objects.

*foodTools.js- Drawing tools for creating SVG drawing objects.

*foods.js- SVG object wrappers (ie lines, circles, rectangles, etc)

===========================

Modified 8/19 by Hawkeye

Added wrapNode() and requestAnObject() Note that requestAnObject() is for testing purposes only.

Also, I deleted all that cruft at the end of the file.  It was annoying the hell out of me.

=========================== 

Modified 8/21 by Hawkeye

Object request functions have been moved to refirgerator.js
Basic Key Capturing has been added.  Pressing 'esc' while drawing now resets the tool.
Added gloabal variable: popupwin in order to manage popup window features.

===========================

Modified 8/27 by Hawkeye

Added the line:

  evt = (evt) ? evt : ((window.event) ? window.event : "");

to eventHandler.handleEvent().  Now we don't have to include that code in every event handling function.

===========================
===========================

Modified 9/03 by Colm

wrapNode() changed to pull the object type name from the id field
instead of the elem.localname field. This is because we're changing
to paths so every shape will be a path instead of being a rectangle
or line or whatever, and we need something different to distinguish 
between the different shapes.
===========================
===========================
Modified 9/03 & Merged 9/05 by Hawkeye

Adding wall event masking features:
* heavily modified init() function.
* added useWalls() and stashWalls()
* created 'canvas' variable as well as 'wallMask' variable

===========================
Modified 9/10 by Hawkeye
* Minor changes to wrap node function.  Needed for TextObject compatibility.

Modified 9/20 by Hawkeye
* moved windowing functions from refrigerator.js
* added global variable: 'madori_label'  this is the name of the madori when saved.
* minor change to event catcher: wallMask is now not visible initially.
===========================
Modified 9/24 by Hawkeye

* Added Zoom toggle thing.
* Grid Size now tells the right size...
* Disabled button 2 in EventHandler class

===========================
===========================
Modified 9/25 by Colm

* Will now delete selected things when delete button
* pressed on keyboard.

===========================
Modified 9/25 by Hawkeye

* Changed default color to black.
===========================
**********/

/****
 *Global variables
 ****/

/*** Application/environment variables ***/
var svgDoc;
var rootElement;
var eventCatcher;
var drawingGroup;
var debugLevel = 19;
var selectList;
var popupwin = null;
var gridSize = 10; // ten pixel snap-to-grid value
var wallWidth = 5;
var wallMask; // object group for event catching object masks.
var canvas;
var madori_label = null;

/*** Drawing attributes ***/
var strokeColor;
var fillColor;
var strokeWidth;

/*** State variables ***/
var buttonOneEventHandler;
var currentTool;
var currentObject;
var handlerTest;

function init() {
  svgDoc       = document.embeds[0].getWindow().svgDocument;
  rootElement  = svgDoc.getElementById("svg");
  eventCatcher = svgDoc.getElementById("coverGroup");
  drawingGroup = svgDoc.getElementById("drawGroup");
  canvas       = svgDoc.getElementById( "cover" );
  wallMask     = new ObjectGroup();
  wallMask.addEventListener = function(a,b,c){wallMask.svgGroup.addEventListener(a,b,c)};
  wallMask.removeEventListener = function(a,b,c){wallMask.svgGroup.removeEventListener(a,b,c)};
  eventCatcher.insertBefore( wallMask.svgGroup,canvas );
  selectList   = new Array();

  strokeColor  = "black";
  fillColor    = "none";
  strokeWidth  = 3;
  showGrid();
  
	rootElement.addEventListener("keyup", keyCapture, false);
	rootElement.addEventListener("SVGZoom", resizeEventCatcher, false);
  rootElement.removeChild( eventCatcher );
  rootElement.appendChild( eventCatcher );
  // remove "loading..." message

  document.getElementById("newGridSize").value=gridSize;
  document.getElementById("zoomPanCheck").checked = eval( rootElement.getAttribute("enableZoomAndPanControls") );
  svgDoc.getElementById("info").firstChild.data="";
}
/****************************************
 *  MAKE CANVAS AVAILABLE TO DRAWING TOOLS
 * OR DISABLE CANVAS TO SELECT OTHER OBJECTS
 ****************************************/
function useCanvas(){
  if (debugLevel >= 20)
    debug("using canvas");
  eventCatcher.setAttribute("pointer-events", "all")
  rootElement.removeChild( eventCatcher );
  rootElement.appendChild( eventCatcher );
  eventCatcher.appendChild( canvas );
}  
function useCurrentLayer(){
  eventCatcher.setAttribute("pointer-events", "all")
  rootElement.removeChild( eventCatcher );
  rootElement.insertBefore( eventCatcher, drawingGroup );
}
function stashCanvas(){
  eventCatcher.setAttribute("pointer-events", "none")
  rootElement.removeChild( eventCatcher );
  rootElement.insertBefore( eventCatcher, rootElement.getFirstChild() );
}
// I enable the wall mask for event catching
function useWalls(){
  eventCatcher.setAttribute("pointer-events", "all");
  rootElement.removeChild( eventCatcher );
  rootElement.appendChild( eventCatcher );
  eventCatcher.appendChild( wallMask.svgGroup );
}
// I disable the wall mask from event catching
function stashWalls(){
  eventCatcher.setAttribute("pointer-events", "none")
  rootElement.removeChild( eventCatcher );
  rootElement.insertBefore( eventCatcher, rootElement.getFirstChild() );
}

/****************************************
 *   UPDATE STATE FROM HTML COMMAND
 ****************************************/
function useTool( tool ){
  if (currentTool) {
    currentTool.deactivate();
  }
  currentTool = eval( tool );
  currentTool.initTool();
}

/***************************************
 *  EVENT HANDLER SUPERCLASS
 *THIS CLASS FACILITATES OBJECT EVENT HANDLING IN A UNIFORM FASHION
 ***************************************/
function EventHandler(){
  this.init();
};
EventHandler.prototype.init = function(){};
EventHandler.prototype.handleEvent = function(evt){
  evt = (evt) ? evt : ((window.event) ? window.event : "");
  var type=evt.type;
  //if (type != "mousemove" && currentTool == selectTool )  debug("EVENTTYPE:"+evt.type);
  if ( evt.button == 2 ) {
    return 0;
  }
  if ( this[type] == null ) {
    throw new Error("Unsupported event type: "+type);
  }
  this[type](evt);
};

/***************************************
  DRAWING TOOL SUPERCLASS
THIS CLASS PROVIDES COMMON ROUTINES FOR DRAWING TOOLS
***************************************/
DrawingTool.prototype = new EventHandler();
DrawingTool.prototype.constructor = DrawingTool;
DrawingTool.superclass = EventHandler.prototype;
function DrawingTool(){}
DrawingTool.prototype.testDrawingTool = function(){
  alert("This is a test of the Drawing Tool.");
}

/*****************************************
 *  GRAB AN OBJECT AND HAND IT TO OUR CURRENT TOOL SO THAT WE CAN DO STUFF TO IT.
 *****************************************/
function grabObject( evt, obj ){
  if ( currentTool.grabObject != null ){
    currentTool.grabObject( evt, obj );
  } // else {  debug("no food grabber"); }
}

/**************************************************
 *
 * Wrap Node
 *
 * This function takes an SVG object and applies our wrapper classes to that object.
 * Function is called recursively on child nodes if necesse est.
 *
 * precondition: "node" is a DOM object with childnodes to be wrapped.
 *    "parentObj":optional: is a "foodGroup" to append nodes to.  
 *    Probably it is a containered version of "node".
 *
 * Postcondition: "node" has been wrapped in JS wrapper classes.  
 *     Class methods can be accessed via common mouse events.
 *
 *************************************************************/


function wrapGroup(node){
	for (var temp = node.firstChild; temp; ){
		var type = temp.localName;
		//debug ("temp localname : " + type);
		if(type == "g"){
			//debug ("wrapping group ");
			var grp = gTool.copyconstructor( temp );
			this.wrapNode(temp, grp);
		}
		else {
			//debug ("wrapping element ");
    	if ( type != null ){
      	if (temp.localName == "path"){
					var attr = temp.attributes;
					type = attr.getNamedItem("id").nodeValue;
      	}
				//debug ("elem nodeValue : " + type); 
      	var wrappedElem = eval( type + "Tool.copyconstructor( temp )");
			}
		}
		temp = temp.nextSibling;
	}
}


function wrapNode( node ){
	//debug (" ");

  if (arguments.length == 2 ){
    var parentObj = arguments[1];
	} else { var parentObj = null; }


  for( var elem = node.firstChild ;  elem;  ) {
    var type = elem.localName;
		//debug ("elem localname : " + elem.localName);
    // pure text data nodes have no type.
		
    if ( type != null ){
      if (elem.localName == "path"){
				var attr = elem.attributes;
				var type = attr.getNamedItem("id").nodeValue;
      }
			//debug ("elem nodeValue : " + type); 
      var wrappedElem = eval( type + "Tool.copyconstructor( elem )");
    }

    if ( parentObj && wrappedElem){
      elem = elem.nextSibling;
      parentObj.addObject( wrappedElem );
    } else {
      elem = elem.nextSibling;
    }
  }
}


/*******************************************
 * keyCapture()
 *   I capture key events.  I might perform particular actions 
 * if a particular key is pressed.
 ******************************************/
function keyCapture(e){
  if ( currentTool && e.keyCode == 27 ){
    //    currentTool.deactivate();
    useTool(currentTool);
  }
	if (selectList.length && e.keyCode == 127){
		selectTool.deleteHandler();	
	}
  // alert("keyCode:"+e.keyCode+" charCode:"+e.charCode)
}

/********************************************
 * getX() and getY() 
 *  These functions return virtual-space 
 * coordinates from user-space data.  Coordinates are also updated 
 * according to "snap-to-grid" functioonality.
 *********************************************/
function getX(evt){
  var userx = evt.getClientX();
  var scale = rootElement.getCurrentScale();
  var panx  = rootElement.getCurrentTranslate().x;
  var newx = ( userx - panx )/scale;
  if (gridSize > 1){
    newx = newx + (gridSize / 2);
    newx -= newx  % gridSize;
  }
  return( newx );
}
function getY(evt){
  var usery = evt.getClientY();
  var scale = rootElement.getCurrentScale();
  var pany  = rootElement.getCurrentTranslate().y;
  var newy = ( usery - pany )/scale;
  if (gridSize > 1){
    newy = newy + (gridSize / 2);
    newy -= newy % gridSize;
  }
  return( newy );
}

/*************************************
 *
 *   Toggle Zoom Function
 *
 *************************************/
function toggleZoom( zoomSetting ){

  if (zoomSetting == true){
    alert("ON");
  } else {
    alert("OFF");
  }
  rootElement.setAttribute( "enableZoomAndPanControls", zoomSetting );
}

/**************************************
 * Um,  Something...  Oh yeah-
 * SnapToGrid( new grid size )
 *   I set the "snap to grid" grid size.  
 *   Note that a gridSize of 1 or less turns snap-to-grid off.
 **************************************/
function snapToGrid( newGridSize ){
  if ( !parseInt(newGridSize) ) { return 0; }
  gridSize = newGridSize;
}
function showGrid( ){
  var pointy = svgDoc.getElementById("gridpoint");
  var pGroup = svgDoc.getElementById("gridpointdraw");
  for (var i=0; i<640;i+=10*gridSize){
    for (var j=0;j<480;j+=10*gridSize){
      var newp = pointy.cloneNode(false);
      newp.setAttribute("x",i);
      newp.setAttribute("y",j);
      pGroup.appendChild( newp );
    }
  }
}
function resizeEventCatcher(){
  var h = rootElement.getAttribute("height");
  var w = rootElement.getAttribute("width");
  var trans = rootElement.getCurrentTranslate();
  var scale = rootElement.getCurrentScale();

  //  debug("resizeing Event Catcher"+w+" "+h+" "+scale+" "+trans.x+" "+trans.y);

  canvas.setAttribute("height", h * (1/scale) )
  canvas.setAttribute("width", w * (1/scale) );
  canvas.setAttribute("transform", "translate("+ (0-trans.x/scale)+","+( 0-trans.y/scale)+")");
}

/*******************************************
 *
 * Set stroke Width/Color & fill color
 *
 ********************************************/
function setStrokeWidth( width ){
  strokeWidth  = Number( width );
}
function setStrokeColor( color ){
  strokeColor = color;
}
function setFillColor( color ){
  fillColor = color;
}

/********************************************
 *
 *  Windowing functions.
 *    This controls window opening and closing.
 *    That way windows can be controlled in a uniform fashion.
 *
 ********************************************/
function windowPlease( src, name, attribs, writeData ){
  // close window if it's already open to reset window state.
  if ( popupwin != null ){
    popupwin.close();
  }
  // specified window source
  if ( src ){
    popupwin = window.open( src , name, attribs );
  } else {
    popupwin = window.open( "blank.html" , name, attribs );
  }
  // specified window code
  if ( writeData != "" ) {
    popupwin.document.write( writeData );
  }
  document.body.onunload= windowClose;
  return popupwin;
}

function windowClose(){
  if (popupwin != null)
    if (!popupwin.closed)
      popupwin.close();
}






















/*

HERE IS HOW TO MANIPULATE ALL LINESTYLES (i.e. walls)
 Redefine thier class.

*/
