/********************************
  File: WindowTool.js
  Created by Colm
  Create Date: 18.9.2002

-----------------------------------
**********************************/

WindowTool.prototype   = new ApplianceTool();
WindowTool.constructor = WindowTool;
WindowTool.superclass  = ApplianceTool.prototype;

function WindowTool(){

}

WindowTool.prototype.initTool = function (){
  useWalls();
  wallMask.addEventListener( "mouseup", this, false );
  wallMask.addEventListener( "mousemove", this, false );
	this.actionState = "click0";
	this.pt1 = new Point2D(0,0);
	this.pt2 = new Point2D(0,0);
	this.evt_cnt = 0;

}

WindowTool.prototype.mouseup = function( evt ){
  switch (this.actionState){
  	case "click0":
			this.startWindow(evt);
			break;
		case "click1":
			this.endWindow(evt);
			break; 
		case "click2":
			this.placeWindow(evt);
			break;
		default : 
			break;
	}
}


WindowTool.prototype.startWindow = function( evt ){
	this.actionState = "click1";
	this.currMask = evt.getTarget().getAttribute("d");
	this.parseMask(this.currMask);
	var d_index = evt.getTarget().getAttribute("style").indexOf(":");
	var lwidth = Number(evt.getTarget().getAttribute("style").substring(d_index + 1,(evt.getTarget().getAttribute("style").length)));
	this.pt1.setFromPoint(this.getXY(evt));
	this.myWin = new WindowObject(this.pt1, this.pt1, lwidth, true);
}


WindowTool.prototype.mousemove = function( evt ){
 	switch (this.actionState){
 		case "click1":
			if (evt.getTarget().getAttribute("d") == this.currMask){  // make sure we're getting events off the right mask.
				this.pt2.setFromPoint(this.getXY(evt));
				this.myWin.update(this.pt2.x, this.pt2.y, this.mskAngle);
			}
			break;
		case "click2":
			this.orientWindow(getX(evt), getY(evt));
			break;
		default:
			break;
	}
}

WindowTool.prototype.endWindow = function( evt ){
  wallMask.removeEventListener( "mouseup", this, false );
 	wallMask.removeEventListener( "mousemove", this, false );
	eventCatcher.addEventListener( "click", this, false );
	eventCatcher.addEventListener( "mousemove", this, false );
	this.actionState = "click2";
}


WindowTool.prototype.click = function( evt ){
	if (this.evt_cnt == 1){
		this.placeWindow(evt);
		this.evt_cnt = 0;
	}
	else
		this.evt_cnt ++;
}

	
WindowTool.prototype.placeWindow = function( evt ){
	this.myWin.placeWindow();
	eventCatcher.removeEventListener( "click", this, false );
	eventCatcher.removeEventListener( "mousemove", this, false );
  wallMask.addEventListener( "mouseup", this, false );
  wallMask.addEventListener( "mousemove", this, false );
	this.actionState = "click0";
}


WindowTool.prototype.deactivate = function(){
 	stashWalls();
	if (this.actionState != "click0"){
		this.myWin.destructor();
		delete this.myWin;
	}
	delete this.actionState;
	wallMask.removeEventListener( "mouseup", this, false );
	wallMask.removeEventListener( "mousemove", this, false);
  eventCatcher.removeEventListener( "click", this, false );
	eventCatcher.removeEventListener( "mousemove", this, false );
}



WindowTool.prototype.calcWindowAngle = function(){
	var d_angle = Math.atan((this.pt2.y - this.pt1.y) / 
											(this.pt2.x - this.pt1.x)) * (180 / Math.PI);
	if (this.pt1.x <= this.pt2.x){
		if (this.pt1.y <= this.pt2.y)
			d_angle *= 1;					
		else if (this.pt1.y > this.pt2.y)
			d_angle +=360;
	}
	else if (this.pt1.x > this.pt2.x){
		if (this.pt1.y <= this.pt2.y)
			d_angle += 180;
		else if (this.pt1.y > this.pt2.y)
			d_angle += 180;		
	}		
	return d_angle;
}


WindowTool.prototype.orientWindow = function(x, y){
	var sweep = 1;
	var o_flag = 90;
	var u_angle = 0;
	var un_angle = 0;
	var m_angle = 0;
	var d_angle = 0;
	
	// normalising the mask angle to 0 - 360
	if (this.mskx2 < this.mskx1){
		if (this.msky2 <= this.msky1)
			m_angle = this.mskAngle * 1;					
		else if (this.msky2 > this.msky1)
			m_angle = this.mskAngle + 360;
	}
	else if (this.mskx2 >= this.mskx1){
		if (this.msky2 <= this.msky1)
			m_angle = this.mskAngle + 180;
		else if (this.msky2 > this.msky1)
			m_angle = this.mskAngle + 180;		
	}		
	
	// calculating angle (0-360)between startpt of wall
	// and where the user has the mouse pointer.
	u_angle = Math.atan((y - this.msky2) / 
											(x - this.mskx2)) * (180 / Math.PI);
	if (this.mskx2 <= x){
		if (this.msky2 <= y)
			un_angle = u_angle * 1;					
		else if (this.msky2 > y)
			un_angle = u_angle + 360;
	}
	else if (this.mskx2 > x){
		if (this.msky2 <= y)
			un_angle = u_angle + 180;
		else if (this.msky2 > y)
			un_angle = u_angle + 180;
	}		
	var diff = 0;
	var i_diff = un_angle - m_angle;
	if (i_diff < 0)
		diff = 360 - (m_angle - un_angle);
	else
		diff = un_angle - m_angle;

	// if the door is drawn in the opposite direction to the
	// wall we need to adjust the orientation parameters
	d_angle = this.calcWindowAngle();
	
	if ((d_angle < m_angle + 1) && (d_angle > m_angle - 1)){
		if(diff <=180)
			this.myWin.setOrient(1);
		else
			this.myWin.setOrient(0);
	}
	else {
		if(diff <=180)
			this.myWin.setOrient(0);
		else
			this.myWin.setOrient(1);
	}
}


