/**
 * This file contains custom Scriptaculus effects
 * These effects should add to the Scriptaculus library,
 * and have the same style/usage as the Scriptaculus library
 * 
 * This requires effects.js to be included before this file
 */


/**
 * A hider is an empty div that is used to cover up and disable an element.
 * There should be a hider element for each element we wish to disable.
 * 
 * If the second argument is given this acts as a setter, and sets the
 * hider of the given element. 
 * 
 * Otherwise, it returns the hider for the given element. If none exists, then
 * it creates one for that element
 * 
 * @param {Object} element
 * @param {Object} newhider - the hider to set
 */
Effect.ElementHider = function(element, newhider) {
	element = $(element);
	if (newhider) {
		element.hiderelement = newhider;
	}
	else if (!element.hiderelement) {
		var hider = new Element('div', { 'class': 'ElementHider' });
		$$('body')[0].insert(hider);
		element.hiderelement = hider.identify();
		hider.hide();
		hider.style.position = "absolute";
		hider.style.zIndex = 2;		
	}
	return element.hiderelement;
}

/**
 * Returns whether a given element is disabled using the Disable effect 
 * @param {Object} element
 */
Effect.IsDisabled = function (element) {
	var hider = $(element.hiderelement);
	return (hider && hider.visible());
}

/**
 * Initializes a hider element with the given arguments hash
 * @param {Object} hider the hider element
 * @param {Object} args  the arguments hash
 */
Effect.InitializeHider = function (hider, args) {
	var color;
	hider.update("");
	if (args) {
		var textcolor = args.textcolor || "#000";
		var textsize = args.textsize || "12pt";
		
		color = args.color;
		if (args.icon)
			hider.update(center_html("<img src='" + args.icon + "'>"));

		if (args.text)
			hider.update(center_html(args.text), "style=color: " + 
							textcolor + "; font-size: " + textsize + ";");	
	}
	hider.style.background = color || "#000";	
}

/**
 * Disable the given element by putting a semi-transparent element over it
 *
 * @param {Object} element
 */
Effect.Disable = function (element){
	element = $(element).cleanWhitespace();

	var hider = $(Effect.ElementHider(element));
	if (hider.visible())
		return;

	Element.clonePosition(hider, element);
	Effect.InitializeHider(hider, arguments[1]);

	var options = Object.extend({
		from: 0,
		to: 0.5,
		duration: 0.5,
		afterSetup: function(effect){
			effect.element.show();
		}
	}, arguments[1] || { });

	return new Effect.Opacity(hider,options);
}

/**
 * Enable the given element by hidding its assigned hider element.
 * This only works if the element has an assigned hider element, and
 * the hider element is visible.
 * 
 * @param {Object} element
 */
Effect.Enable = function (element){
	element = $(element).cleanWhitespace();

	var hider = $(Effect.ElementHider(element));
	if (!hider.visible())
		return;
	
	Element.clonePosition(hider, element);
	Effect.InitializeHider(hider, arguments[1]);

	var options = Object.extend({
		from: hider.getOpacity() || 0.5,
		to: 0,
		duration: 0.5,
		afterFinishInternal: function(effect){
			effect.element.hide();
		}
	}, arguments[1] || { });

	return new Effect.Opacity(hider,options);
}

/** This is a copy of the shake effect, but with less shakes! */
Effect.SmallShake = function(element) {
  element = $(element);
  var options = Object.extend({
    distance: 20,
    duration: 0.5
  }, arguments[1] || {});
  var distance = parseFloat(options.distance);
  var split = parseFloat(options.duration) / 10.0;
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element,
      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    
    new Effect.Move(effect.element,
      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
        effect.element.undoPositioned().setStyle(oldStyle);
  }}) }}) }}) }});
};







