Transition = {
	FADE_IN : "FadeIn",
	FADE_OUT : "FadeOut",
	GROW_LEFT : "GrowLeft",
	GROW_LEFT_DOWN : "GrowLeftDown",
	GROW_LEFT_UP : "GrowLeftUp",
	GROW_RIGHT : "GrowRight",
	GROW_RIGHT_DOWN : "GrowRightDown",
	GROW_RIGHT_UP : "GrowRightUp",
	addEffect : function(element, effect, attributeStr) {
		var effectClassName = effect + "Effect";
		if (!window[effectClassName]) return;
		var applyToElement = ((element == document) || (element == window)) ? document.body : element;
		if (!applyToElement.effects) applyToElement.effects = new EffectsCollection();
		if (applyToElement != element) element.effects = applyToElement.effects;
		applyToElement.effects[effect] = new window[effectClassName](applyToElement);
		if (attributeStr) {
			var attributes = attributeStr.split(",");
			for (var i=0; i<attributes.length; i++) {
				var attComponents = attributes[i].split("=");
				if (attComponents.length < 2) continue;
				var methodName = "set" + Transition.capitalize(attComponents[0]);
				if (!applyToElement.effects[effect][methodName]) continue;
				applyToElement.effects[effect][methodName](attComponents[1]);
			}
		}
	},
	capitalize : function(str) {
		var newStr = str.replace(/^[a-z]/, function(c) { return c.toUpperCase(); });
		return newStr;
	},
	removeEffect : function(element, effect) {
		if (!element.effects || !element.effects[effect]) return;
		delete(element.effects[effect]);
	}
};
function EffectsCollection() {}
EffectsCollection.prototype.play = function() {
	if (arguments.length) {
		for (var i=0; i<arguments.length; i++) {
			if (this[arguments[i]]) this[arguments[i]].play();
		}
	} else {
		for (var effect in this) {
			if (this[effect] instanceof Effect) this[effect].play();
		}
	}
}
function Effect() {
	this.duration = Effect.DEFAULT_DURATION;
	this.increment = Effect.DEFAULT_INCREMENT_MS;
}
Effect.DEFAULT_DURATION = 1;
Effect.DEFAULT_INCREMENT_MS = .1;
Effect.prototype.play = function() {}
Effect.prototype.setDuration = function(duration) { this.duration = duration; }
Effect.prototype.setIncrement = function(increment) { this.increment = increment; }
function FadeOutEffect(element) {
	if (!element) return;
	this.bgElement = element;
	if (!this.bgElement.id) this.bgElement.id = "FADEEFFECT" + Math.floor(Math.random() * 1000000);
	this.interval = null;
	this.type = Transition.FADE_OUT;
	this.opacity = FadeOutEffect.DEFAULT_OPACITY;
	this.direction = 1;
	this.backgroundColor = FadeOutEffect.DEFAULT_BG_COLOR;
	this.opacityFraction = -1;
}
FadeOutEffect.prototype = new Effect;
FadeOutEffect.DEFAULT_BG_COLOR = "#000000";
FadeOutEffect.DEFAULT_OPACITY = 50;
FadeOutEffect.ELEMENT_NAME_ROOT = "transitionFadeElement_";
FadeOutEffect.prototype.finish = function() {
	window.clearInterval(this.interval);
}
FadeOutEffect.prototype.getFadeElement = function() {
	var fadeElement = document.getElementById(FadeOutEffect.ELEMENT_NAME_ROOT + this.bgElement.id);
	if (!fadeElement) {
		var fadeElement = document.createElement("div");
		fadeElement.id = FadeOutEffect.ELEMENT_NAME_ROOT + this.bgElement.id;
		fadeElement.style.position = "absolute";
		fadeElement.style.display = "none";
		fadeElement.style.zIndex = 999;
		fadeElement.style.backgroundColor = this.backgroundColor;
		fadeElement.style.filter = "alpha(opacity=0)";
		fadeElement.style.opacity = 0;
		document.body.appendChild(fadeElement);
	}
	return fadeElement;
}
FadeOutEffect.prototype.getHeight = function() {
	return (this.bgElement == document.body) ? Math.max(this.bgElement.clientHeight, this.bgElement.scrollHeight) : this.bgElement.offsetHeight;
}
FadeOutEffect.prototype.getLeft = function() { return this.bgElement.offsetLeft; }
FadeOutEffect.prototype.getTop = function() { return this.bgElement.offsetTop; }
FadeOutEffect.prototype.getWidth = function() {
	if (jQuery.browser.msie) return (this.bgElement == document.body) ? Math.max(document.body.clientWidth,document.body.scrollWidth) : this.bgElement.offsetWidth;
	else return (this.bgElement == document.body) ? Math.max(document.body.clientWidth,parseInt(jQuery("#designWrapper").css('width'))) : this.bgElement.offsetWidth;
}
FadeOutEffect.prototype.play = function() {
	var fadeElement = this.getFadeElement();
	var currentOpacity = (fadeElement.filters) ? fadeElement.style.opacity = 0.1 : fadeElement.style.opacity * 100;
	this.opacityFraction = (this.opacity - currentOpacity) / (this.duration / this.increment);
	fadeElement.style.width = this.getWidth();
	fadeElement.style.height = this.getHeight();
	fadeElement.style.top = this.getTop();
	fadeElement.style.left = this.getLeft();
	this.bgElement.effects[this.type].repeat();
	this.interval = window.setInterval("document.getElementById('" + this.bgElement.id + "').effects['" + this.type + "'].repeat();", this.increment * 1000);
	fadeElement.style.display = "block";
}
FadeOutEffect.prototype.repeat = function() {
	var fadeElement = this.getFadeElement();
	var currentOpacity = (fadeElement.filters) ? fadeElement.style.opacity = 0.1 : fadeElement.style.opacity * 100;
	var newOpacity = currentOpacity + this.opacityFraction;
	if ((newOpacity * this.direction) >= this.opacity) {
		fadeElement.style.filter = "alpha(opacity=" + this.opacity + ")";
		fadeElement.style.opacity = this.opacity / 100;
		this.finish();
	} else {
		fadeElement.style.filter = "alpha(opacity=" + newOpacity + ")";
		fadeElement.style.opacity = newOpacity / 100;
	}
}
FadeOutEffect.prototype.setBackgroundColor = function(bgColor) { this.backgroundColor = bgColor; }
FadeOutEffect.prototype.setOpacity = function(opacity) { this.opacity = opacity; }
function FadeInEffect(element) {
	this.superClass(element);
	this.type = Transition.FADE_IN;
	this.opacity = FadeInEffect.DEFAULT_OPACITY;
	this.direction = -1;
}
FadeInEffect.prototype = new FadeOutEffect;
FadeInEffect.prototype.superClass = FadeOutEffect;
FadeInEffect.DEFAULT_OPACITY = 0;
FadeInEffect.prototype.finish = function() {
	window.clearInterval(this.interval);
	this.getFadeElement().style.display = "none";
}