WindowTool.prototype.intersectLineLine = function(a1, a2, b1, b2) {
    var result;
    var ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
    var ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x);
    var u_b  = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
    if ( u_b != 0 ) {
        var ua = ua_t / u_b;
        var ub = ub_t / u_b;

        if ( 0 <= ua && ua <= 1 && 0 <= ub && ub <= 1 ) {
            result = new Point2D(
                    a1.x + ua * (a2.x - a1.x),
                    a1.y + ua * (a2.y - a1.y));
        } else {
						//debug ("user x y : " + b1.x + " " + b1.y);
						return "error";
        }
    } else {
        if ( ua_t == 0 || ub_t == 0 ) {
            debug("ERROR : line coincident with mask.");
        } else {
            debug("ERROR : line parallel with mask");
        }
    }
    return result;
};


WindowTool.prototype.parseMask = function ( path ){
	this.mskx1 = 0;
	this.msky1 = 0;
	this.mskx2 = 0;
	this.msky2 = 0;
	this.mskAngle = 0;

	var str_arr = new Array();
 	var l_index = 0;
	for (var i =0; i < path.length; i++){
		if(path.charAt(i) == ","){
			str_arr.push(path.substring(l_index,  i));
			l_index = i;	
		} 	 	
	}
	for (var k = 0; k < str_arr.length; k ++){
		var temp = new Array();
		l_index = 0;
		for (var i = 0; i < str_arr[k].length; i++){
			if(str_arr[k].charAt(i) == " "){
				temp.push(str_arr[k].substring(l_index,  i));
				l_index = i;	
			}
		} 
		temp.push(str_arr[k].substring(l_index,str_arr[k].length));
		if(k == 0){
			this.mskx1 = Number(temp[temp.length-2]);
			this.msky1 = Number(temp[temp.length-1]);
		}
		else if (k == 1){
			this.mskx2 = Number(temp[temp.length-2]);
			this.msky2 = Number(temp[temp.length-1]);
		}
	}	
	this.mskAngle = Math.atan((this.msky2 - this.msky1) / 
													  (this.mskx2 - this.mskx1)) * (180 / Math.PI);
}


WindowTool.prototype.calcIp1 = function(userx, usery) {
	var midab_x = (this.mskx1 + userx) / 2;
	var midab_y = (this.msky1 + usery) / 2;
	var midbc_x = (userx + this.mskx2) / 2;
	var midbc_y = (usery + this.msky2) / 2;
	var nslope_ab = ((usery - this.msky1) / 
									 (userx - this.mskx1));
	var nslope_bc = ((this.msky2 - usery) / 
									 (this.mskx2 - userx));
	var pslope_ab = -1 / nslope_ab;
	var pslope_bc = -1 / nslope_bc;
	
	// if the x coords of a and b are the same then 
	// the perpendicular slope of the line between a and b is infinity. 
	
	if (nslope_ab == 0){
		pslope_ab = 1000000; 
	}
	var ab_y_intercept =(( pslope_ab * (midab_x - 0) ) - midab_y) * -1;
	var bc_y_intercept =(( pslope_bc * (midbc_x - 0) ) - midbc_y) * -1;
	var centre_x =( bc_y_intercept - ab_y_intercept) / (pslope_ab - pslope_bc);
	var centre_y = ((pslope_ab * bc_y_intercept) - (ab_y_intercept * pslope_bc)) / (pslope_ab - pslope_bc);
	return new Point2D(centre_x,centre_y);
}

// gets the centre point of the line width.
WindowTool.prototype.getXY = function( evt ){
	var userx = getX(evt);
	var usery = getY(evt);
	var flag = 0;
	var brk = 0;
	var ip1 = new Point2D(0,0); 
	var ip2 = new Point2D(0,0); 
	
	// this loop is needed, as if the user clicks on the centre line
	// the ip lines never intersect. so if the intersection function
	//returns an error we shift where the user clicked by one pixel 
	// and try again/
	
	while (flag == 0){	
		brk++;
		ip1 = this.calcIp1(userx, usery);
		ip2  = this.intersectLineLine( new Point2D(this.mskx1, this.msky1), new Point2D(this.mskx2, this.msky2), 
																		 new Point2D(userx, usery), ip1);
		if ((ip2 != "error") || (brk == 10))
			flag = 1;
		else{
			userx ++;
			usery +=2;
		}
	}
	return ip2;
}

var windowTool = new WindowTool();
