var Effect = new Object();

Effect.defaultTime = 6;

if(/MSIE/.test(navigator.userAgent) && (parseFloat(navigator.appVersion)<7)){
	Effect._setStyle = function(element, style){
		if(style["opacity"]){
			Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + 'alpha(opacity='+style["opacity"]*100+')' });
		}
		Element.setStyle(element, style);
	}

	Effect._getStyle = function(element, style){
		if(/opacity/.test(style)){
			if(opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
			if(opacity[1]) return parseFloat(opacity[1]) / 100;
			return 1.0;
		}
		return Element.getStyle(element, style);
	}
}
else{
	Effect._setStyle = Element.setStyle;
	Effect._getStyle = Element.getStyle;
}

Effect._parseColor = function(string){
	var rgb = string.split(/rgb\(|,|\)|#/g);
	if(rgb.length == 1) return [rgb[0]*0xFF0000, rgb[0]*0x00FF00, rgb[0]*0x0000FF];
	return rgb;
}

Effect._list = new Array();

Effect.Tween = Class.create();

Effect.Tween.prototype = {
	initialize: function(element, name, initialValue, goalValue, steps, units, onComplete){
		this.element	= $(element)
		this.name		= name;
		this.value		= parseFloat(initialValue);
		this.velocity	= 0;
		this.units		= units;
		this.setGoal(goalValue, steps, onComplete);
	},

	setGoal: function(goalValue, steps, onComplete){
		this.goal		= goalValue;
		this.steps		= steps;
		this.timer		= Math.ceil(steps/2) - steps % 2;
		this.sync		= steps % 2 - 1;
		this.Floaterval	= 4 * (goalValue - this.value - this.velocity * steps) / (steps * steps + 2 * steps + steps % 2);
		this.onComplete	= onComplete;
	},

	getGoal: function(){
		var value = new Object();
		value[this.name] = this.goal + this.units;
		return value;
	},

	getValue: function(){
		var value = new Object();
		value[this.name] = this.value + this.units;
		return value;
	},

	iterate: function(){
		if(this.steps == 1){
			this.velocity = 0;
			return false;
		}
		this.velocity = this.timer < this.steps-- ? this.velocity + this.Floaterval : this.sync ? this.velocity + ++this.sync : this.velocity - this.Floaterval;
		this.value = this.value + this.velocity;
		return true;
	}
}

Effect.setStyle = function(element, style, options){
	element = $(element);
	options = options || {};
	options.steps = options.steps || 6;
	var onCompleteInserted = false;

	for(name in style){
		var initialValue = Effect._getStyle(element, name);

		if(typeof initialValue != undefined){
			var initialTemp = initialValue;
			initialValue = initialValue.toString().split(/(?=(\D\D$))/,2);
			
			switch(initialValue.length){
				case 0: initialValue[0] = parseFloat(initialTemp);
				case 1: initialValue[1] = "";
			}
		}

		var goalValue = parseFloat(style[name]);

		var tween = Effect._list.find(function(storedTween){return (storedTween.element == element) && (storedTween.name == name);});
		if(tween) tween.setGoal(goalValue, options.steps, goalValue[1], options.onComplete);
		else Effect._list[Effect._list.length] = new Effect.Tween(element, name, initialValue[0], goalValue, options.steps, initialValue[1], options.onComplete);
	
		if(options.onComplete) options.onComplete = null;
	}

	if(!Effect._ticker)	Effect._ticker = new PeriodicalExecuter(function(){
		var keepers = new Array();
		var onCompletes = new Array();

		Effect._list.each(function(tween){
			if(tween.iterate()){
				Effect._setStyle(tween.element, tween.getValue());
				keepers[keepers.length] = tween;
			}
			else {
				Effect._setStyle(tween.element, tween.getGoal());
				if(tween.onComplete) onCompletes[onCompletes.length] = tween.onComplete;
			}
		});

		Effect._list = keepers;
		onCompletes.each(function(onComplete){onComplete()});
	}, 1/24);
}

Effect.AjaxRequest = Class.create();

Effect.AjaxRequest.prototype = {
	initialize: function(url, element, effectElement, style, options){
		
		options = options || {};
		this.stepsIn = options.stepsIn || 6;
		this.stepsOut = options.stepsOut || 6;
		this.onLoad = options.onLoad;
		this.element = element;
		this.effectElement = effectElement;

		this.style = style;
		
		if(!$(element).oldStyle){
			$(element).oldStyle = {};
			Object.extend($(element).oldStyle, this.style);
			for(name in $(element).oldStyle) $(element).oldStyle[name] = Effect._getStyle(effectElement, name).toString();
		}
		
		this.ajaxRequest = new Ajax.Request(url, {onComplete:function(response){
			this.flagRequest=true;
			this.content = response.responseText;
			this.finish();
		}.bindAsEventListener(this)});

		Effect.setStyle(this.effectElement, this.style, {steps:this.stepsIn, onComplete:function(){
			this.flagEffect=true;
			this.finish();
		}.bindAsEventListener(this)});
	},

	kill: function(){
		this.finish = function(){};
	},
	
	finish: function(){
		if(this.flagRequest && this.flagEffect){
			$(this.element).innerHTML = this.content;
			if(this.onLoad) this.onLoad();
			Effect.setStyle(this.effectElement, $(this.element).oldStyle, {steps:this.stepsOut});
			this.flagRequest = this.flagEffect = false;
		}
	}
}

Effect.setRollover = function(element){
	element = $(element);
	if(element&&(element.src.indexOf("_on") == -1)){
		var rollover = new Image();
		rollover.src = element.src.replace(/\.([^/]+)$/, "_over.$1");
		element.rolloveron	= function(){this.src = this.src.replace(/\.([^/]+)$/, "_over.$1")}.bindAsEventListener(element);
		element.rolloveroff	= function(){this.src = this.src.replace("_over", "")}.bindAsEventListener(element);
		Event.observe(element,"mouseover", element.rolloveron);
		Event.observe(element,"mouseout", element.rolloveroff);
	}
}

Effect.stopRollover = function(element){
	Event.stopObserving(element, "mouseover", element.rolloveron);
	Event.stopObserving(element, "mouseout", element.rolloveroff);
}

Effect.setSwitch = function(elements, options){
	options.activationEvent = options.activationEvent || "click";
	options.initialize = options.initialize || function(){};
	options.activate = options.activate || function(){};
	options.deactivate = options.deactivate || function(){};
	
	elements.each(function(element){
		var elementObject = $(element);
		options.initialize(elementObject);
		
		elementObject.activate		= options.activate;
		elementObject.deactivate	= options.deactivate;
		elementObject.isactive		= false;
		
		Event.observe(elementObject, options.activationEvent, function(){
			if(!this.isactive){
				this.activate(this);
				this.isactive = true;
			}
		}.bindAsEventListener(elementObject));
		
		elements.without(element).each(function(notElement){
			Event.observe(elementObject, options.activationEvent, function(){
				if(this.isactive){
					this.deactivate(this);
					this.isactive = false;
				}
			}.bindAsEventListener($(notElement)));
		});
	});	
}

