// ===========================================================================================
// Copyright 2010
// by Asset Generation Elite Services, Inc.
// ===========================================================================================
function locObj(x, y, z, w, h, opa)
{
	this.x   = parseInt(x);
	this.y   = parseInt(y);
	this.z   = parseInt(z);
	this.w   = parseInt(w);
	this.h   = parseInt(h);
	this.opacitySet(opa);
}

locObj.prototype.opacitySet = function(opa)
{
	if (!((opa >= 0) && (opa <= 100)))
	{
		opa = 100;
	}

	if (opa > 100) opa = 100;
	if (opa <   0) opa = 0;

	this.opa = opa;
}

locObj.prototype.add = function(delta)
{
	if (delta == null)
		return;

	this.x   += delta.x;
	this.y   += delta.y;
	this.z   += delta.z;
	this.w   += delta.w;
	this.h   += delta.h;
	this.opacitySet(this.opa + delta.opa);
}

locObj.prototype.subtract = function(delta)
{
	if (delta == null)
		return;

	this.x   -= delta.x;
	this.y   -= delta.y;
	this.z   -= delta.z;
	this.w   -= delta.w;
	this.h   -= delta.h;
	this.opacitySet(this.opa - delta.opa);
}

locObj.prototype.give2ref = function(ref)
{
	var zee = (this.opa == 0)? 0:this.z;	// Completely transparent?  then move it to back until visible

	refPosSet(ref, this.x, this.y);
	refZeeSet(ref, zee);
	refSizeSet(ref, this.w, this.h);
}

locObj.prototype.give2obj = function(obj)
{
	this.give2ref(objStyleRef(obj));
	if (!((this.opa >= 0) && (this.opa <= 100)))
	{
		var xxx = 100;
	}
	var sq_opa = parseInt(100 * ((this.opa / 100) * (this.opa / 100)));
	if (!((sq_opa >= 0) && (sq_opa <= 100)))
	{
		var xxx = 100;
	}
	objOpacitySet(obj, sq_opa);
}

locObj.prototype.alertVal = function(texxt)
{
	alert(texxt+"X="+this.x+" Y="+this.y+" Z="+this.z+" W="+this.w+" H="+this.h+" OPA="+this.opa);
}

// ===========================================================================================
function sceneObj(kontent)
{
	this.content = kontent;		// Object which has the interesting info
	this.innerHTML = "";		// Generated by this.content.Display()
}

sceneObj.prototype.displayOptionGenerate = function(disp_opt_string)
{
	if (disp_opt_string == null) disp_opt_string = "";
	return(this.content.displayOptionGenerate(disp_opt_string));
}

sceneObj.prototype.displayClear = function()
{
	this.innerHTML = "";
}

sceneObj.prototype.display = function(disp_opt, w, h)
{
	this.innerHTML = this.content.display(disp_opt, w, h);

	return(this.innerHTML);
}

// ===========================================================================================
function SceneFind(lyst, scene, yank)
{
	var found = null;
	for(var i = 0; i < lyst.length; i++)
	{
		if (scene == lyst[i])
		{
			found = lyst[i];
			if (yank)
				lyst.splice(i--, 1);	// remove it from the lyst, decr index to reflect shorter lyst
			break;
		}
	}
	return(found);
}

// ===========================================================================================
function SceneFindByCode(lyst, kode, yank)
{
	var found = null;
	for(var i = 0; i < lyst.length; i++)
	{
		if (lyst[i].content.izCode(kode))
		{
			found = lyst[i];
			if (yank)
				lyst.splice(i--, 1);	// remove it from the lyst, decr index to reflect shorter lyst
			break;
		}
	}
	return(found);
}

function SubLystByKeyword(lyst, key, yank)	// Find and return (an Array of all) matches in lyst to keyword
{
	var foundLyst = new Array();
	for(var i = 0; i < lyst.length; i++)
	{
		if (lyst[i].content.izMatch(key))
		{
			foundLyst.push(lyst[i]);
			if (yank)
				lyst.splice(i--, 1);		// remove it from the lyst, decr index to reflect shorter lyst
		}
	}
	return(foundLyst);
}

