/////////////
//	Author : Colm
///////////////
// 23-3  changed to pull arcs in and out of database.
////////////////
/***************************************
  ARC SHAPE
***************************************/

Arc.prototype = new Shape;
Arc.constructor = Arc;
Arc.superclass = Shape.prototype;


function Arc( x1, y1, x2, y2, x3, y3, rad, sw, la, axr, draw ){
  if (arguments.length > 0) 
    this.init(x1, y1, x2, y2, x3, y3, rad, sw, la, axr, draw );
}

Arc.prototype.init = function(x1, y1, x2, y2, x3, y3, rad, sw, la, axr, draw){
  Arc.superclass.init.call(this, null);

/*	debug("  ");
	debug ("x1 y1 : " + x1 + " " + y1);
	debug ("x2 y2 : " + x1 + " " + y1);
	debug ("x3 y3 : " + x1 + " " + y1);
	
	debug ("rad : " + rad);
	debug ("sweep : " + sw);
	debug ("large arc : " + la);
	debug ("axr : " + axr);
*/	

  this.handles[0] = new Handle(x1, y1, this);
  this.handles[1] = new Handle(x2, y2, this);
  this.handles[2] = new Handle(x3, y3, this);

  this.radius = rad;
  this.sweep = sw;
  this.large_arc = la;
  this.axis_rot = axr;
	if(draw)
		this.make();
}

// to generate an elliptical curve SVG needs 3 additional parameters
// which are calculated here. 
// Radius. Calculated based on three points on the circumference.
// Large Arc Flag - calculated using a lot of mucking around with coordinate geometry.
// sweep value - ditto as with large arc flag.

Arc.prototype.calcRadius = function() {
	var midab_x = ((this.handles[0].point.x+this.handles[1].point.x) / 2);
	var midab_y = ((this.handles[0].point.y+this.handles[1].point.y) / 2);
	var midbc_x = ((this.handles[1].point.x+this.handles[2].point.x) / 2);
	var midbc_y = ((this.handles[1].point.y+this.handles[2].point.y) / 2);
	
	var nslope_ab = ((this.handles[1].point.y - this.handles[0].point.y) / 
									 (this.handles[1].point.x - this.handles[0].point.x));
	var nslope_bc = ((this.handles[2].point.y - this.handles[1].point.y) / 
									 (this.handles[2].point.x - this.handles[1].point.x));
	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);
	var ret = Math.sqrt(((centre_x - this.handles[0].point.x) * 
													 (centre_x - this.handles[0].point.x)) + ((centre_y -
														this.handles[0].point.y) * (centre_y - this.handles[0].point.y)));
	return ret;
}

Arc.prototype.calcLargeArc = function(){
	var ret;
	var midab_x = ((this.handles[0].point.x+this.handles[1].point.x) / 2);
	var midab_y = ((this.handles[0].point.y+this.handles[1].point.y) / 2);

	var init_rad = Math.sqrt(((midab_x - this.handles[0].point.x) * (midab_x - this.handles[0].point.x)) + ((midab_y -
		this.handles[0].point.y) * (midab_y - this.handles[0].point.y)));
	var curr_rad = Math.sqrt(((midab_x - this.handles[2].point.x) * (midab_x - this.handles[2].point.x)) + ((midab_y -
		this.handles[2].point.y) * (midab_y - this.handles[2].point.y)));
	if (curr_rad < 0)
		curr_rad *= -1;
	if(curr_rad >= init_rad)
		ret = 1;
	else 
		ret = 0;
	
	return ret;
}

Arc.prototype.calcSweep = function(){
	var sweep_flag = 0;
	var ret;
	if (this.handles[0].point.x <= this.handles[1].point.x) { 
		var minX = this.handles[0].point.x;
		var minY = this.handles[0].point.y;
		var maxX = this.handles[1].point.x;
		var maxY = this.handles[1].point.y;
		sweep_flag = 1;
	}
	else if (this.handles[0].point.x > this.handles[1].point.x) { 
		var minX = this.handles[1].point.x;
		var minY = this.handles[1].point.y;
		var maxX = this.handles[0].point.x;
		var maxY = this.handles[0].point.y;
		sweep_flag = -1;
	}
	var ab_slope = (maxY - minY) / (maxX - minX);
	var t_slope = (this.handles[2].point.y - minY) / (this.handles[2].point.x - minX);
	var temp = ab_slope - t_slope;
	temp *=sweep_flag;
	if (this.handles[2].point.x  < minX)
	 	temp *= -1;
	if (temp > 0)
		ret = 1;
	else 
	 	ret = 0;
	return ret;
}

Arc.prototype.constructPathString = function(){
	var ret = "M" + this.handles[0].point.x + ", " + 
							 this.handles[0].point.y + "A"+this.radius + ", " + 
							 this.radius + " " + this.axis_rot + " " + 
							 this.large_arc + ", " + this.sweep + " " + 
							 this.handles[1].point.x + " " +this.handles[1].point.y;
	return ret;
}

Arc.prototype.make = function() {
  this.svgNode = svgDoc.createElement("path");
  this.svgNode.addEventListener( "click", this, false );
 	style = this.svgNode.getStyle();
	style.setProperty("fill", "none");
  style.setProperty("stroke", strokeColor);
  style.setProperty("stroke-width", strokeWidth);
 	drawingGroup.appendChild( this.svgNode );
	this.svgNode.setAttribute("id", "arc");
	this.radius = this.calcRadius();
	this.large_arc =this.calcLargeArc();
	this.sweep = this.calcSweep();
	var pathstring = this.constructPathString();
	this.svgNode.setAttribute("d", pathstring);
}

Arc.prototype.update = function( x, y ){
	if (x && y){
		this.handles[2].moveto(x, y);			  
		this.radius = this.calcRadius();
		this.large_arc = this.calcLargeArc();
		this.sweep = this.calcSweep();
  	var pathstring = this.constructPathString();
		this.svgNode.setAttribute("d", pathstring);
	}
	else {
		this.radius = this.calcRadius();
		this.large_arc = this.calcLargeArc();
		this.sweep = this.calcSweep();
  	var pathstring = this.constructPathString();
		// debug ("pathstring : " + pathstring);
  	this.svgNode.setAttribute("d", pathstring);
	} 
}

Arc.prototype.destructor = function(){
  this.svgNode.parentNode.removeChild( this.svgNode );
	for (var k = 0; k < this.handles.length ; k ++)
		delete (this.handles[k]);
  delete this.svgNode;
	delete this.radius;
	delete this.axis_rot;
  delete this.large_arc;
  delete this.sweep;
}
