////////////////////////////////////////////////////////////////////////////
//
//                       Copyright (c) 2006-2007
//                       The Other Solutions, Inc.
//                       USA
//
//                       All Rights Reserved
//
//   This source file is subject to the terms and conditions of the
//   The Other Solutions Software License Agreement which restricts the manner
//   in which it may be used.
//   It's strictly forbidden to copy or use without 
//	  written permission unless viewed from the following web sites:
//		www.theothersolutions.com
//		www.hvks.com
//   Mail: hve@hvks.com
//
/////////////////////////////////////////////////////////////////////////////
//
// Module name     :   coordinate.js
// Module ID Nbr   :   
// Description     :   Javascript Graphic display coordinate system
// --------------------------------------------------------------------------
// Change Record   :   
//
// Version	Author/Date		Description of changes
// -------  -------------	----------------------
// 01.01	HVE/06-Jul-27		Initial release
// 01.02	HVE/2006-Dec-26	Set origin correct for drawings areas in first and second quadrant
//	01.03 HVE/2007-Feb-15	The coordinate ran inifinity for x < 4. 	
// 01.04 HVE/2007-Apr-9		Added the drawCircle() * fillCircle() prototype
// End of Change Record
//
/////////////////////////////////////////////////////////////////////////////

// Class Coordinate
function Coordinate(gr,dim_x,dim_y,min_x,min_y,max_x,max_y,step_x,step_y)
	{
	var fix;
	check(arguments);
	
	if(max_x>0&&min_x>0)min_x=0;
	if(max_x<0&&min_x<0)max_x=0;
	if(max_y>0&&min_y>0)min_y=0;
	if(max_y<0&&min_y<0)max_y=0;
	if(step_x==0)step_x=1;
	if(step_y==0)step_y=1;
	
	this.gr=gr;
	this.dim_x=dim_x;
	this.dim_y=dim_y;
	this.min_x=min_x;
	this.min_y=min_y;
	this.max_x=max_x;
	this.max_y=max_y;
	this.step_x=step_x;
	this.step_y=step_y;
	this.disp=25;

	this.xwidth=dim_x-2*this.disp;
	this.yhight=dim_y-2*this.disp;
	this.xorig=this.disp+this.xwidth*(-min_x/(max_x-min_x)); 
	this.yorig=dim_y-(this.disp+this.yhight*(-min_y/(max_y-min_y)));
	this.xscale=this.xwidth/(max_x-min_x);
	this.yscale=this.yhight/(max_y-min_y);
	
	// Draw X & Y line
	gr.drawLine(this.xorig+this.xscale*this.min_x,this.yorig,this.xorig+this.xscale*this.max_x,this.yorig);
	gr.drawLine(this.xorig,this.yorig-this.yscale*this.min_y,this.xorig,this.yorig-this.yscale*this.max_y);
	// Draw minor line along x-axis and unit
	for(var i=min_x+(min_x==0?step_x:0); i <= max_x; i+=step_x )
		{var s_length;
		if(i==0) continue;
		gr.drawLine( Math.round(this.xorig+i*this.xscale),this.yorig-5,Math.round(this.xorig+i*this.xscale),this.yorig+5);
		s_length=String(i).length; s_length=(s_length-1)/2;
		gr.drawString(i.toString(),Math.round(this.xorig+i*this.xscale-12*s_length),this.yorig+10);
		}
	// Draw minor line along y-axis and unit	
	if(step_y<1) fix=1; else fix=0;
	for(var i=min_y+(min_y==0?step_y:0); i <= max_y; i+=step_y )
		{var s_length;
		if(i==0) continue;
		gr.drawLine( this.xorig-5,Math.round(this.yorig-i*this.yscale), this.xorig+5, Math.round(this.yorig-i*this.yscale));
		if(String(max_y).length>3) // To many characters to the left of the yaxis. Place on the right side of the y-axis
			gr.drawString(i.toFixed(fix),this.xorig+6,Math.round(this.yorig-i*this.yscale-7));
		else // place the units to the left of the y-axis
			gr.drawString(i.toFixed(fix),Math.max(this.xorig-10*(i.toFixed(1).length)-2,0),Math.round(this.yorig-i*this.yscale-7));
//		gr.drawStringRect(i.toFixed(1),Math.max(this.xorig-10*(i.toFixed(1).length)-2,0),Math.round(this.yorig-i*this.yscale-7),"right");
		}
		
	this.legend=new Array();
	}