// ===========================================================================================
function cardzObj(name, orig)
{
	this.name  = name;
	this.elem  = null;				// (Eventually) holds the element id for this cardz "div" HTML element
	this.myscene = null;			// (Eventually) holds (a pointer to) the scene being displayed
	this.my_w    = 0;
	this.my_h    = 0;
	this.myopt   = "";
	if (orig)
		this.curr  = orig.clone();
	else
		this.curr  = new locObj(  0,  0, 10, 100, 100,   0);
	this.prev  = this.curr.clone();
	this.idtag = -1;				// user defined ID Tag associated with cardz "innerHTML"

	this.step_delay = 100;			// time delay between steps (default value)
	this.tid   = 0;
	this.targ  = null;
	this.totalsteps = 0;			// How many total steps for current target
	this.steps = 0;					// Remaining Number of steps for xlate: curr --> to
									// Value of Zero means: no movement
									
	this.endrun = 4;				// threshold of nearness...no more "accel" & begin "bounce"
	this.bounce = false;			// true means create "bounce" effect during landing
									// false means no bounce effect

	this.accel  = false;			// true means to put "english" on the movement
									// false means that total movement is evenly divided between all steps
	this.rejunz = null;				// Array of relative "speed" of each step
	this.limz   = null;				// Array to hold calculated accumulation thresholds for each of the rejunz

	this.accelClear();
	this.accelRejunzAdd(4);
	this.accelRejunzAdd(5);
	this.accelRejunzAdd(6);
	this.accelRejunzAdd(7);
	this.accelRejunzAdd(8);
	this.accelRejunzAdd(6);
	this.accelRejunzAdd(4);
	this.accelRejunzAdd(1);

	this.accelActive();
	this.elemInit();
}

cardzObj.prototype.elemInit = function()
{
	if (this.elem)
	{
		this.xlateTarget(this.curr, 1);
	}
}

cardzObj.prototype.elemSetup = function(phase)
{
	this.elem  = objById(this.name);
	if (this.elem)
	{
		this.elemInit();
	}
	else
	{
		if (phase == 0)
			windowload_todo_list.funkAdd(new funcObj(this, cardzObj.prototype.elemSetup, phase + 1));
		else
		{
			alert("You Browser's Javascript is behaving oddly ... try FireFox! [ERROR: Cardz Elem == NULL]");
		}
	}
}

cardzObj.prototype.Open = function(elem_class)
{
	echo('<div class="' + elem_class + '" id="'+this.name+'"'+"\n");
}

cardzObj.prototype.Close = function()
{
	echo('</div>'+"\n");
	this.elemSetup(0);
}

cardzObj.prototype.elemSceneSet = function(idtag, scene, opt)
{
	this.myscene = scene;
	if (this.elem)
	{
		this.idtag = idtag;
		this.my_w  = this.curr.w;
		this.my_h  = this.curr.h;
		this.myopt = opt;
		this.elem.innerHTML = this.myscene.display(this.myopt, this.curr.w, this.curr.h);
	}
	else
	{
		windowload_todo_list.funkAdd(new funcObj(this, cardzObj.prototype.elemSceneSet, idtag, scene, opt));
	}
}

cardzObj.prototype.accelClear = function()
{
	this.accel = false;
	this.rejunz = new Array();
}

cardzObj.prototype.accelRejunzAdd = function(speed)
{
	if ((this.accel == false) && (speed > 0.1))
		this.rejunz.push(speed);
}

cardzObj.prototype.accelActive = function()
{
	if (this.rejunz.length == 0)
		return;

	// Calculate the total speed (for Normailzation)
	var totspeed = 0;
	for(var arr=0; arr < this.rejunz.length; arr++)
		totspeed += this.rejunz[arr];

	totspeed /= this.rejunz.length;
	if (totspeed == 0)
		totspeed = 1;

	// Now, normalize the speed list & create thresholds
	this.limz = new Array();
	for(var arr=0; arr < this.rejunz.length; arr++)
	{
		this.rejunz[arr] /= totspeed;
		this.limz.push(this.rejunz[arr]);
	}
	
	this.accel = true;
}

cardzObj.prototype.xlateTarget = function(target, deltaT)
{
	var num_steps = Math.ceil(deltaT / this.step_delay);

	if (target == null)
		num_steps = 0;

	if (num_steps < 0)
	    num_steps = 0;

	if (num_steps == 0)
		target = null;

	if (this.limz.length == 0)
		this.accel = false;

	this.targ  = target;
	this.totalsteps = num_steps;
	this.steps = num_steps;
	this.prev  = this.curr.clone();

	if (this.elem != null)
	{
		this.xlateStep();
	}
}

