/*
----------------------------------------------------------------------
EXAMPLE:

smooth=new Smooth({dyn:35, speed:-2, to:300});
smooth.onplay=function(pos){obj.style.height=pos+"px"};
smooth.onend=function(d){ _(obj).css({display:d>0?"block":"none"})};

----------------------------------------------------------------------
opt={
	dyn:     [-100..+100]   //dynamic scrolling (default:50)
	speed:   [-10..+10]     //scrolling speed (default:1)
	from:    [number]       //start position  (default:0)
	to:      [number]       //end position  (default:100)
}
methods={	
	go:      function(){};
	back:    function(){};
	start:   function(from, to){};
}
events={
	onstart: function(){};
	onplay:  function(){};
	onend:   function(){};
}
----------------------------------------------------------------------
*/

var Smooth=new _Class({
	dyn:0,
	speed:1,
	from:0,
	to:100,
	init:function(opt){
		this.dyn=(opt.dyn!=undefined?opt.dyn:-50)/100;
		this.speed=opt.speed?(opt.speed>0?opt.speed:-1/opt.speed):1;
		this.from=opt.from!=undefined?opt.from:this.from;
		this.to=opt.to!=undefined?opt.to:this.to;
		this.onstart=opt.onstart || this.onstart;
		this.onplay=opt.onplay || this.onplay;
		this.onend=opt.onend || this.onend;
		if(opt.autostart) opt.autostart>0?this.start():this.toogle();
	},
	start:function(from, to){
		if(from!=undefined) this.from=from;
		if(to!=undefined) this.to=to;
		this.d=this.from<this.to?1:-1; //direction
		this.startPos=this.from;
		this.endPos=this.to;
		this.range=0;
		if(this.tm){
			clearTimeout(this.tm);
			this.tm=null;
		}
		else{
			this.onstart(this.d);
			this.curPos=this.from;
		}
		this.onplay(this.curPos);
		this.play(); 
	},
	play:function(){
		var _this=this;
		if(this.dyn!=0) this.range=Math.round((this.dyn>0?(this.endPos-this.curPos)*this.dyn:-(this.curPos-this.startPos)*this.dyn)*this.speed);
		if(this.range*this.d<1) this.range=this.d*this.speed;
		this.curPos+=this.range;
		if(this.endPos*this.d<this.curPos*this.d) return this.end();
		this.onplay(this.curPos, this.curPos/this.endPos);
		this.tm=setTimeout(function(){_this.play()}, 0);
	},
	end:function(){
		clearTimeout(this.tm);
		this.tm=null;
		this.curPos=this.endPos;
		this.onend(this.d);
		return false;
	},
	toogle:function(){
		var t=this.from;
		this.from=this.to;
		this.to=t;	
		this.start();
	},
	onstart:function(d){},
	onplay:function(curPos){},
	onend:function(d){}
});



var Transition=new _Class({
	init:function(img, opt){
		var _this=this;
		this.img=img;
		this.dyn=opt.dyn!=undefined?opt.dyn:10;
		this.speed=opt.speed!=undefined?opt.speed:1;
		this.hardhide=opt.hardhide?1:0;
		this.smooth=new Smooth({
			dyn:_this.dyn, 
			speed:_this.speed,
			onstart:function(){_this.inTransition=1},
			onplay:function(pos){img.css({opacity:pos/100})},
			onend:function(){_this.inTransition=0}
		});
	},
	appear:function(){
		var _this=this;
		if(this.hardhide && this.smooth_disapear) this.smooth_disapear.end(); //hardhide disappearing if new appear (appear new from dark)
		setTimeout(function(){_this.smooth.start()}, 0); //setTimeout used for IE
	},
	disappear:function(){
		var _this=this;
		if(this.inTransition) this.smooth.end();
		if(this.smooth_disapear) this.smooth_disapear.end();
		this.img_disapear=_(this.img.parentNode).insert(this.img.cloneNode(true)).css({position:"absolute", zIndex:1, top:this.img.offsetTop, left:this.img.offsetLeft});
		this.smooth_disapear=new Smooth({
			dyn:_this.dyn, 
			speed:_this.speed,
			onplay:function(pos){_this.img_disapear.css({opacity:pos/100})},
			onend:function(){_this.smooth_disapear=_this.img_disapear=_this.img_disapear.remove();  _this.ondisapear()},
			autostart:-1
		});
		this.img.css({opacity:0});
	},
	ondisapear:function(){}
});



var EFX={
	slide:function(obj, b, opt){
		var sm=obj._efx_slide;
		if(!sm){
			opt=opt || {};
			opt.dyn=opt.dyn!=undefined?opt.dyn:50;
			opt.speed=opt.speed!=undefined?opt.speed:-1;
			opt.onstart=function(d){ obj.css({overflow:"hidden", paddingBottom:0, paddingTop:d<0?0:sm.css.paddingTop, height:sm.from, position:sm.css.position});};
			opt.onplay=function(pos){ obj.css({height:pos});};
			opt.onend=function(d){obj.css(sm.css); if(d<0) obj.css({display:"none"});};
			sm=obj._efx_slide=new Smooth(opt);
		}
		if(sm.isVisible!=undefined && sm.isVisible===b) return false;
		if(sm.tm) sm.toogle(); //if play is not finished
		else{
			var is_hidden=(obj.css("display")=="none");
			b=sm.isVisible=(b==undefined?(is_hidden?1:0):b);
			if(!is_hidden) obj.css({display:"none"});
			sm.css=obj.css(["overflow", "position", "paddingTop", "paddingBottom", "height"]);
			if(is_hidden) obj.css({position:"absolute"}); //for height init
			obj.css({display:"block"});
			var end=obj.offsetHeight-sm.css.paddingTop;
			sm.start(b?0:end, b?end:0);
		}
		return sm;
	},
	fade:function(obj, b, opt){
		var sm=obj._efx_fade;
		if(!sm){
			opt=opt || {};
			opt.dyn=opt.dyn!=undefined?opt.dyn:50;
			opt.speed=opt.speed!=undefined?opt.speed:-1;
			opt.onstart=function(d){obj.css({visibility:"visible", opacity:sm.from/100});};
			opt.onplay=function(pos){obj.css({opacity:pos/100}); };
			opt.onend=function(d){if(d<0) obj.css({visibility:"hidden"});};
			sm=obj._efx_fade=new Smooth(opt);
		}
		if(sm.isVisible!=undefined && sm.isVisible===b) return false;
		if(sm.tm) sm.toogle(); //if play is not finished 
		else {
			b=sm.isVisible=(b==undefined?(obj.css("visibility")=="hidden"?1:0):b);
			var end=100;
			sm.start(b?0:end, b?end:0);
		}
		return sm;
	}
};

