var scenes = Array();
var actors = Array();

function Scene(name,frameLength)
{
	scenes[name] = this;
	
	this.frames = Array();
	
	this.name = name;
	this.numFrames = 0;
	this.frameLength = frameLength;
	
	this.action = action;
	this.nextFrame = nextFrame;
	this.moveActors = moveActors;
	this.addActor = addActor;
	this.instructActor = instructActor;
	this.debug=debug;
}
/*
	Actor instructions
	
	style property to change
		
		property
		startValue
		endValue
		startFrame
		endFrame
		addPX
		
*/
function addActor(id)
{
	if (!actors[id])
		actors[id] = document.getElementById(id);		
}
function instructActor(id,instructions)
{
	this.addActor(id);
	
	if (instructions.endFrame)
	{
		if (instructions.endFrame>this.numFrames)
			this.numFrames = instructions.endFrame;
	}
	else
	{
		if (instructions.frame>this.numFrames)
			this.numFrames = instructions.frame;
	}
	
	if (instructions.type=='setStyle' || instructions.type=='setAttr')
	{
		if (!this.frames['f'+instructions.frame])
			this.frames['f'+instructions.frame] = '';
			
		this.frames['f'+instructions.frame] += ';'+id+':'+instructions.type+':'+instructions.property+':'+instructions.value;
	}
	else
	{
		var numFrames = instructions.endFrame-instructions.startFrame+1;
		
		var distance = (instructions.endValue-instructions.startValue);
		var px = (instructions.addPX?'px':'');
		
		var nStartFrame = instructions.startFrame;
		var nEndFrame = instructions.endFrame;
		
		var constSpeed = {
			stepSize: distance/numFrames
		};
		
		var nValue = instructions.startValue;
		var speed = 0;
		var frame = nStartFrame-1;
		var nStartPos = instructions.startValue;
		var nEndPos = instructions.endValue;
		
		if (instructions.accelerate)
		{
			var increment = constSpeed.stepSize/1000;
			while (Math.abs(increment)<Math.abs(constSpeed.stepSize))
			{
				frame += 1;
				increment *= 2;
				nValue += increment;
				
				if (!this.frames['f'+frame])
					this.frames['f'+frame] = '';
					
				this.frames['f'+frame] += ';'+id+':'+instructions.type+':'+instructions.property+':'+parseInt(nValue)+px;
			}		
			nStartFrame = (frame+1);
			nStartPos = nValue+increment;
		}
		if (instructions.decelerate)
		{
			nValue = instructions.endValue;
			var frame = instructions.endFrame+1;
			var increment = -constSpeed.stepSize/1000;
			while (Math.abs(increment)<Math.abs(constSpeed.stepSize))
			{
				frame -= 1;
				increment *= 2;
				nValue += increment;
				
				if (!this.frames['f'+frame])
					this.frames['f'+frame] = '';

				this.frames['f'+frame] += ';'+id+':'+instructions.type+':'+instructions.property+':'+parseInt(nValue)+px;
			}
			
			nEndFrame = (frame-1);
			nEndPos = nValue+increment;
		}
		constSpeed.stepSize = (nEndPos-nStartPos+1)/(nEndFrame-nStartFrame+1);
		nValue = nStartPos;
		for (var frame=nStartFrame;frame<=nEndFrame; frame++)
		{
			nValue += constSpeed.stepSize;
			
			if (!this.frames['f'+frame])
				this.frames['f'+frame] = '';
			
			this.frames['f'+frame] += ';'+id+':'+instructions.type+':'+instructions.property+':'+parseInt(nValue)+px;
		}
	}
}
var doWhatNext;
function action(afterEffects)
{
	if (afterEffects)
		doWhatNext = afterEffects;
	else
		doWhatNext = null;
		
	this.frame = 0;
	setTimeout('scenes[\''+this.name+'\'].nextFrame()',10);
}
function debug()
{
	for (var f=1; f<=this.numFrames; f++)
	{
		if (this.frames['f'+f])
			__debug('Frame '+f+': '+this.frames['f'+f]);
		else
			__debug('Frame '+f+': no movemet');
	}
}
function nextFrame()
{
	if (this.frame!=this.numFrames)
	{
		this.frame++;
		this.moveActors();
		setTimeout('scenes[\''+this.name+'\'].nextFrame()',this.frameLength);	
	}
	else
	{
		if (doWhatNext!=null)
			doWhatNext();
	}
}
function moveActors()
{	
	if (this.frames['f'+this.frame])
	{
		var frameDetails = this.frames['f'+this.frame];
		var instructions = frameDetails.split(';');
		for (var i=1; i<instructions.length; i++)
		{
			if (instructions[i]!='')
			{
				var details = instructions[i].split(':');
				var actor = actors[details[0]];
				
				if (details[1]=='position')
					actor.style[details[2]] = details[3];
					
				else if (details[1]=='transparency')
				{
					actor.style['opacity'] = parseInt(details[3])/100;
					actor.style['-moz-opacity'] = parseInt(details[3])/100;
					if (actor.filters)
						actor.filters.alpha['opacity'] = parseInt(details[3]);
				}
				else if (details[1]=='setStyle')
					actor.style[details[2]] = details[3];
					
				else if (details[1]=='setAttr')
					actor.setAttribute(details[2],details[3]);
			}
		}
	}
}


function __debug(txt)
{
	document.getElementById('debug').innerHTML += txt+'<br />';
}
