//	Javascript trim, ltrim, rtrim
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}
 
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
 
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}



//	Array Functions
function inArray (value, array)
{
	for (var i=0, l=array.length; i<l; ++i)
	{
		if (array[i] == value)
			return i;
	}
	return -1;
}
function rmFromArray (value, array)
{
	var i = inArray(value, array);
	if (i != -1) array.splice(i, 1);
	return array;
}
function is_array(input){
	return typeof(input)=='object'&&(input instanceof Array);
}



//	Create HTML element
function create_HTML (tag, obj) {
	
	if (!obj) obj = {};
	var elm	= document.createElement(tag);
	var a;
	switch (tag) {
		
		case 'img':
		a	= new Array('class', 'id', 'src', 'title', 'alt', 'style');
		break;
		
		case 'a' :
		a	= new Array('class', 'id', 'href', 'title', 'style');
		break;
		
		case 'input' :
		a	= new Array('class', 'id', 'type', 'value', 'title', 'name', 'style');
		break;
		
		case 'option' :
		a	= new Array('class', 'id', 'value', 'style');
		break;
		
		case 'iframe' :
		a	= new Array('class', 'id', 'src', 'style', 'name');
		break;
		
		case 'form' :
		a	= new Array('class', 'id', 'action', 'enctype', 'method', 'style');
		break;
		
		default :
		a	= new Array('class', 'id', 'style');
		break;
		
	}
	for (var i in obj) {
		if (inArray(i, a) != -1) {
			if (i == 'class') {
				elm.className = obj[i];
			} else if (i == 'style') {
				var styles	= obj[i].split(';');
				for (var j=0; j<styles.length; j++) {
					if (styles[j]) {
						var tmp	= styles[j].split(':');
						elm.style[trim(tmp[0])]	= trim(tmp[1]);
					}
				}
			} else {
				elm.setAttribute(i, obj[i]);
			}
		}
	}
	elm.removeAttribute('height');	//	Retrait des attributs automatiquement ajouté par IE (6 au moins)
	elm.removeAttribute('width');	//	Retrait des attributs automatiquement ajouté par IE (6 au moins)
	return elm;
	
}



//	SET OPACITY
//	o must be between 0 and 100
function set_opacity (e, o)
{
	o	= Number(o);
	e.style.opacity	= o/100;
	e.style.filter	= 'alpha(opacity=' + o + ')';
	/*
	-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; // first! IE8
	filter: alpha(opacity=50);					// second! IE7
	*/
}



//	FRAME MANAGER
//	Je suis coincé à utiliser la variable frameManager
//	l'appel à la fonction update() via setInterval perdant la référence à l'objet
function FrameManager ()
{
	this.fps		= 30;		//	Frame Per Second rate
	this.frameCount	= 0;		//	Number of frame played
	this.objects	= [];		//	Array of Objects to update by FrameManager.update()
	this.intervalId;			//	Interval Id
}
FrameManager.prototype = {
	start : function ()
	{
		this.intervalId	= setInterval(frameManager.update, Math.round(1000/this.fps));
	},
	
	stop : function ()
	{
		clearInterval(this.intervalId);
	},
	
	update : function ()
	{
		frameManager.frameCount++;
		for (var i=0; i<frameManager.objects.length; i++)
		{
			frameManager.objects[i].frameUpdate();
		}
	},
	
	set_frameRate : function (fps)
	{
		this.fps	= fps;
		this.stop();
		this.start();
	},
	
	search_object : function (object)
	{
		for (var i=0; i<this.objects.length; i++)
			if (this.objects[i] == object) return i;
		return false;
	},
	
	add_object : function (object)
	{
		if (this.search_object(object) === false)
			this.objects.push(object);
	},
	
	rm_object : function (object)
	{
		var search	= this.search_object(object);
		if (search !== false)
			this.objects.splice(search, 1);
	}
}
var frameManager	= new FrameManager();