function GrowEffect(element, horizontal, vertical) {
	if (!arguments.length) return;
	var horName = (horizontal == 0) ? "" : ((horizontal == -1) ? "_LEFT" : "_RIGHT");
	var vertName = (vertical == 0) ? "" : ((vertical == -1) ? "_DOWN" : "_UP");
	this.type = Transition["GROW" + horName + vertName];
	this.element = element;
	this.horizontal = horizontal;
	this.vertical = vertical;
	this.top = this.left = -1;
	this.width = this.height = -1;
	this.clipTop = this.clipRight = this.clipBottom = this.clipLeft = -1;
	this.xFraction = this.yFraction = -1;
}
GrowEffect.prototype = new Effect;
GrowEffect.DIRECTIONS = {y: {Up:1, Down:-1}, x: {Right: 1, Left: -1}};
GrowEffect.prototype.finish = function() {
	this.element.style.visibility = "visible";
}
GrowEffect.prototype.incrementPosition = function() {
}
GrowEffect.prototype.incrementClip = function() {
}
GrowEffect.prototype.play = function() {
	this.top = this.element.offsetTop;
	this.left = this.element.offsetLeft;
	this.width = this.element.offsetWidth;
	this.height = this.element.offsetHeight;
	this.xFraction = this.element.offsetWidth / (this.duration / this.increment);
	this.yFraction = this.element.offsetHeight / (this.duration / this.increment);
	this.setPosition(this.left + this.width, this.top + this.height);
	this.setClip(0, 0, 0, 0);
	this.element.effects[this.type].repeat();
	this.interval = window.setInterval("document.getElementById('" + this.element.id + "').effects['" + this.type + "'].repeat();", this.increment * 1000);
	this.finish();
}
GrowEffect.prototype.repeat = function() {
	if (this.element.offsetTop - this.yFraction <= this.top) {
		window.clearInterval(this.interval);
		this.setPosition(this.left, this.top);
		this.setClip(0, this.width, this.height, 0);
	} else {
		this.setPosition(this.element.offsetLeft - this.xFraction, this.element.offsetTop - this.yFraction);
		this.setClip(0, this.clipRight + this.xFraction, this.clipBottom + this.yFraction, 0);
	}
}
GrowEffect.prototype.setClip = function(t, r, b, l) {
	this.clipTop = t;
	this.clipRight = r;
	this.clipBottom = b;
	this.clipLeft = l;
	this.element.style.clip = "rect(" + t + "px, " + r + "px, " + b + "px, " + l + ")";
}
GrowEffect.prototype.setPosition = function(x, y) {
	this.element.style.left = x + "px";
	this.element.style.top = y + "px";
}
for (var hDir in GrowEffect.DIRECTIONS.x) {
	generateGrowSubClass("Grow" + hDir + "Effect", GrowEffect.DIRECTIONS.x[hDir], 0);
	for (var vDir in GrowEffect.DIRECTIONS.y) {
		generateGrowSubClass("Grow" + hDir + vDir + "Effect", GrowEffect.DIRECTIONS.x[hDir], GrowEffect.DIRECTIONS.y[vDir]);
	}
}
for (var vDir in GrowEffect.DIRECTIONS.y) {
	generateGrowSubClass("Grow" + vDir + "Effect", 0, GrowEffect.DIRECTIONS.y[vDir]);
}
function generateGrowSubClass(className, horizontal, vertical) {
	window[className] = new Function("element", "this.superClass(element, " + horizontal + ", " + vertical + ");");
	window[className].prototype = new GrowEffect;
	window[className].prototype.superClass = GrowEffect;
}
