/* This notice must be untouched at all times.

jsgraphics.js    v. 1.26
The latest version is available at http://www.walterzorn.de/

Copyright (c) 2002 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn <walter@kreuzotter.de>
Last modified: 10. 1. 2003

High Performance JavaScript Graphics Library.
Provides methods to draw lines, rectangles, ellipses, polygons, text
and to fill rectangles and ellipses.
NOTE: Operations, functions and branching have rather been optimized
to efficiency and speed than to shortness of source code.

This software is provided "as is", without a warranty of any kind.
*/


function ckOp7(el)
{
	if (!window.opera || !el) return false;
	el.innerHTML += '<div id="WZjsG" style="position:absolute;"><\/div>';
	return (el.innerHTML.indexOf('<DIV ID=\'WZjsG\'><\/DIV>') != -1);
}


function mkDiv(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:' + w + 'px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'overflow:hidden;background-color:' + this.color + ';'+
		'"><\/div>\n';
}


function mkLbl(txt, x, y)
{
	if (this.canvas) this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'font-family:' +  this.ftFam + ';'+
		'font-size:' + this.ftSz + ';'+
		'color:' + this.color + ';' + this.ftSty + '">'+
		txt +
		'<\/div>\n';
}


function mkLine(x1, y1, x2, y2)
{
	if (x1>x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1>y2)? -1 : 1;
	if (dx>=dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while ((dx--)>=0)
		{
			if (p>0)
			{
				this.mkDiv(ox, y, x-ox+1, 1);
				x++;
				y += yIncr;
				p += pru;
				ox = x;
			}
			else
			{
				x++;
				p += pr;
			}
		}
		this.mkDiv(ox, y, x2-ox+1, 1);
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if (y2<=y1)
		{
			while ((dy--)>=0)
			{
				if (p>0)
				{
					this.mkDiv(x, y, 1, oy-y+1);
					x++;
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, 1, oy-y2+1);
		}
		else
		{
			while ((dy--)>=0)
			{
				if (p>0)
				{
					this.mkDiv(x, oy, 1, y-oy+1);
					x++;
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, oy, 1, y2-oy+1);
		}
	}
}


function mkOval(left, top, width, height, fill)
{
	var a = width>>1, b = height>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	ox = 0, oy = b,
	h,
	a2 = (a*a)<<1, b2 = (b*b)<<1,
	st = (a2>>1)*(1-(b<<1)) + b2,
	tt = (b2>>1) - a2*((b<<1)-1);
	if (fill)
	{
		do
		{
			if (st<0)
			{
				st += b2*((x<<1)+3);
				tt += (b2<<1)*(x+1);
				x++;
			}
			else if (tt<0)
			{
				st += b2*((x<<1)+3) - (a2<<1)*(y-1);
				tt += (b2<<1)*(x+1) - a2*((y<<1)-3);
				x++;
				y--;
				h = oy-y;
				this.mkOvalQdsFill(cx, cy, -x+1, -oy, oy-h+1+hod, ((x-1)<<1)+1+wod, h);
				ox = x;
				oy = y;
			}
			else
			{
				st -= (a2<<1)*(y-1);
				tt -= a2*((y<<1)-3);
				y--;
			}
		}
		while (y);
		this.mkOvalQdsFill(cx, cy, -a, -oy, 0, width+1, oy+1+hod);
	}
	else
	{
		var w;
		do
		{
			if (st<0)
			{
				st += b2*((x<<1)+3);
				tt += (b2<<1)*(x+1);
				x++;
			}
			else if (tt<0)
			{
				st += b2*((x<<1)+3) - (a2<<1)*(y-1);
				tt += (b2<<1)*(x+1) - a2*((y<<1)-3);
				x++;
				y--;
				w = x-ox;
				h = oy-y;
				if (w&2 && h&2)
				{
					var dx, dy;
					if (oy!=b)
					{
						dx = 0;
						dy = 1;
						this.mkOvalQds(cx, cy, -x+1, x-1+wod, -oy, oy+hod, 1, 1);
					}
					else
					{
						dx = 1;
						dy = 0;
					}
					this.mkOvalQds(cx, cy, -x+2, x-2+wod, -oy-dy, oy+dy+hod, 1, 1);
					this.mkOvalQds(cx, cy, -x+dx, x-dx+wod, -y-1, y+1, 1, 1);
				}
				else this.mkOvalQds(cx, cy, -x+1, ox+wod, -oy, oy-h+1+hod, w, h);
				ox = x;
				oy = y;
			}
			else
			{
				st -= (a2<<1)*(y-1);
				tt -= a2*((y<<1)-3);
				y--;
			}
		}
		while (y);
		this.mkOvalQds(cx, cy, -a, ox+wod, -oy, 0, a-ox+1, oy+1+hod);
	}
}


function jsGraphicsFt()
{
	this.PLAIN = '';
	this.BOLD = 'font-weight:bold;';
	this.ITALIC = 'font-style:italic;';
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
	this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsGraphicsFt();


function jsGraphics(id)
{
	this.setColor = new Function('color', 'this.color = color;');
	this.setFont = new Function('fam','sz','sty',
		'this.ftFam = fam;'+
		'this.ftSz = sz;'+
		'if (sty) this.ftSty = sty;'
	);
	this.drawLine = new Function('x1','y1','x2','y2',
		'if (this.canvas) this.mkLine(x1, y1, x2, y2);'
	);
	this.drawPolyline = new Function('x','y',
		'if (!this.canvas) return;'+
		'var z = 0; while (z < x.length-1)'+
			'this.mkLine(x[z], y[z], x[++z], y[z]);'
	);
	this.drawPolyLine = this.drawPolyline;
	this.drawRect = new Function('x','y','w','h',
		'if (!this.canvas) return;'+
		'this.mkDiv(x, y, w, 1);'+
		'this.mkDiv(x+w, y, 1, h);'+
		'this.mkDiv(x, y+h, w+1, 1);'+
		'this.mkDiv(x, y, 1, h);'
	);
	this.fillRect = new Function('x','y','w','h',
		'if (this.canvas) this.mkDiv(x, y, w, h);'
	);
	this.drawPolygon = new Function('x','y',
		'if (!this.canvas) return;'+
		'this.drawPolyline(x, y);'+
		'this.mkLine(x[x.length-1], y[x.length-1], x[0], y[0]);'
	);
	this.drawEllipse = new Function('x','y','w','h',
		'if (this.canvas) this.mkOval(x, y, w, h, false);'
	);
	this.drawOval = this.drawEllipse;
	this.fillEllipse = new Function('x','y','w','h',
		'if (this.canvas) this.mkOval(x, y, w-1, h-1, true);'
	);
	this.fillOval = this.fillEllipse;
	this.drawString = mkLbl;
	this.clear = new Function(
		'if (!this.canvas) return;'+
		'this.canvas.innerHTML = this.defhtm;'+
		'this.htm = "";'
	);
	this.paint = new Function(
		'if (!this.canvas || !this.htm) return;'+
		'if (typeof this.canvas.appendChild != "undefined" &&'+
			'typeof document.createRange != "undefined" &&'+
			'typeof document.createRange().createContextualFragment != "undefined")'+
		'{'+
			'var x = document.createRange();'+
			'x.setStartBefore(this.canvas);'+
			'x = x.createContextualFragment(this.htm);'+
			'this.canvas.appendChild(x);'+
		'}'+
		'else this.canvas.innerHTML += this.htm;'+
		'if (!this.op7) this.htm = "";'
	);
	this.mkDiv = mkDiv;
	this.mkLine = mkLine;
	this.mkOval = mkOval;
	this.mkOvalQdsFill = new Function('cx','cy','xl','yt','yb','w','h',
		'xl += cx;'+
		'this.mkDiv(xl, cy+yt, w, h);'+
		'this.mkDiv(xl, cy+yb, w, h);'
	);
	this.mkOvalQds = new Function('cx','cy','xl','xr','yt','yb','w','h',
		'xr += cx;'+
		'xl += cx;'+
		'yt += cy;'+
		'yb += cy;'+
		'this.mkDiv(xr, yt, w, h);'+
		'this.mkDiv(xr, yb, w, h);'+
		'this.mkDiv(xl, yb, w, h);'+
		'this.mkDiv(xl, yt, w, h);'
	);
	this.canvas = (typeof document.all != "undefined" && document.all[id])? document.all[id]
		: (typeof document.getElementById != "undefined" && document.getElementById(id))? document.getElementById(id)
		: null;
	if (this.canvas && typeof this.canvas.innerHTML == "undefined")
		this.canvas = null;
	this.color = '#000000';
	this.ftFam = 'verdana,geneva,helvetica,sans-serif';
	this.ftSz = ((0x6&0xd|0x2)<<1) + String.fromCharCode((0x2|0x5)<<4,(0x6|0x9)<<3);
	this.ftSty = Font.PLAIN;
	this.defhtm = (this.canvas && this.canvas.innerHTML)? this.canvas.innerHTML : '';
	this.htm = '';
	this.op7 = ckOp7(this.canvas);
}