//	MOTION OBJECT
function Motion (e)
{
	this.element		= e;			//	HTML element motion target
	this.frameManager	= frameManager;	//	FrameManager instance
	this.motions		= [];			//	Array of motions for element
	this.repeat			= false;		//	Repeat mode. If true, motion is put to the end of the list at its end. If false, motion is removed
}
Motion.prototype = {
	search_motion : function (motion)
	{
		for (var i=0; i<this.motions.length; i++)
			if (this.motions[i] == motion) return i;
		return false;
	},
	
	rm_motion : function (motion)
	{
		var search	= this.search_motion(motion);
		if (search !== false)
			this.motions.splice(search, 1);
	},
	
	end_motion : function (motion)
	{
		if (this.repeat)
		{
			motion.state	= 'init';
			var i	= this.search_motion(motion);
			this.motions.splice(i, 1);
			this.motions.push(motion);
		}
		else
		{
			this.rm_motion(motion);
		}
	},
	
	fade : function (start, end, speed, easeIn, easeOut)
	{
		var motion	= {
			'type':'fade', 'state':'init', 'vars':{'start':start, 'end':end, 'speed':speed, 'easeIn':easeIn, 'easeOut':easeOut}
			};
		this.motions.push(motion);
		this.frameManager.add_object(this);
	},
	
	_fade : function (motion)
	{
		switch (motion.state)
		{
			case 'init':
			set_opacity(this.element, motion.vars.start);
			motion.vars.opacity	= motion.vars.start
			motion.state		= 'read';
			break;
			
			case 'read':
			if (motion.vars.speed > 0)
			{
				if (motion.vars.opacity >= motion.vars.end)
				{
					set_opacity(this.element, motion.vars.end);
					this.end_motion(motion);
					return false;
				}
			}
			else
			{
				if (motion.vars.opacity <= motion.vars.end)
				{
					set_opacity(this.element, motion.vars.end);
					this.end_motion(motion);
					return false;
				}
			}
			motion.vars.opacity	+= motion.vars.speed;
			set_opacity(this.element, motion.vars.opacity);
			break;
			
			case 'end':
			default:
			break;
		}
	},
	
	frameUpdate : function ()
	{
		if (this.motions.length == 0)
		{
			this.frameManager.rm_object(this);
			return false;
		}
		switch (this.motions[0].type)
		{
			case 'fade':
			this._fade(this.motions[0]);
			break;
			
			default:
			break;
		}
	}
}



//	ANIM MANAGER
function AnimManager ()
{
	this.imgDisplayed	= false;			//	Number of the img wich is displayed
	this.elements		= [];				//	List of elements useds in anim
	this.targetElement;						//	Element wich will receive the anim
	this.inProgress		= false;			//	Anim is in progress
	this.motion			= false;			//	Motion object
	this.frameCount		= 0;				//	Number of frame since the last motion was launched
	this.displayTime	= 60;				//	Display Time of image in frame
	this.animSpeed		= 3;				//	Anim speed
	this.targetElement	= document;			//	HTML element wich will receive the anim
}
AnimManager.prototype = {
	init : function (vars)
	{
		if (!vars.imgs)
			return false;
		if (vars.element)
			this.targetElement	= vars.element;
		if (vars.fps)
			frameManager.set_frameRate(vars.fps);
		if (vars.imgDisplayTime)
			this.displayTime = Math.round(vars.imgDisplayTime * frameManager.fps);
		if (vars.animSpeed)
			this.animSpeed = vars.animSpeed;
		
		for (var i=0; i<vars.imgs.length; i++)
		{
			var element		= create_HTML('img', {src:vars.imgs[i], style:'position:absolute; top:0px; left:0px;'});
			element.onload	= function () {this.loaded = true;};
			element.motion	= new Motion(element);
			this.elements.push(element);
		}
		frameManager.add_object(this);
		frameManager.start();
	},
	
	frameUpdate : function ()
	{
		if (!this.inProgress)
		{
			if (this.changeElement())
				this.inProgress = true;
		}
		else
		{
			this.frameCount++;
		}
		
		if (this.frameCount > this.displayTime)
		{
			if (this.changeElement())
				this.frameCount	= 0;
		}
	},
	
	changeElement : function ()
	{
		if (!isNaN(this.imgDisplayed) && (this.imgDisplayed < this.elements.length-1))
			this.imgDisplayed++
		else
			this.imgDisplayed = 0;
		
		if (this.elements[this.imgDisplayed].loaded || isOnloadProblemBrowser())
		{
			this.targetElement.appendChild(this.elements[this.imgDisplayed]);
			this.elements[this.imgDisplayed].motion.fade(0, 100, 3);
			return true;
		}
		else
		{
			this.imgDisplayed = false;
			return false;
		}
	}
}
var animManager	= new AnimManager();

