/*****************************************************************************
 * sprite handling class inspired by emile framework
 * https://github.com/madrobby/emile
 * coded for muddle-code.de
 *****************************************************************************/
function Sprite (parent, imgfile, opts)
{
	var me = this;
	
	this.param = {obj:undefined, width:0, height:0,runhandle:undefined,animhandle:undefined};

	this.param.width = opts.width;
	this.param.height= opts.height;
	
	//# valid opts {left, bottom, visible, width,height}
	//# prepare the parent
	
	var left = opts.left || 0;
	var bottom = opts.bottom || 0;
	var visible = opts.visible || "block";	
	
	$(parent).css("position", "relative");
	this.param.obj = document.createElement ("div");
	this.param.obj.setAttribute("style", "width:"+opts.width+"px;height:"+opts.height+"px;display:"+visible+";left:"+left+"px;bottom:"+bottom+"px;position:absolute;background-image:url("+imgfile+");");
	$(parent).append (this.param.obj);
	
	//# easing routines
	this._easing = function(func,pos)
	{
		if (func=="linear") {
			return pos;
		}
		else if (func=="spring") {
			return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
		}
		else if (func=="easeOutBounce") {
		   if ((pos) < (1/2.75)) {
			  return (7.5625*pos*pos);
			} else if (pos < (2/2.75)) {
			  return (7.5625*(pos-=(1.5/2.75))*pos + .75);
			} else if (pos < (2.5/2.75)) {
			  return (7.5625*(pos-=(2.25/2.75))*pos + .9375);
			} else {
			  return (7.5625*(pos-=(2.625/2.75))*pos + .984375);
			}
		}
		
		//# fallback means linear
		return pos;
	}

	//# hide the sprite
	this.hide = function ()
	{
		$(this.param.obj).css ("display","none");
		return this;
	}
	
	//# show the sprite
	this.show = function ()
	{
		$(this.param.obj).css("display", "block");
		return this;
	}
	
	//# let the effect perform like "the stage is yours"
	this.run = function (opts)
	{
		//# valid opts: {duration, from, to, property, ease, reverse}
		var start = (new Date).getTime();
		var dur   = opts.duration || 200;
		var finish= start+dur;
		
		//# set the start
		var unit = opts.property=="opacity" ? "" : "px";
		$(this.param.obj).css(opts.property, opts.from+unit);

		log ("running from "+ opts.from+" to "+opts.to+" (unit: "+unit+")");
		
		this.show ();
		
		this.param.runhandle = setInterval(function (){
					var time = (new Date).getTime();
					var pos = time>finish ? 1 : (time-start)/dur;

					//# move property
					var target  = parseInt (opts.to);
					var source  = parseInt (opts.from);
					var pingpong= opts.reverse || false;
					
					//# easing support
					var easing = opts.ease || "linear";
					pos = me._easing(easing,pos);
					var interpolate = (source+(target-source)*pos).toFixed(3);
					
					//log ("   "+opts.property+": "+interpolate+unit+"(pos: "+pos+")");
					$(me.param.obj).css(opts.property, interpolate+unit);

					if (time>finish) {
						clearInterval(me.param.runhandle);
						if (pingpong == true) {
							//# change from and to
							setTimeout (function(){me.run ({duration: dur, from: target, to: source, ease: easing,property:opts.property,reverse:true});},10);
						}
					}

			
		}, 20);
		return this;
	}
	
	//# stop all
	this.stop = function ()
	{
		if (this.param.animhandle) {
			clearInterval (this.param.animhandle);
			this.param.animhandle = undefined;
		}
		if (this.param.runhandle) {
			clearInterval (this.param.runhandle);
			this.param.runhandle = undefined;
		}
	}
	
	//# animated sprite
	this.animate = function (opts) 
	{
		//# valid opts {count,direction, fps,width}
		var	dir = opts.direction || "right";
		var count = opts.count || 1; 
		var begin = dir=="right" ? 0 : count;
		var end   = dir=="right" ? count-1 : begin+count-1;
		var rate  = opts.fps || 40;
		var width = this.param.width / count;
		var index = 0;
		
		this.param.animhandle = setInterval (function(){
			var pos = index*width * (-1);

			me.param.obj.style.width = width+"px";
			me.param.obj.style.backgroundPosition = pos+"px";			
			me.show ();
			
			index++;
			if (index > end) {
				index = begin;
			}
			
		}, rate);
		return this;		
	}
}