Coordinate.prototype.toString=function()
	{var ss="";
	ss+=" Dimension: ("+this.dim_x+","+this.dim_y+")";
	ss+=" Min: ("+this.min_x+","+this.min_y+")";
	ss+=" Max: ("+this.max_x+","+this.max_y+")";
	ss+=" Step: ("+this.step_x+","+this.step_y+")";	
	ss+=" Scale: ("+this.xscale+","+this.yscale+")";	
	ss+=" Origin: ("+this.xorig+","+this.yorig+")";	
	ss+=" WxH: ("+this.xwidth+","+this.yhight+")";	
	return ss;
	}	
Coordinate.prototype.paint=function() { return this.gr.paint(); }
Coordinate.prototype.clear=function() { return this.gr.clear(); this.legend.length=0; }
Coordinate.prototype.addLegend=function(color,legend)
	{var s_length=String(legend).length;
	this.gr.setColor(color);
	this.gr.setStroke(2);
	this.gr.drawLine( this.dim_x-100-40,this.disp+this.legend.length*15+5, this.dim_x-100-10, this.disp+this.legend.length*15+5);
	this.gr.setStroke(1); 
	this.gr.drawString(String(legend),this.dim_x-100,this.disp+this.legend.length*15);
	this.gr.setColor("#000000");
	this.legend[this.legend.length]=legend;
	}
Coordinate.prototype.addLegendPoint=function(color,str,legend)
	{var s_length=String(legend).length;
	this.gr.setColor(color);
	this.gr.setStroke(2);
	if(this.legend.length>=26)
		this.gr.drawString(str,this.dim_x+150,this.disp-15+(this.legend.length-26)*15);
	else
	 	this.gr.drawString(str,this.dim_x-10,this.disp-15+this.legend.length*15);
	this.gr.setStroke(1); 
	if(this.legend.length>=26)
		this.gr.drawString(String(legend),this.dim_x+160,this.disp-15+(this.legend.length-26)*15);
	else
		this.gr.drawString(String(legend),this.dim_x,this.disp-15+this.legend.length*15);
	this.gr.setColor("#000000");
	this.legend[this.legend.length]=legend;
	}
Coordinate.prototype.addXname=function(xname)
	{
	this.gr.drawString(String(xname),this.dim_x-this.disp-8*String(xname).length,this.yorig+1);
	}
Coordinate.prototype.addYname=function(yname)
	{var len=String(yname).length;
	this.gr.drawString(String(yname),this.xorig-8*Math.min(len,3),this.disp-20);		
	}
Coordinate.prototype.addTitle=function(title)
	{
	this.gr.drawStringRect(String(title),this.disp,this.disp/3,this.dim_x-2*this.disp, "Center");		
	}
Coordinate.prototype.drawPoint=function(x,y) 
	{
	x=Math.round(this.xorig+x*this.xscale)
	y=Math.round(this.yorig-y*this.yscale)
	this.gr.drawLine(x-5,y+5,x+5,y-5);		
	this.gr.drawLine(x-5,y-5,x+5,y+5);		
	}
Coordinate.prototype.drawPolyline=function(Xpts,Ypts) 
	{
	var x=new Array;
	var y=new Array;
	for(var i=0; i<Xpts.length; i++ )
		{
		x[i]=Math.round(this.xorig+Xpts[i]*this.xscale);
		y[i]=Math.round(this.yorig-Ypts[i]*this.yscale);
		}
	this.gr.drawPolyline(x,y);		
	}
Coordinate.prototype.fillPolygon=function(Xpts,Ypts) 
	{
	var x=new Array;
	var y=new Array;
	for(var i=0; i<Xpts.length; i++ )
		{
		x[i]=Math.round(this.xorig+Xpts[i]*this.xscale);
		y[i]=Math.round(this.yorig-Ypts[i]*this.yscale);
		}
	this.gr.fillPolygon(x,y);		
	}
Coordinate.prototype.drawString=function(Str,Xpt,Ypt) 
	{
	var x, y;
	x=Math.round(this.xorig+Xpt*this.xscale);
	y=Math.round(this.yorig-Ypt*this.yscale);
	this.gr.drawString(Str,x,y);		
	}	
Coordinate.prototype.drawCircle=function(x,y,r) 
	{
	x=Math.round(this.xorig+x*this.xscale);
	y=Math.round(this.yorig-y*this.yscale);
	this.gr.drawEllipse(x-r,y-r,2*r,2*r);		
	}
Coordinate.prototype.fillCircle=function(x,y,r) 
	{
	x=Math.round(this.xorig+x*this.xscale);
	y=Math.round(this.yorig-y*this.yscale);
	this.gr.fillEllipse(x-r,y-r,2*r,2*r);		
	}
	
Coordinate.prototype.fillRect=function(x,y,w,h) 
	{// x,y topmost left corner
	x=Math.round(this.xorig+x*this.xscale);
	y=Math.round(this.yorig-y*this.yscale);
	this.gr.fillRect(x,y,w,h);		
	}

