/*-------------------------------------
drawmark(x,y)
----------------------------------------*/
function drawmark(x,y)
{
var xmax,ymax;
// scale (x,y) into [0,1]
var w = (lPos[1] - 2 *gUtter);
var h = (lPos[3] - 2 *gUtter);

if(wantsAn)
	{
	x -= onMin; // scrolling
	y -= yMin;  
	ymax = gMax;
	xmax = nMult*nSteps;
	x /= xmax;
	}
	else 
	{
	xmax= xMax;
	ymax =yMax;
	if(yAxis) { x += xmax; x /= (2*xmax);} else x /= xmax;
	}
        if(xAxis) { y += ymax; y /= (2*ymax);} else y /= ymax;
	x = gUtter + w*x;
	y = gUtter + (1-y)*h;
if(x < gUtter) return;	
gLine.DrawTick(x,y,gMarkColor,false);
}

/*--------------------
OPS
https://developer.mozilla.org/en/Canvas_tutorial/Applying_styles_and_colors
----------------------------*/
var MOVE_OP = 'moveTo' ;
var ARC_OP =  'arc' ;
var RECT_OP=  'rect' ;
var BEGIN_OP ='begin';
var FILL_OP = 'fill';
var STROKE_OP = 'stroke';
var FILLSTYLE_OP = 'fillStyle' ;
var STROKESTYLE_OP = 'strokeStyle' ;
var LINEWIDTH_OP = 'lineWidth' ;
var SPIN_OP = 'spin';
var FONT_OP = 'font';
var FILLTEXT_OP = 'fillText' ;

/*------------------------------------
drawgraph ([[x,y],[x,y]...])
uses global gList
-----------------------------------------*/
function ynorm(y,ymax,h)
{
	if(xAxis) { y += ymax; y /= (2*ymax);} else y /= ymax;
	y = gUtter + (1-y)*h;
return y;
}
function xnorm(x,xmax,w)
{
	if(yAxis) { x += xmax; x /= (2*xmax);} else x /= xmax;
	x = gUtter + w*x;
return x;
}
function rnorm(r,xmax,w) // radius
{
	r /= xmax; if(yAxis) r/=2;
	return w*r;
}

function drawgraph(xmax,ymax)
{
var i= 0;
var x,y;
if(gList.length < 1) return;

gFrame=1; // no scrolling for plots
if(ymax == 0) ymax=100;
if(xmax == 0) xmax=ymax;

var w = (lPos[1] - 2 *gUtter);
var h = (lPos[3] - 2 *gUtter);

gLine.context.lineCap  = 'round';
gLine.context.lineJoin = 'round';
gLine.context.strokeStyle = gColor; 
gLine.context.lineWidth = lWidth;
gLine.context.fillStyle = fColor;

// 

gLine.context.beginPath();
for(i=0;i<gList.length;i++)
	{
	x=gList[i][0] ; y=gList[i][1];
	
	if(x == FONT_OP) {gLine.context.font = y; continue;}
	if(x == FILLTEXT_OP) 
				{
				gLine.context.fillText(y[0],xnorm(y[1],xmax,w),ynorm(y[2],ymax,h));
				continue;
				}
	if(x == SPIN_OP) {_spin(rnorm(y[0],xmax,w),rnorm(y[1],xmax,w),rnorm(y[2],xmax,w),y[3],y[4],xmax,w,ymax,h); continue;}
	if(x == LINEWIDTH_OP) {gLine.context.lineWidth = y; continue;}
	if(x == FILLSTYLE_OP) {gLine.context.fillStyle = y; continue;}
	if(x == STROKESTYLE_OP) {gLine.context.strokeStyle = y; continue;}
	if(x == BEGIN_OP){gLine.context.beginPath();continue;}
	if(x == FILL_OP) {gLine.context.fill();continue;}
	if(x == STROKE_OP) {gLine.context.stroke();continue;}
	if(x == RECT_OP) {gLine.context.rect(xnorm(y[0],xmax,w),ynorm(y[1],ymax,h),rnorm(y[2],xmax,w),-rnorm(y[3],ymax,h));continue;}
	if(x == MOVE_OP) {gLine.context.moveTo(xnorm(y[0],xmax,w),ynorm(y[1],ymax,h));continue;}
	if(x == ARC_OP)  {gLine.context.arc(xnorm(y[0],xmax,w),ynorm(y[1],ymax,h),rnorm(y[2],xmax,w),y[3],y[4],y[5]); continue;}
	if(i == 0 && x != MOVE_OP){gLine.context.moveTo(xnorm(x,xmax,w),ynorm(y,ymax,h));continue;}
	
	x = xnorm(x,xmax,w);
	y = ynorm(y,ymax,h);
	gLine.context.lineTo(x,y); // default behaviour
	}
gLine.context.stroke();
} // drawgraph

/*-----------------------
font()
https://developer.mozilla.org/en/CSS/font
------------------------------*/
function font (fo)
{
gList.push([FONT_OP,fo]);
}

/*---------------------------
text - maxwidth NYI
----------------*/
function text(t,x,y)
{
gList.push([FILLTEXT_OP,[t,x,y]]);
}


/*--------------------------
fillstyle
-----------------------------*/
function fillstyle(c)
{
gList.push([FILLSTYLE_OP,c]);
}

/*--------------------------
strokestyle
-----------------------------*/
function strokestyle(c)
{
stroke();
gList.push([STROKESTYLE_OP,c]);
}