cardzObj.prototype.xlateStep = function()
{
	if ((this.targ == null) || (this.steps <= 0.01))
	{
		this.targ  = null;
		this.steps = 0;
		return;							// Always finished if steps == 0
	}

	var calcsteps  = this.steps;		// will never be less than One
	var rspeed     = 1;					// nominal speed
	var overshootFactor = 1;			// ...means "no overshoot"
	if (this.steps >= this.endrun)
	{
		if (this.accel)
		{
			var progress = (this.totalsteps - this.steps) / this.totalsteps;
			for(var arr=0; arr < this.rejunz.length; arr++)
			{
				if (progress < this.limz[arr])
				{
					rspeed = this.rejunz[arr];
					break;
				}
			}
			rspeed     = 1 / rspeed;
			calcsteps *= rspeed;
		}
	}
	else
	{
		this.steps = parseInt(this.steps);		// use integer-only math for final steps
		if (this.bounce)
		{
			overshootFactor = ((8 * this.steps) - 3) / 5;	// over < 60%; over == 0% for n==1
		}
		calcsteps = this.steps;
	}

	// Calculate and update the location for this step
	this.curr.x   += parseInt(overshootFactor * (this.targ.x   - this.curr.x)   / calcsteps);
	this.curr.y   += parseInt(overshootFactor * (this.targ.y   - this.curr.y)   / calcsteps);
	this.curr.z   += parseInt(overshootFactor * (this.targ.z   - this.curr.z)   / calcsteps);
	this.curr.w   += parseInt(overshootFactor * (this.targ.w   - this.curr.w)   / calcsteps);
	this.curr.h   += parseInt(overshootFactor * (this.targ.h   - this.curr.h)   / calcsteps);
	this.curr.opacitySet(this.curr.opa + parseInt(   (this.targ.opa - this.curr.opa) / calcsteps));

	// Apply the new location to the actual HTML design element
	this.curr.give2obj(this.elem);
	
	// Mark this step done
	this.steps -= rspeed;
	if ((this.steps >= 1) || (this.steps > 0.01))
	{
		// Schedule the next step
		this.timerStart(this.step_delay);
	}
	else
	{
		// full xlation is complete
		this.targ  = null;
		this.steps = 0;

		if (this.elem && this.myscene)
		{
			if ((this.my_w != this.curr.w) || (this.my_h != this.curr.h))
				this.elem.innerHTML = this.myscene.display(this.myopt, this.curr.w, this.curr.h);
		}
	}
}

cardzObj.prototype.timerCancel = function()
{
	if (this.tid != 0)
	{
		var tiddly = this.tid;
		this.tid = 0;
		clearInterval(tiddly);
		// TBD:  Set up pause-button to restart-timer
	}
}

cardzObj.prototype.timerStart = function(delta)
{
	var thisObj = this;
	
	this.timerCancel();
	this.tid = setTimeout(function() { thisObj.xlateStep(); }, delta);
}

// ===========================================================================================
function cardzTestObj(cardID)
{
	this.nomad = cardID;
	
	var orig = new locObj(  0,   0, 10, 200, 300,   0);
	this.nomad.xlateTarget(orig, 1);
	orig.opacitySet(100);

	this.stepz = new Array();	
	this.stepz.push(orig);
	this.stepz.push(new locObj(100,   0, 10, 100, 150,  60));
	this.stepz.push(new locObj(100, 100, 10, 100, 150,  40));
	this.stepz.push(new locObj(100, 100, 10,  50,  75,  70));
	this.stepz.push(new locObj(650,  50, 10, 150, 100, 100));
	this.stepz.push(new locObj(  0,   0, 10, 200, 300, 100));

	// Flambouyant Exit!!
	this.stepz.push(new locObj( -500, -500, 10,1000,1000,   0));
	// Flambouyant Entrace!!
	this.stepz.push(new locObj(  400,   50, 10, 150, 250, 100));
	this.stepz.push(new locObj(    0,    0, 10, 150, 250,   0));
	this.stepz.push(new locObj(  700,  200, 10, 150, 250,   0));
	this.stepz.push(new locObj(  200,   50, 10, 150, 250, 100));

//	this.nomad.curr.alertVal("Starting at ");

	this.migrwait(3000, 1000, 0);
}

cardzTestObj.prototype.migrwait = function(delay, steps, waypoint)
{
	var thisObj = this;

	if (waypoint < this.stepz.length)
	{
		this.nomad.xlateTarget(this.stepz[waypoint], steps);
		setTimeout(function() { thisObj.migrwait(delay, steps, waypoint + 1); }, delay);
	}
}

// ===========================================================================================
