/**
* @fileoverview Provides the YUI with several built-in effect combinations.
* @author Dav Glass <dav.glass@yahoo.com>
* @version 0.1 
* @class Provides the YUI with several built-in effect combinations.
* @requires YAHOO.util.Dom
* @requires YAHOO.util.Anim
*/
YAHOO.widget.Effects = function() {
	
/**
* @class Provides the YUI with several built-in effect combinations.
* @constructor
*/
}
/**
* @constructor
* This effect makes the object expand & dissappear.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1<br>
* }</code>
*/
YAHOO.widget.Effects.Puff = function(inElm, opts) {
    var start_elm = YAHOO.util.Dom.get(inElm);
    /**
    * DOM manipulation...
    * @type HTMLElement
    */
    var elm = start_elm.cloneNode(true);
    start_elm.parentNode.replaceChild(elm, start_elm);
    YAHOO.widget.Effects.Hide(start_elm);
    
    /**
    * Current location on the page
    * @type Array
    */
    var xy = YAHOO.util.Dom.getXY(elm);
    /**
    * Get the Height
    * @type Integer
    */
    var h = parseInt(YAHOO.util.Dom.getStyle(elm, 'height'));
    /**
    * Get the Width
    * @type Integer
    */
    var w = parseInt(YAHOO.util.Dom.getStyle(elm, 'width'));
    
    /**
    * One and a Half Times Bigger than it is
    */
    var nh = ((h / 2) + h);
    var nw = ((w / 2) + w);
    /**
    * Adjust position based on the new height and width
    */
    var nto = ((nh - h) / 2);
    var nlo = ((nw - w) / 2);
    var nt = xy[1] - nto;
    var nl = xy[0] - nlo;
    
    /**
    * Position needs to be absolute, so the new Height & Width will work
    */
    YAHOO.util.Dom.setStyle(elm, 'position', 'absolute');
    
    var attributes = {
        top: { to: nt },
        left: { to: nl },
        width: { to: nw },
        height: { to: nh },
        opacity: { from: 1, to: 0 }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var puff = new YAHOO.util.Anim(elm, attributes, secs, ease);
    puff.onComplete.subscribe(function() {
        var elm = this.getEl();
        /**
        * Replace the "cloned" element so we can put the original back with display:none set from above
        */
        elm.parentNode.replaceChild(start_elm, elm);
    });
    puff.animate();
    
    return puff;
}
/**
* @constructor
* @class This effect makes the object dissappear with display none.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
*/
YAHOO.widget.Effects.Hide = function(inElm) {
    var elm = YAHOO.util.Dom.get(inElm);
    YAHOO.util.Dom.setStyle(elm, 'display', 'none');
}
/**
* @constructor
* @class This effect makes the object Appear with display block.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
*/
YAHOO.widget.Effects.Show = function(inElm) {
    var elm = YAHOO.util.Dom.get(inElm);
    YAHOO.util.Dom.setStyle(elm, 'display', 'block');
}
/**
* @constructor
* @class This effect makes the object fade & disappear.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1<br>
* }</code>
*/
YAHOO.widget.Effects.Fade = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    var attributes = {
        opacity: { from: 1, to: 0 }
    };

    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var fade = new YAHOO.util.Anim(elm, attributes, secs, ease);
    fade.onComplete.subscribe(function() {
        var elm = this.getEl();
        YAHOO.widget.Effects.Hide(elm);
    });
    fade.animate();
    return fade;
}
/**
* @constructor
* @class This effect makes the object fade & appear.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 3<br>
* }</code>
*/
YAHOO.widget.Effects.Appear = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    YAHOO.util.Dom.setStyle(elm, 'opacity', '0');
    YAHOO.widget.Effects.Show(elm);
    var attributes = {
        opacity: { from: 0, to: 1 }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 3);

    var appear = new YAHOO.util.Anim(elm, attributes, secs, ease);
    appear.animate();
    return appear;
}
/**
* @constructor
* @class This effect makes the object act like a window blind and retract.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1<br>
* }</code>
*/
YAHOO.widget.Effects.BlindUp = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    elm._height = YAHOO.util.Dom.getStyle(elm, 'height');
    YAHOO.util.Dom.setStyle(elm, 'overflow', 'hidden');
    var attributes = {
        height: { to: 0 }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var bup = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bup.onComplete.subscribe(function() {
        var elm = this.getEl();
        YAHOO.widget.Effects.Hide(elm);
        YAHOO.util.Dom.setStyle(elm, 'height', elm._height);
    });
    bup.animate();
    return bup;
}
/**
* @constructor
* @class This effect makes the object act like a window blind opening.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1<br>
* }</code>
*/
YAHOO.widget.Effects.BlindDown = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    var elmH = parseInt(YAHOO.util.Dom.getStyle(elm, 'height'));
    YAHOO.util.Dom.setStyle(elm, 'overflow', 'hidden');
    YAHOO.util.Dom.setStyle(elm, 'height', '0');
    YAHOO.widget.Effects.Show(elm);
    var attributes = {
        height: { from: 0, to: elmH }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var bdown = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bdown.animate();
    return bdown;
}