/*--------------------------
linewidth
-----------------------------*/
function linewidth(l)
{
stroke();
gList.push([LINEWIDTH_OP,l]);
}

/*-------------------------
begin
------------------------------*/
function begin()
{
gList.push([BEGIN_OP,0]);
}

/*-------------------------
stroke
------------------------------*/
function stroke()
{
gList.push([STROKE_OP,0]);
gList.push([BEGIN_OP,0]);
}

/*-------------------------
fill
------------------------------*/
function fill()
{
gList.push([FILL_OP,0]);
gList.push([BEGIN_OP,0]);
}

/*-------------------------------
moveto(x,y)
----------------------------*/
function moveto(x,y)
{
gList.push([MOVE_OP,[x,y]]);
}

/*----------------------------
plot(x,y) --> push(x,y)
-----------------------------------*/
function plot(x,y)
{
if(wantsAn)
	{
	adata = new Array(); 
	ldata = new Array();
	wantsAn = 0;
	}
gFrame  = 1;
gList.push([x,y]);
}

/*----------------------------
plotf (f,xmin,xmax[,steps])
--------------------------------*/
function plotf(f,xmin,xmax,steps)
	{
	if(arguments.length < 4) steps = 100;
	var dx = (xmax-xmin)/steps ;
	gList.push([MOVE_OP,[xmin,f(xmin)]]);
	for(var x=xmin+dx; x<=xmax; x+=dx)
		plot(x,f(x));
	plot(xmax,f(xmax));
	}
	
/*--------------------------------
paramf
SHOULD USE the _spin method : no push
------------------------------------*/
function paramf(fx,fy,tmin,tmax,steps)
	{
	if(arguments.length < 5) steps =100;
	var dt = (tmax-tmin)/steps ;
	gList.push([MOVE_OP,[fx(tmin),fy(tmin)]]);
	for(var t =tmin+dt; t <=tmax; t+=dt)
		plot(fx(t),fy(t));
	plot(fx(tmax),fy(tmax));
	}
	
/*--------------------------------
polar(r,t[,x0,y0])
-------------------------------------*/
function polar(r,t,x0,y0)
	{
	if(arguments.length < 4) {x0=y0=0;}
	xAxis=yAxis=1;
	plot(r*cos(t)/2+x0,r*sin(t)+y0);
	}
	
/*-----------------------------
polarf(f,[x0[,y0[,tmin[,tmax]]]])
------------------------------------*/
function polarf(f,x0,y0,tmin,tmax,steps)
	{
	var dt,fmin;
	if(arguments.length < 6) steps = 100 ;
	if(arguments.length < 5) tmax=2*PI;
	if(arguments.length < 4) tmin=0;
	if(arguments.length < 3) y0=0;
	if(arguments.length < 2) x0=0;
	dt = (tmax - tmin)/steps;
	
	fmin=f(tmin);
	gList.push([MOVE_OP,[fmin*cos(tmin)/2+x0,fmin*sin(tmin)+y0]]); 
	
	for (var t = tmin+dt; t<=tmax; t+=dt) polar(f(t),t,x0,y0);
	polar(f(tmax),tmax,x0,y0);
	}
	
/*--------------------------
dot == filled circle
--------------------------------*/
function dot(x,y,width)
{
if(arguments.length < 3) width = 3 ;
stroke(); // whatever defined
circle(x,y,width);
fill();
} // dot

/*-------------------------
spinograph
best if R/r = rational NYI
http://linuxgazette.net/133/luana.html
http://blog.nihilogic.dk/2009/02/html5-canvas-cheat-sheet.html
ctx.strokeStyle = "#9CFF00";   
----------------------------------*/
function spin (R,r,p,steps,tmax)
{
	if(arguments.length < 5) tmax = 2*PI;
	if(arguments.length < 4) steps = 1000;
	trace("spin(" + R +", " + r +", " + p +");") 
	gList.push([SPIN_OP,[R,r,p,steps,tmax]]);
}

function _spin (R,r,p,steps,tmax,xmax,w,ymax,h)
{
var t,x,y,dt;

	if(r==0) r=R/2; 
	gLine.context.stroke();
	gLine.context.beginPath();
	dt = tmax/steps;
	
	x=(R-r+p)/2;
	x=xnorm(x,xmax,w);
	y=ynorm(0,ymax,h);
	gLine.context.moveTo(x,y);
	for(t=dt; t<tmax; t+=dt)
	{
	x=(R-r)*cos(t) + p*cos((R-r)*t/r);
	x/=2;
	y=(R-r)*sin(t) - p*sin((R-r)*t/r);
	x=xnorm(x,xmax,w);
	y=ynorm(y,ymax,h);
	gLine.context.lineTo(x,y);
	}
	gLine.context.stroke();
	gLine.context.beginPath();
} // _spin
	

	
/*---------------------------------
arc
------------------------------------*/
function arc(x, y, radius, startAngle, endAngle, anticlockwise)
{
gList.push([ARC_OP,[x,y,radius,startAngle,endAngle,anticlockwise]]);
}

/*-------------------------------
circle
----------------------------*/
function circle(x,y,R)
{
	moveto(x-R,y);
	arc(x,y,R,-PI,PI,1);
}

/*--------------------------
rect
-----------------------------*/
function rect(x,y,w,h)
{
	moveto(x,y);
	gList.push([RECT_OP,[x,y,w,h]]);
}
	


