/**
 * slidesPane, il mio primo acerbo plug-in per MooTools ;)
 * Autore: Vincenzo Acinapura
 * ---
 * 
 * Cose da implementare:
 * +  Aggiungere la classe {activeClass} alla slide attiva.
 *    Adesso il ragionamento del cazzo che ho fatto mi preclude
 *    questa possibilità.
 *    
 * +  Aggiungere l'opzione di poter ricominciare daccapo lo
 *    scorrimento delle slide se ci troviamo con l'ultima slide
 *    visualizzata. (Quindi i pulsanti dovrebbero rimanere sempre
 *    con la classe {activeClass}.
 *    
 * +  Opzione per conservare in un cookie l'ultima slide visualizzata
 *    in modo da far ripartire le slide da quel punto. Sembrerebbe 
 *    esserci un problema con la funzione toInt() su ie6.
 */

var SlidesPane = new Class({

    options: {
        slidesContainerSelector: "ul.slides",     // Selettore del contenitore delle slides
        viewportSelector: "div.viewport",         // Classe per area visibile.
        activeClass: "active",                    // Classe per bottone/slide attiva
        prevButtonClass: "prev",                  // Classe per il bottone Previous
        nextButtonClass: "next",                  // Classe per il bottone Next
        slideWidth: 100,                          // Larghezza delle slide
        slidesToShow: 4,                          // Numero di slide da mostrare per volta
        startWithSlide: 0,                        // Specifica la slide con la quale partire
        randomSlideAtStart: false,                // Permette di visualizzare una slide a caso al caricamento
        startOver: false,                         // Per far ricominciare lo slide show daccapo
        effectOptions: {                          // Opzioni per l'effetto di transizione
            duration: 600,
            wait: false,
            transition: Fx.Transitions.Quad.easeOut
        },
        onNext: function(){                       // Callback da eseguire al termine del passaggio a slide successiva
            this.fireEvent("onChange");
            if (this.currentSlide == this.slides.length - this.options.slidesToShow) {
                this.nextButton.removeClass(this.options.activeClass);
            }
            
        },
        onPrev: function(){                       // Callback da eseguire al termine del passaggio a slide precedente
            this.fireEvent("onChange");
            if (this.currentSlide == 0) {
                this.prevButton.removeClass(this.options.activeClass);
            }
        },
        onChange: function(){                     // Callback da eseguire a qualsiasi passaggio di slide
            $$(this.prevButton, this.nextButton).each(function(button){
                button.addClass(this.options.activeClass);
            }.bind(this));
        }
    },
    
    box: null,                                    // Riferimento al contenitore del componente
    slidesContainer: null,                        // Riferimento al contenitore delle slides
    slides: [],                                   // Collezione delle slides
    currentSlide: null,                           // Riferimento alla slide corrente
    viewport: null,                               // Riferimento all'elemento che rappresenta l'area visibile
    prevButton: null,                             // Riferimento al pulsante Prev
    nextButton: null,                             // Riferimento al pulsante Next
    scroll: null,                                 // Istanza dell'effetto Fx.Scroll
    lastSlideSeen: function(){                    // Funzione che recupera l'ultima slide da un cookie.
        return Cookie.get('lastSlideSeen') || 0;
    },
    
    initialize: function(boxSelector, options){

        this.setOptions(options);
        
        // Il box che contiene tutto lo slider.
        this.box = $E(boxSelector);
        
        // La parte visibile.
        this.viewport = this.box.getElement(this.options.viewportSelector);
        
        // Il contenitore delle slides (solitamente un'<ul>).
        this.slidesContainer = this.box.getElement(this.options.slidesContainerSelector);
        
        // La collezione delle slides (solitamente elementi <li>).
        this.slides = this.slidesContainer.getChildren();
        
        // Con quale slide partiamo?
        if (this.options.startWithSlide > 0) {
            this.options.startWithSlide = this.options.startWithSlide.limit(0, (this.slides.length - this.options.slidesToShow));
        }
        
        this.currentSlide = this.options.startWithSlide || 0;
        
        // Se l'utente decide di partire con una slide a caso, onoriamo la sua scelta.
        if (this.options.randomSlideAtStart) {
            this.currentSlide = $random(0, (this.slides.length - 1)).limit(0, (this.slides.length - this.options.slidesToShow));
            //console.log(this.currentSlide);
        }
        
        // Inizializziamo i bottoni.
        this.prevButton = this.box.getElement("." + this.options.prevButtonClass) || null;
        this.nextButton = this.box.getElement("." + this.options.nextButtonClass) || null;
        
        // Aggiungo eventi e classi ai pulsanti (verificando prima che ci siano ;))
        if (this.prevButton) {
            this.prevButton.addClass(this.options.activeClass);
            this.prevButton.addEvent('click', this.prev.bind(this));
        }
        if (this.nextButton) {
            this.nextButton.addClass(this.options.activeClass);
            this.nextButton.addEvent('click', this.next.bind(this));
        }
        
        if (this.currentSlide == 0) {
            this.prevButton.removeClass(this.options.activeClass);
        }
        
        if (this.currentSlide == this.slides.length - this.options.slidesToShow) {
            this.nextButton.removeClass(this.options.activeClass);
        }
        
        // Aggiungo gli stili indispensabili per il corretto funzionamento del componente.
        this.box.setStyles({
            "width": (this.options.slideWidth * this.options.slidesToShow.toInt()),
            "position": (this.box.getStyle("position") || "relative")
        });
        
        this.viewport.setStyles({
            "width": (this.options.slideWidth * this.options.slidesToShow.toInt()),
            "overflow": "hidden"
        });
        
        this.slidesContainer.setStyles({
            "width": (this.options.slideWidth * this.slides.length)
        });
        
        this.slides.each(function(slide, i){
            slide.setStyles({
                "width": this.options.slideWidth,
                "float": "left",
                "display": "inline"
            })
        }.bind(this));
        
        // Inizializzo l'effetto di transizione da una slide all'altra.
        this.scroll = new Fx.Scroll(this.viewport, this.options.effectOptions);
        this.scroll.toElement(this.slides[this.currentSlide]);
    },
    
    prev: function(){
        // Passa alla slide precedente.
        if (this.currentSlide > 0) {
            this.scroll.toElement(this.slides[--this.currentSlide]);
        }
        this.fireEvent("onPrev");
    },
    
    next: function(){
        // Passa alla slide successiva.
        if (this.currentSlide < this.slides.length - this.options.slidesToShow) {
            this.scroll.toElement(this.slides[++this.currentSlide]);
        }
        this.fireEvent("onNext");
    },
    
    change: function(slideIndex){
        this.fireEvent("onChange");
    }
});

SlidesPane.implement(new Options, new Events);
