﻿// list of effects already run to be reused
var effects = {};
// latest effect ran
var prevEffect = false;
// CSS initial properties for the elements on which we apply the effects
var initialElements = [];
// list of style properties to be monitored
var saveStyle = ['position', 'width', 'height', 'opacity', 'filter', 'top', 'left', 'backgroundColor', 'visibility', 'display'];

Spry.Effect.FadeBlind = function(element, options)
{
	Spry.Effect.Cluster.call(this, options);
	
	this.name = 'FadeBlind';
	var duration = 1000;
	var doToggle = false;
	var from = 100;
	var to = 0;

	if (options)
	{
		if (options.duration) duration = options.duration;
		if (options.toggle) doToggle = options.toggle;
		if (options.from) from = options.from;
		if (options.to) to = options.to;
	}

	var options = {duration: duration, from: from, to: to, toggle: doToggle};
	var blind = new Spry.Effect.Blind(element, options); 
	this.addParallelEffect(blind);

	var options = {duration: duration, from: from, to: to, toggle: doToggle};
	var fade = new Spry.Effect.Fade(element, options); 
	this.addParallelEffect(fade);
};

Spry.Effect.FadeBlind.prototype = new Spry.Effect.Cluster();
Spry.Effect.FadeBlind.prototype.constructor = Spry.Effect.FadeBlind; 

/* 
 * FadeSlide 
 * 		Custom Cluster effect that fade in/out and slide simultaneous an element
 * 		by running in parallel the Fade() and Slide() predefined clusters
 */

Spry.Effect.FadeSlide = function(element, options)
{
	Spry.Effect.Cluster.call(this, options);
	
	this.name = 'FadeSlide';
	var duration = 1000;
	var doToggle = false;
	var from = 100;
	var to = 0;

	if (options)
	{
		if (options.duration) duration = options.duration;
		if (options.toggle) doToggle = options.toggle;
		if (options.from) from = options.from;
		if (options.to) to = options.to;
	}

	var options = {duration: duration, from: from, to: to, toggle: doToggle};
	var slide = new Spry.Effect.Slide(element, options);
	this.addParallelEffect(slide);

	var options = {duration: duration, from: from, to: to, toggle: doToggle};
	var fade = new Spry.Effect.Fade(element, options);
	this.addParallelEffect(fade);
};

Spry.Effect.FadeSlide.prototype = new Spry.Effect.Cluster();
Spry.Effect.FadeSlide.prototype.constructor = Spry.Effect.FadeSlide;

var Observer = {};

/*
 * 	Observer.onPreEffect(obj)
 * 		Before running an effect forward the initial CSS values are saved.
 *    We will use later these when the animation will finish or is canceled 
 * 		to restore the animated element to be ready for the next effect.
 *    This function is automatically called by the effect.
 *  Parameters:
 * 		obj - the running effect that calls this function
 */
Observer.onPreEffect = function(obj){
	if (obj.direction && obj.direction == Spry.forwards)
		saveElement(obj.element);
	else
		restoreElement(obj.element);
};

/*
 * 	Observer.onCancel(obj)
 * 		When an effect is canceled this function will restore the element CSS.
 * 		Also we toggle the effect so the next time will run to go forward again.
 *    This function is automatically called by the effect.
 *  Parameters:
 * 		obj - the running effect that calls this function
 */
Observer.onCancel = function(obj){
	if (obj.direction == Spry.forwards)
		obj.doToggle();
	restoreElement(obj.element);
};

/*
 * 	Observer.onPostEffect(obj)
 *    This function is automatically called by the effect.
 *  Parameters:
 * 		obj - the running effect that calls this function
 */
Observer.onPostEffect = function(obj){
	//if (obj.direction == Spry.forwards)
	//	setTimeout(function(){obj.start()}, 150);
	//else
	//	restoreElement(obj.element);
	if (obj.direction == Spry.forwards)
		obj.element.style.display = 'none';
	//else
	//	obj.element.style.visibility = 'hidden';
};

/* 
 * saveElement(el)
 * 		Save into the global array of 'initialElements' some CSS properties 
 * 		of the given element that where altered by the animation running.
 * Parameters:
 *		el - the DOM element for which to save the CSS properties
 */
var saveElement = function(el){
	if (!initialElements[el.id])
	{
		initialElements[el.id] = {};
		for (var i = 0; i < saveStyle.length; i++)
		{
			initialElements[el.id][saveStyle[i]] = Spry.Effect.getStyleProp(el, saveStyle[i]);
		}
	}
};

/* 
 * restoreElement(el)
 * 		Restore from the global array 'initialElements' some CSS properties 
 * 		of the given element to prepare it for the next effect to run.
 * Parameters:
 *		el - the DOM element for which to restore the CSS properties
 */
var restoreElement = function(el){
	for (var i = 0; i < saveStyle.length; i++)
		el.style[saveStyle[i]] = initialElements[el.id][saveStyle[i]];
};

var runEffect = function(element, options, imgobj, closeimg, openimg, noeffect)
{
	if(noeffect){
		var obj=document.getElementById(element);
		if(obj.style.display=='none')
		{
			imgobj.src=closeimg;
			obj.style.display='block';
		}
		else
		{
			obj.style.display='none';
			imgobj.src=openimg;
		}
		return;
	}
	
	var effect='Squish';
	if (prevEffect && effects[prevEffect+'_'+element] && effects[prevEffect+'_'+element].isRunning){
		effects[prevEffect+'_'+element].cancel();
		setTimeout(function(){runEffect(effect, element, options)}, 150);
		return false;
	}

	if (!effects[effect+'_'+element]){
		effects[effect+'_'+element] = new Spry.Effect[effect](element, options);
		if (effect != 'Highlight' && effect != 'Shake' && effect != 'Pulsate')
			effects[effect+'_'+element].addObserver(Observer);	
	}

	if (effects[effect+'_'+element].direction == Spry.forwards)
		imgobj.src=closeimg;
	else
		imgobj.src=openimg;
		
	effects[effect+'_'+element].start();
	prevEffect = effect;
	return false;
};

