/*
Actualy it's again just peaces of jQuerry library
*/

AjaxToolkit.effect = function(element) {
	
	var ef = {
		source: $(element)
	};
	
	ef.move = function(where, callback, opt) {
		opt = opt || {};
		opt.left = where.x;
		opt.top = where.y;
		
		this.animate(opt, opt.speed || "slow", callback);
	};
	
	ef.show = function(speed,callback){
		var hidden = this.source;
		if (speed) {
			this.animate({
				height: "show", width: "show", opacity: "show"
			}, speed, callback);
		} else {
			hidden.style.display = hidden.oldblock ? hidden.oldblock : "";
			if ( AjaxToolkit.css(hidden,"display") == "none" )
				hidden.style.display = "block";
		}
		return this;
	};

	ef.hide = function(speed,callback){
		var visible = this.source;
		if (speed) {
			this.animate({
				height: "hide", width: "hide", opacity: "hide"
			}, speed, callback);
		} else {
			visible.oldblock = visible.oldblock || AjaxToolkit.css(visible,"display");
			if ( visible.oldblock == "none" )
				visible.oldblock = "block";
			visible.style.display = "none";
		}
		return this;
	};
	
	ef.toggle = function( speed, callback ){
		return AjaxToolkit.isHidden(this.source) ? this.show(speed,callback) : this.hide(speed, callback);
	};
	
	ef.slideDown = function(speed,callback){
		return this.animate({height: "show"}, speed, callback);
	};
	
	ef.slideUp = function(speed,callback){
		return this.animate({height: "hide"}, speed, callback);
	};
	
	ef.fadeIn = function(speed, callback){
		return this.animate({opacity: "show"}, speed, callback);
	};
	
	ef.fadeOut = function(speed, callback){
		return this.animate({opacity: "hide"}, speed, callback);
	};
	
	ef.fadeTo = function(speed,to,callback){
		return this.animate({opacity: to}, speed, callback);
	};
	
	ef.slideToggle = function(speed, callback) {
		if (AjaxToolkit.isHidden(this.source)) return this.slideDown(speed,callback);
		return this.slideUp(speed,callback);
	};
	
	ef.autoSize = function(min, fix, speed) {
		if (!this.source._fitOptions) {
			this.source._fitOptions = {"min": min, "fix": fix, "speed": speed};
			_a.addEvent(this.source, "keyup", this.fitSize);
			_a.addEvent(this.source, "change", this.fitSize);
			this.source.style.height = (min || 20) + "px";
			this.source.style.overflowY = "hidden";
			this.source.className = this.source.className + ' autosize';
		}
		this.fitSize(1);
	};
	
	ef.fitSize = function(plain) {
		var el = this.source || this;
		if (el.scrollHeight > el.clientHeight && !el._inResize) {
			el._inResize = 1;
			var newH = el.scrollHeight;
			var min = el._fitOptions["min"] || 20;
			var fix = el._fitOptions["fix"] || 5;
			
			if (newH < min) {
				newH = el._fitOptions["min"];
			} else {
				newH = newH + fix;
			}
			if (plain) {
				ef.source.style.height = newH + "px";
				ef.source._inResize = 0; 
				ef.fitSize.call(ef.source, 1);
			} else {
				ef.animate({"height": newH}, el._fitOptions["speed"], function() {ef.source.focus(); ef.source._inResize = 0; ef.fitSize.call(ef.source);});
			}
		}
	}
	
	ef.queue = function(type,fn){
		if ( !fn ) {
			fn = type;
			type = "fx";
		}
	
		//return AjaxToolkit.each(function(){
			if ( !this.source.queue )
				this.source.queue = {};
	
			if ( !this.source.queue[type] )
				this.source.queue[type] = [];
	
			this.source.queue[type].push( fn );
		
			if ( this.source.queue[type].length == 1 )
				fn.apply(this.source);
		//});
	};
	
	ef.animate = function( prop, speed, easing, callback ) {
		return this.queue(function(){
		
			this.curAnim = prop || {};
			var opt = AjaxToolkit.effect(this).speed(speed, easing, callback);
			
			for ( var p in prop ) {
				var e = new AjaxToolkit.effect(this).fx( this, opt, p );
				if ( prop[p].constructor == Number )
					e.custom( e.cur(), prop[p] );
				else if (prop[p].length && !e[ prop[p] ]) {
					e.custom( prop[p][0], prop[p][1] );
				} else {
					e[ prop[p] ]( prop );
				}
			}
			
		});
	};
	
	ef.speed = function(speed, easing, fn) {
		var opt = speed && speed.constructor == Object ? speed : {
			complete: fn || !fn && easing || 
				AjaxToolkit.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && easing.constructor != Function && easing
		};

		opt.duration = (opt.duration && opt.duration.constructor == Number ? 
			opt.duration : 
			{ slow: 600, fast: 200 }[opt.duration]) || 400;
	
		// Queueing
		opt.old = opt.complete;
		opt.complete = function(){
			AjaxToolkit.effect(this).dequeue(this, "fx");
			if ( AjaxToolkit.isFunction( opt.old ) )
				opt.old.apply( this );
		};
	
		return opt;
	};
	
	ef.easing = {},
	
	//ef.source.queue = {},
	
	ef.dequeue = function(elem,type){
		type = type || "fx";
	
		if ( elem.queue && elem.queue[type] ) {
			// Remove self
			elem.queue[type].shift();
	
			// Get next function
			var f = elem.queue[type][0];
		
			if ( f ) f.apply( elem );
		}
	};

	/*
	 * I originally wrote fx() as a clone of moo.fx and in the process
	 * of making it small in size the code became illegible to sane
	 * people. You've been warned.
	 */
	
	ef.fx = function( elem, options, prop ){

		var z = this;

		// The styles
		var y = elem.style;
		
		// Store display property
		var oldDisplay = AjaxToolkit.css(elem, "display");

		// Make sure that nothing sneaks out
		y.overflow = "hidden";

		// Simple function for setting a style value
		z.a = function(){
			if ( options.step )
				options.step.apply( elem, [ z.now ] );

			if ( prop == "opacity" )
				AjaxToolkit.attr(y, "opacity", z.now); // Let attr handle opacity
			else if ( parseInt(z.now) ) // My hate for IE will never die
				y[prop] = parseInt(z.now) + "px";
			
			y.display = "block"; // Set display property to block for animation
		};

		// Figure out the maximum number to run to
		z.max = function(){
			return parseFloat( AjaxToolkit.css(elem,prop) );
		};

		// Get the current size
		z.cur = function(){
			var r = parseFloat( AjaxToolkit.curCSS(elem, prop) );
			return r && r > -10000 ? r : z.max();
		};

		// Start an animation from one number to another
		z.custom = function(from,to){
			z.startTime = (new Date()).getTime();
			z.now = from;
			z.a();

			z.timer = setInterval(function(){
				z.step(from, to);
			}, 13);
		};

		// Simple 'show' function
		z.show = function(){
			if ( !elem.orig ) elem.orig = {};

			// Remember where we started, so that we can go back to it later
			elem.orig[prop] = this.cur();

			options.show = true;

			// Begin the animation
			z.custom(0, elem.orig[prop]);

			// Stupid IE, look what you made me do
			if ( prop != "opacity" )
				y[prop] = "1px";
		};

		// Simple 'hide' function
		z.hide = function(){
			if ( !elem.orig ) elem.orig = {};

			// Remember where we started, so that we can go back to it later
			elem.orig[prop] = this.cur();

			options.hide = true;

			// Begin the animation
			z.custom(elem.orig[prop], 0);
		};
		
		//Simple 'toggle' function
		z.toggle = function() {
			if ( !elem.orig ) elem.orig = {};

			// Remember where we started, so that we can go back to it later
			elem.orig[prop] = this.cur();

			if(oldDisplay == "none")  {
				options.show = true;
				
				// Stupid IE, look what you made me do
				if ( prop != "opacity" )
					y[prop] = "1px";

				// Begin the animation
				z.custom(0, elem.orig[prop]);	
			} else {
				options.hide = true;

				// Begin the animation
				z.custom(elem.orig[prop], 0);
			}		
		};

		// Each step of an animation
		z.step = function(firstNum, lastNum){
			var t = (new Date()).getTime();

			if (t > options.duration + z.startTime) {
				// Stop the timer
				clearInterval(z.timer);
				z.timer = null;

				z.now = lastNum;
				z.a();

				if (elem.curAnim) elem.curAnim[ prop ] = true;

				var done = true;
				for ( var i in elem.curAnim )
					if ( elem.curAnim[i] !== true )
						done = false;

				if ( done ) {
					// Reset the overflow
					y.overflow = "";
					
					// Reset the display
					y.display = oldDisplay;
					if (AjaxToolkit.css(elem, "display") == "none")
						y.display = "block";

					// Hide the element if the "hide" operation was done
					if ( options.hide ) 
						y.display = "none";

					// Reset the properties, if the item has been hidden or shown
					if ( options.hide || options.show )
						for ( var p in elem.curAnim )
							if (p == "opacity")
								AjaxToolkit.attr(y, p, elem.orig[p]);
							else
								y[p] = "";
				}

				// If a callback was provided, execute it
				if ( done && AjaxToolkit.isFunction( options.complete ) )
					// Execute the complete function
					options.complete.apply( elem );
			} else {
				var n = t - this.startTime;
				// Figure out where in the animation we are and set the number
				var p = n / options.duration;
				
				// If the easing function exists, then use it 
				z.now = options.easing && ef.easing[options.easing] ?
					ef.easing[options.easing](p, n,  firstNum, (lastNum-firstNum), options.duration) :
					// else use default linear easing
					((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;

				// Perform the next step of the animation
				z.a();
			}
		};
		return z;
	};
	return ef;
};