/**
 * Component: mylo.slider
 * Slider/Carousel like slider component
 *
 * @version        0.2b
 *
 * @author        Lyubomir Petrov <lpetrov@mylo.bg>
 * @website       http://creative.mylo.bg/blog/
 * @copyright    Mylo Creative, Mylo Ltd
 * @license
 * Copyright (c) 2008, Mylo Ltd
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, 
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *  - Redistributions of source code must retain the above 
 *    copyright notice, this list of conditions and the
 *    following disclaimer.
 *    
 *  - Redistributions in binary form must reproduce the 
 *    above copyright notice, this list of conditions and 
 *    the following disclaimer in the documentation and/or
 *    other materials provided with the distribution.
 *     
 *  - Neither the name of the Mylo Ltd nor the names of its 
 *    contributors may be used to endorse or promote products
 *    derived from this software without specific prior 
 *     written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 

 if(!$defined(mylo))
    var mylo={};


mylo.slider = new Class({
    Implements:[Events, Options],
    options:{
        layout:0, /* default using the LAYOUT_HORIZONTAL for the slider */
        prevButton:null,
        nextButton:null,                         
        elementWidth:null, //in px pleasee, automaticly calculated from the first element in the list
        elementHeight:null, //in px pleasee, automaticly calculated from the first element in the list
        inactiveOpacity:0.4,
        scrollSpeed:1400,
        scrollTransition:Fx.Transitions.Quint //getting funky
    },
    /* Events */
    beforeSlide:Class.empty,
    afterSlide:Class.empty,
    init:Class.empty,
    /* End of Events */
    
    /* Other properties */
    element:null,
    elements:[],
    activeElement:0,
    scroller:null,
    initialize:function(el, options) {
        this.setOptions(options);
        this.element = $(el);
        this.elements = this.element.getElements("li");
        if(this.options.elementWidth == null) {
            //scrollSize in IE is by default 19, is this a bug in IE or moo?
            this.options.elementWidth = $(this.elements[0]).getSize().x + $(this.elements[0]).getScroll().x;
        }
        if(this.options.elementHeight == null) {
            //and again
            this.options.elementHeight = $(this.elements[0]).getSize().y + $(this.elements[0]).getScroll().y;
        }
                                   
        //dynamicly set size of the inner wrapper and do the overflow
        this.element.getElements("ul")[0].setStyle("width",(this.options.elementWidth*this.elements.length)+"px");
        this.element.getElements("ul")[0].setStyle("height",(this.options.elementHeight*this.elements.length)+"px");
        
        //overflow
        this.element.setStyle("overflow","hidden");
        
        //bind buttons
        this.options.nextButton.addEvent("click",this.slide.bind(this,+1));
        this.options.nextButton.store('fx', new Fx.Tween(this.options.nextButton,{
                property:'opacity',
                link:'cancel',
                duration:this.options.scrollSpeed*0.7,
                transition:this.options.scrollTransition.easeIn
        }));
        this.options.prevButton.addEvent("click",this.slide.bind(this,-1));
        this.options.prevButton.store('fx',new Fx.Tween(this.options.prevButton,{
                property:'opacity',
                link:'cancel',
                duration:this.options.scrollSpeed*0.7,
                transition:this.options.scrollTransition.easeIn
        }));
        
        //fade out on init & some other layout settings
        for(var i=0;i<this.elements.length;i++) {
            //prepare fx object
            $(this.elements[i]).store('fx',new Fx.Tween($(this.elements[i]),{
                property:'opacity',
                link:'cancel',
                duration:this.options.scrollSpeed*0.7,
                transition:this.options.scrollTransition.easeIn
            }));
            $(this.elements[i]).retrieve('fx').set(this.options.inactiveOpacity); //reset the fx
            
            //set the float
            if(this.options.layout == mylo.slider.constants.LAYOUT_HORIZONTAL)
                $(this.elements[i]).setStyle("float","left");
                
            $(this.elements[i]).setStyle("width",this.options.elementWidth);
            $(this.elements[i]).setStyle("height",this.options.elementHeight);
            
        }
        //scroller prepare
        this.scroller = new Fx.Scroll(this.element, {
            duration:this.options.scrollSpeed,
            link:'cancel',
            transition: this.options.scrollTransition.easeOut
            }
        );
        
        //initial settings
        this.options.prevButton.setStyle('visibility','hidden');
        this.options.prevButton.setStyle('opacity',0);
        this.slide(0);
        this.fireEvent.delay(1,this,["init"]); //hack for fireing the event
    },
    slide:function(count) {    
        this.fireEvent("beforeSlide",count);    
        if((this.activeElement+count) <= this.elements.length-1 && (this.activeElement+count) >= 0) {
            this.slideTo(this.activeElement + count);
        }
    },   
    slideTo:function(elementId) {
        if(elementId < this.elements.length) {
            
            //fadein/out
            var inactiveElement;
            if(elementId < this.activeElement) 
                inactiveElement = this.elements[elementId + 1];
            else
                inactiveElement = this.elements[elementId - 1];
            
            this.activeElement = elementId;
            
            if(inactiveElement) {
                 inactiveElement.retrieve('fx').start(1.0,this.options.inactiveOpacity);
            }
                                                                  
            var currentElement = this.elements[this.activeElement];
            if(currentElement)
                currentElement.retrieve('fx').start(this.options.inactiveOpacity,1.0);

                 
            
            //do scrolling, depending on the layout option
            if(this.options.layout == mylo.slider.constants.LAYOUT_HORIZONTAL)
                var newPosition = this.activeElement * this.options.elementWidth;
            else
                var newPosition = this.activeElement * this.options.elementHeight;
            
            this.scroller.start(
                this.options.layout == mylo.slider.constants.LAYOUT_HORIZONTAL ? newPosition : 0,
                this.options.layout == mylo.slider.constants.LAYOUT_VERTICAL ? newPosition : 0
            );
        }
        //set button states
        this.buttonStates();
        
        //event
        this.fireEvent("afterSlide");
    },                           
    buttonStates:function() {
        if(this.activeElement == 0) {
            if(this.options.prevButton.getStyle('opacity') == 1)
                this.options.prevButton.retrieve('fx').start(1.0,0.0);
        } else {
            if(this.options.prevButton.getStyle('opacity') == 0)
                this.options.prevButton.retrieve('fx').start(0.0,1.0);
        }
        
        if(this.activeElement == this.elements.length-1) {
            if(this.options.nextButton.getStyle('opacity') == 1)
                this.options.nextButton.retrieve('fx').start(1.0,0.0);
        } else {
            if(this.options.nextButton.getStyle('opacity') == 0)
                this.options.nextButton.retrieve('fx').start(0.0,1.0);
        }
    }
});

/* Constants */
mylo.slider.constants = {
    LAYOUT_HORIZONTAL:0,
    LAYOUT_VERTICAL:1
};
