function Path() {
	this.concat = int_concat;
	this.add = int_add;
	this.rotate = int_rot;
	
	function int_concat(p) {
		return new PathList(new Array(this, p));
	}
	
	function int_add(p) {
		return new PathAdd(this, p);
	}
	
	function int_rot(xc,yc,v) {
		return new RotatePath(this, xc, yc, v);
	}
}


// The following object is used for the concat
function PathList(inPathList) {
	// All path objects must have these 5 methods
	this.x  = 0;	// Retrieves the current x value
	this.y  = 0;
	this.step = int_step;			// Move to next step
	this.reset = int_reset;			// Resets the current position

	// The rest may vary from different path objects

	this.pathList = inPathList;
	this.currentPath = 0;

	function int_step() {
		if (this.currentPath >= this.pathList.length) return false;
		if (this.pathList[this.currentPath].step()) {
			this.x = this.pathList[this.currentPath].x;
			this.y = this.pathList[this.currentPath].y;
		}
		else {
			this.currentPath++;
			if (this.currentPath >= this.pathList.length) return false;
			this.x = this.pathList[this.currentPath].x;
			this.y = this.pathList[this.currentPath].y;
		}
		return true;
	}
	
	function int_reset() {
		this.currentPath = 0;
		for (var i=0; i<this.pathList.length; i++)
			this.pathList[i].reset();
		this.x = this.pathList[this.currentPath].x;
		this.y = this.pathList[this.currentPath].y;		
	}	
}


// The following object is used for adding two paths
function PathAdd(p1,p2) {
	// All path objects must have these 5 methods
	this.x  = 0;	// Retrieves the current x value
	this.y  = 0;
	this.step = int_step;			// Move to next step
	this.reset = int_reset;			// Resets the current position

	// The rest may vary from different path objects


	this._p1 = p1;
	this._p2 = p2;
	
	function int_step() {
		var c1 = this._p1.step();
		var c2 = this._p2.step();

		this.x = this._p1.x + this._p2.x;
		this.y = this._p1.y + this._p2.y;

		return (c1 || c2);
	}
	
	function int_reset() {
		this._p1.reset();
		this._p2.reset();

		this.x = this._p1.x + this._p2.x;
		this.y = this._p1.y + this._p1.y;
	}	
}

function RotatePath(p,xc,yc,v) {
	this.x  = 0;	// Retrieves the current x value
	this.y  = 0;
	this.step = int_step;			// Move to next step
	this.reset = int_reset;			// Resets the current position


	// The rest may vary from different path objects

	this._p = p;
	this._xc = xc;
	this._yc = yc;
	this._v = v;
	
	function int_step() {
		var c = this._p.step();

		var pol = toPol(this._p.x - this._xc, this._p.y - this._yc);
		var rec = toRec(pol.r, pol.v + toRad(this._v));

		this.x = rec.x + this._xc;
		this.y = rec.y + this._yc;

		return c;
	}
	
	function int_reset() {
		this._p.reset();
		var pol = toPol(this._p.x - this._xc, this._p.y - this._yc);
		var rec = toRec(pol.r, pol.v + toRad(this._v));

		this.x = rec.x - this._xc;
		this.y = rec.y - this._yc;
	}	

	function toPol(x,y) {
		var o = new Object();
		o.r = Math.sqrt(x*x + y*y);
		if (x == 0)
			o.v = Math.PI / 2;
		else
			o.v = Math.atan(y/x);
		if (x < 0)
			o.v = o.v + Math.PI;
		return o;
	}
	
	function toRec(r,v) {
		var o = new Object();
		o.x = r * Math.cos(v);
		o.y = r * Math.sin(v);
		return o;
	}

	function toRad(deg) {
		return deg*Math.PI/180;
	}
}

PathAdd.prototype    = new Path;
PathList.prototype   = new Path;
RotatePath.prototype = new Path;	