/**
* @constructor
* @class This effect makes the object slide open from the right.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1<br>
* }</code>
*/
YAHOO.widget.Effects.BlindRight = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    var elmW = parseInt(YAHOO.util.Dom.getStyle(elm, 'width'));
    YAHOO.util.Dom.setStyle(elm, 'overflow', 'hidden');
    YAHOO.util.Dom.setStyle(elm, 'width', '0');
    YAHOO.widget.Effects.Show(elm);
    var attributes = {
        width: { from: 0, to: elmW }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var bright = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bright.animate();
    return bright;
}
/**
* @constructor
* @class This effect makes the object slide closed from the left.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1<br>
* }</code>
*/
YAHOO.widget.Effects.BlindLeft = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    var elmW = YAHOO.util.Dom.getStyle(elm, 'width');
    elm._width = elmW;
    YAHOO.util.Dom.setStyle(elm, 'overflow', 'hidden');
    var attributes = {
        width: { to: 0 }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var bleft = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bleft.onComplete.subscribe(function() {
        var elm = this.getEl();
        YAHOO.widget.Effects.Hide(elm);
        YAHOO.util.Dom.setStyle(elm, 'width', elm._width);
        elm._width = null;
    });
    bleft.animate();
    return bleft;
}
/**
* @constructor
* @class This effect makes the object appear to fold up.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1,<br>
*   to: 5,<br>
* }</code>
*/
YAHOO.widget.Effects.Fold = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    elm._to = 5;
    YAHOO.util.Dom.setStyle(elm, 'overflow', 'hidden');
    YAHOO.widget.Effects.Show(elm);
    elm._height = YAHOO.util.Dom.getStyle(elm, 'height');
    elm._width = YAHOO.util.Dom.getStyle(elm, 'width');
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);
    if (opts && opts.to) {
        elm._to = opts.to;
    }
    
    var attributes = {
        height: { to: elm._to }
    };

    var bfold = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bfold.onComplete.subscribe(function() {
        var elm = this.getEl();
        if (this.done) {
            YAHOO.widget.Effects.Hide(elm);
            YAHOO.util.Dom.setStyle(elm, 'height', elm._height);
            YAHOO.util.Dom.setStyle(elm, 'width', elm._width);
        } else {
            this.done = true;
            this.attributes = { width: { to: 0 }, height: { from: elm._to, to: elm._to } }
            this.animate();
        }
    });
    bfold.animate();
    return bfold;
}
/**
* @constructor
* @class This effect makes the object shake from Right to Left.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: .25,<br>
*   offset: 10,<br>
*   maxcount: 5<br>
* }</code>
*/
YAHOO.widget.Effects.ShakeLR = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    elm._offSet = 10;
    elm._maxCount = 5;
    elm._counter = 0;
    elm._elmPos = YAHOO.util.Dom.getXY(elm);
    //YAHOO.util.Dom.setStyle(elm, 'position', 'absolute');
    var attributes = {
        left: { to:  ( - elm._offSet) }
    };

    if (opts && opts.offset) {
        elm._offSet = opts.offset;
    }
    if (opts && opts.maxcount) {
        elm._maxCount = opts.maxcount;
    }
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : .25);

    var bshake = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bshake.onComplete.subscribe(function() {
        var elm = this.getEl();
        if (!this.done) {
            if (elm._counter < elm._maxCount) {
                elm._counter++;
                if (elm._left) {
                    elm._left = null;
                    this.attributes = { left: { to: ( - elm._offSet) } }
                } else {
                    elm._left = true;
                    this.attributes = { left: { to: elm._offSet } }
                }
                this.animate();
            } else {
                this.done = true;
                elm._left = null;
                elm._counter = null;
                this.attributes = { left: { to: 0 } }
                this.animate();
            }
        }
    });
    bshake.animate();
    return bshake;
}
/**
* @constructor
* @class This effect makes the object shake from Top to Bottom.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: .25,<br>
*   offset: 10,<br>
*   maxcount: 5<br>
* }</code>
*/
YAHOO.widget.Effects.ShakeTB = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    elm._offSet = 10;
    elm._maxCount = 5;
    elm._counter = 0;
    elm._elmPos = YAHOO.util.Dom.getXY(elm);
    //YAHOO.util.Dom.setStyle(elm, 'position', 'absolute');
    var attributes = {
        top: { to:  ( - elm._offSet) }
    };

    if (opts && opts.offset) {
        elm._offSet = opts.offset;
    }
    if (opts && opts.maxcount) {
        elm._maxCount = opts.maxcount;
    }
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeOut);
    var secs = ((opts && opts.seconds) ? opts.seconds : .25);

    var bshake = new YAHOO.util.Anim(elm, attributes, secs, ease);
    bshake.onComplete.subscribe(function() {
        var elm = this.getEl();
        if (!this.done) {
            if (elm._counter < elm._maxCount) {
                elm._counter++;
                if (elm._left) {
                    elm._left = null;
                    this.attributes = { top: { to: ( - elm._offSet) } }
                } else {
                    elm._left = true;
                    this.attributes = { top: { to: elm._offSet } }
                }
                this.animate();
            } else {
                this.done = true;
                elm._left = null;
                elm._counter = null;
                this.attributes = { top: { to: 0 } }
                this.animate();
            }
        }
    });
    bshake.animate();
    return bshake;
}
/**
* @constructor
* @class This effect makes the object drop from sight.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1,<br>
* }</code>
*/
YAHOO.widget.Effects.Drop = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    var elmH = parseInt(YAHOO.util.Dom.getStyle(elm, 'height'));
    var attributes = {
        top: { from: 0, to: elmH },
        opacity: { from: 1, to: 0 }
    };
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeIn);
    var secs = ((opts && opts.seconds) ? opts.seconds : 1);

    var drop = new YAHOO.util.Anim(elm, attributes, secs, ease);
    drop.onComplete.subscribe(function() {
        var elm = this.getEl();
        YAHOO.widget.Effects.Hide(elm);
        YAHOO.util.Dom.setStyle(elm, 'top', 0);
    });
    drop.animate();
    return drop;
}
/**
* @constructor
* @class This effect makes the object flash on and off.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* @returns Animation Object
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: .25,<br>
*   maxcount: 9<br>
* }</code>
*/
YAHOO.widget.Effects.Pulse = function(inElm, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    elm._counter = 0;
    elm._maxCount = 9;
    var attributes = {
        opacity: { from: 1, to: 0 }
    };

    if (opts && opts.maxcount) {
        elm._maxCount = opts.maxcount;
    }
    
    var ease = ((opts && opts.ease) ? opts.ease : YAHOO.util.Easing.easeIn);
    var secs = ((opts && opts.seconds) ? opts.seconds : .25);

    var pulse = new YAHOO.util.Anim(elm, attributes, secs, ease);
    pulse.onComplete.subscribe(function() {
        var elm = this.getEl();
        if (!this.done) {
            if (elm._counter < elm._maxCount) {
                elm._counter++;
                if (elm._on) {
                    elm._on = null;
                    this.attributes = { opacity: { to: 0 } }
                } else {
                    elm._on = true;
                    this.attributes = { opacity: { to: 1 } }
                }
                this.animate();
            } else {
                this.done = true;
                elm._on = null;
                elm._counter = null;
                this.attributes = { opacity: { to: 1 } }
                this.animate();
            }
        }
    });
    pulse.animate();
    return pulse;
}
/**
* @constructor
* @class This effect takes an array of other effects (Maximum of 4 effects) and processes them in order.
* @param {String/HTMLElement/Array} inElm HTML element to apply the effect to
* @param {Array} effects Array of effects to apply in order to the element
* @param {Object} options Pass in an object of options for this effect, you can choose the Easing and the Duration
* <code> <br>var options = {<br>
*   ease: YAHOO.util.Easing.easeOut,<br>
*   secs: 1,<br>
*   Any other options from the other effects<br>
* }</code>
*/
YAHOO.widget.Effects.Batch = function(inElm, effects, opts) {
    var elm = YAHOO.util.Dom.get(inElm);
    var eff = eval('YAHOO.widget.Effects.' + effects[0]);
    tmp = new eff(elm, opts);
    tmp._effects = effects;
    tmp._opts = opts;
    tmp._counter = 1;
    tmp.onComplete.subscribe(function() {
        var elm = this.getEl();
        if (this._effects[this._counter]) {
            var eff = eval('YAHOO.widget.Effects.' + this._effects[this._counter]);
            this._counter++;
            tmp = new eff(elm);
            tmp._effects = this._effects;
            tmp._opts = this._opts;
            tmp._counter = this._counter;
            tmp.onComplete.subscribe(function() {
                var elm = this.getEl();
                if (this._effects[this._counter]) {
                    var eff = eval('YAHOO.widget.Effects.' + this._effects[this._counter]);
                    this._counter++;
                    tmp = new eff(elm);
                    tmp._effects = this._effects;
                    tmp._opts = this._opts;
                    tmp._counter = this._counter;
                    tmp.onComplete.subscribe(function() {
                        var elm = this.getEl();
                        if (this._effects[this._counter]) {
                            var eff = eval('YAHOO.widget.Effects.' + this._effects[this._counter]);
                            this._counter++;
                            tmp = new eff(elm);
                        }
                    });
                }
            });
        }
    });
}
