
Type.registerNamespace('Devy.UI');

Devy.UI.Carousel = function() {
    Devy.UI.Carousel.initializeBase(this);

    //Miembros
    this._Container = null;
    this._CSSClass = "";
    this._Titulo = "";
    this._Nombre = "";

    this._ItemsContainer = null;
    this._cmdAnterior = null;
    this._cmdSiguiente = null;
    this._cmdPlayPause = null;
    this._cmdPlayPauseContainer = null;

    this._SlideShowEnabled = false;
    this._SlideShowEnabledTimer = false;
    this._SlideShowTimerEnabled = false;
    this._SlideShowTimerInterval = 5000;
    this._FadeTransitions = true;
    this._PageChangeDirection = "";

    this._Criteria = {};

    this._ObjectsType = "";
    this._RecordsPerPage = 0;
    this._HtmlViewTemplateName = "";

    this._events = null;

    this._PAGES = new Array();
    this._TotalCount = 0;
    this._PagesCount = 0;
    this._CurrentPos = 0;

    this._ServiceBussy = false;
    this._ServiceLastResult = "";
    this._ServiceLastError = "";

}

Devy.UI.Carousel.prototype = {
    //*********************************************************************
    //Publicos
    set_Container: function (value) { this._Container = value; },
    get_Container: function () { return this._Container; },

    set_CSSClass: function (value) { this._CSSClass = value; },
    get_CSSClass: function () { return this._CSSClass; },

    set_Titulo: function (value) { this._Titulo = value; },
    get_Titulo: function () { return this._Titulo; },

    set_Nombre: function (value) { this._Nombre = value; },
    get_Nombre: function () { return this._Nombre; },

    set_ObjectsType: function (value) { this._ObjectsType = value; },
    get_ObjectsType: function () { return this._ObjectsType; },

    set_PagesCount: function (value) { this._PagesCount = value; },
    get_PagesCount: function () { return this._PagesCount; },

    set_TotalCount: function (value) { this._TotalCount = value; },
    get_TotalCount: function () { return this._TotalCount; },

    get_CurrentPos: function () { return this._CurrentPos; },

    get_SlideShowEnabled: function () { return this._SlideShowEnabled; },
    set_SlideShowEnabled: function (value) { this._SlideShowEnabled = value; },

    get_SlideShowInterval: function () { return this._SlideShowTimerInterval; },
    set_SlideShowInterval: function (value) { this._SlideShowTimerInterval = value; },

    get_Criteria: function () { return this._Criteria; },
    set_Criteria: function (value) { this._Criteria = value; },

    get_RecordsPerPage: function () { return this._RecordsPerPage; },
    set_RecordsPerPage: function (value) { this._RecordsPerPage = value; },

    get_FadeTransitions: function () { return this._FadeTransitions; },
    set_FadeTransitions: function (value) { this._FadeTransitions = value; },

    get_HtmlViewTemplateName: function () { return this._HtmlViewTemplateName; },
    set_HtmlViewTemplateName: function (value) { this._HtmlViewTemplateName = value; },

    get_RandomizeRecords: function () { return this._RandomizeRecords; },
    set_RandomizeRecords: function (value) { this._RandomizeRecords = value; },

    initialize: function () {
        Devy.UI.Carousel.callBaseMethod(this, 'initialize');
        this._initInterface();

        var contexto = this;
        var timeoutTime = 100;
        if (typeof (jQuery) == "undefined") timeoutTime = 4000;

        setTimeout(function () {
            contexto._atachEvents();

            contexto._CurrentPos = -1; //Para que no falle _getNextRandomPageNumber

            if (contexto._SlideShowEnabled) contexto._playPause();

            contexto._PageChangeDirection = "next";
            if (contexto._RandomizeRecords) {
                contexto._BeginPageChange(contexto._getNextRandomPageNumber());
            }
            else {
                contexto._BeginPageChange(0);
            }
        }, timeoutTime);

        Devy.UI.Carousel.__RegisterInstance(this);
    },

    dispose: function () {
        this._detachEvents();
        Devy.UI.Carousel.callBaseMethod(this, 'dispose');
    },

    _atachEvents: function () {
        if (this._cmdAnterior)
            $addHandlers(this._cmdAnterior, { click: this._cmdAnteriorClick }, this);

        if (this._cmdSiguiente)
            $addHandlers(this._cmdSiguiente, { click: this._cmdSiguienteClick }, this);

        if (this._cmdPlayPause)
            $addHandlers(this._cmdPlayPause, { click: this._cmdPlayPauseClick }, this);
    },

    _detachEvents: function () {
        if (this._cmdAnterior)
            $clearHandlers(this._cmdAnterior);

        if (this._cmdSiguiente)
            $clearHandlers(this._cmdSiguiente);

        if (this._cmdPlayPause)
            $clearHandlers(this._cmdPlayPause);
    },

    //*********************************************************************
    //Event Handlers
    _cmdAnteriorClick: function (evt) {
        evt.preventDefault();

        this._anterior();
        this._SlideShowTimerEnabled = false;
        this._setPlayPause_Play();
    },

    _cmdSiguienteClick: function (evt) {
        evt.preventDefault();

        this._siguiente();
        this._SlideShowTimerEnabled = false;
        this._setPlayPause_Play();
    },

    _cmdPlayPauseClick: function (evt) {
        evt.preventDefault();

        this._playPause();
    },

    _getNextRandomPageNumber: function () {
        aleat = this._CurrentPos;

        pasadas = 0;
        while (aleat == this._CurrentPos || pasadas > 10) {
            //Generamos un numero aleatorio
            numPosibilidades = this._PagesCount - 1;
            aleat = Math.random() * numPosibilidades;
            aleat = Math.round(aleat);

            pasadas++;
        }

        return aleat;
    },

    _SlideShowTimerTick: function () {
        if (this._SlideShowTimerEnabled) {
            this._PageChangeDirection = "next";

            if (this._RandomizeRecords) {
                this._BeginPageChange(this._getNextRandomPageNumber());
            }
            else {
                if (this._CurrentPos < (this._PagesCount - 1)) {
                    this._BeginPageChange(this._CurrentPos + 1);
                }
                else {
                    this._BeginPageChange(0); //Damos la vuelta
                }
            }
            this._launchSlideShowTimer();
        }
    },

    _launchSlideShowTimer: function (callback, interval) {
        var SlideShowTimerTick_Delegate = Function.createDelegate(this, this._SlideShowTimerTick);
        setTimeout(SlideShowTimerTick_Delegate, this._SlideShowTimerInterval);
    },

    //*********************************************************************
    //Mis eventos    
    get_events: function () {
        if (!this._events) {
            this._events = new Sys.EventHandlerList();
        }
        return this._events;
    },
    add_beginPageChange: function (handler) {
        this.get_events().addHandler('beginPageChange', handler);
    },
    remove_beginPageChange: function (handler) {
        this.get_events().removeHandler('beginPageChange', handler);
    },
    add_endPageChange: function (handler) {
        this.get_events().addHandler('endPageChange', handler);
    },
    remove_endPageChange: function (handler) {
        this.get_events().removeHandler('endPageChange', handler);
    },
    _raiseEvent: function (eventName, eventArgs) {
        var handler = this.get_events().getHandler(eventName);

        var theEventArgs = null;
        if (handler) {
            if (!eventArgs) {
                theEventArgs = Sys.EventArgs.Empty;
            }
            else {
                theEventArgs = eventArgs;
            }

            handler(this, theEventArgs);
        }

        //Llamamos a defaultHandler si existe
        if (typeof (DevyCarrouselDefaultEventHandler) != "undefined")
            DevyCarrouselDefaultEventHandler(this, eventName, eventArgs);
    },

    //Manejo de Paginas
    _siguiente: function () {
        this._PageChangeDirection = "next";

        if (this._RandomizeRecords) {
            this._BeginPageChange(this._getNextRandomPageNumber());
        }
        else {
            if (this._CurrentPos < (this._PagesCount - 1)) {
                this._BeginPageChange(this._CurrentPos + 1);
            }
        }
    },
    _anterior: function () {
        this._PageChangeDirection = "previous";

        if (this._CurrentPos > 0) {
            this._BeginPageChange(this._CurrentPos - 1);
        }
    },
    _playPause: function () {
        if (this._SlideShowTimerEnabled) {
            this._SlideShowTimerEnabled = false;
            this._setPlayPause_Play();
        }
        else {
            this._SlideShowTimerEnabled = true;
            this._setPlayPause_Pause();
            this._launchSlideShowTimer();
        }
    },

    _setPlayPause_Play: function () {
        if (this._cmdPlayPause.innerHTML) {
            this._cmdPlayPause.innerHTML = "<span>Play</span>";
            Sys.UI.DomElement.removeCssClass(this._cmdPlayPauseContainer, "Play");
            Sys.UI.DomElement.removeCssClass(this._cmdPlayPauseContainer, "Pause");
            Sys.UI.DomElement.addCssClass(this._cmdPlayPauseContainer, "Play");
        }
    },

    _setPlayPause_Pause: function () {
        if (this._cmdPlayPause.innerHTML) {
            this._cmdPlayPause.innerHTML = "<span>Pausa</span>";
            Sys.UI.DomElement.removeCssClass(this._cmdPlayPauseContainer, "Play");
            Sys.UI.DomElement.removeCssClass(this._cmdPlayPauseContainer, "Pause");
            Sys.UI.DomElement.addCssClass(this._cmdPlayPauseContainer, "Pause");
        }
    },

    _BeginPageChange: function (NewPage) {
        if (NewPage != this._CurrentPos) {
            var eventDataArgs = new Array();
            eventDataArgs.waitForCompleteCallBack = false;
            eventDataArgs.pageChangeDirection = this._PageChangeDirection;

            eventDataArgs.CompleteCallBack = Function.createDelegate(this,
            function () {
                this.___BeginPageChange(NewPage);
            });

            this._raiseEvent('beginPageChange', eventDataArgs);

            if (!eventDataArgs.waitForCompleteCallBack) { //Si no, esperamos que se llame de afuera
                if (this._FadeTransitions) {
                    //this._doFadeAnimationStep(0, this._ItemsContainer, true, eventDataArgs.CompleteCallBack);
                    this._doFadeTransition(true, eventDataArgs.CompleteCallBack);
                }
                else
                    this.___BeginPageChange(NewPage);
            }
            else //Desactivamos FadeTransitions
                this._FadeTransitions = false;
        }
    },

    ___BeginPageChange: function (NewPage) {
        if (this._PAGES[NewPage]) {
            this._EndPageChange(NewPage);
        }
        else {
            this._setLoading();

            //Invocamos el servicio
            var ServiceData = new Array();
            ServiceData.Requester = this;
            ServiceData.RequestedPage = NewPage;

            this._Criteria.RecordsPerPage = this._RecordsPerPage;

            switch (this._ObjectsType) {
                case "eventos":
                    Devy.UI.Carousels.EventosService.GetEventos(this._Criteria, NewPage + 1, this._HtmlViewTemplateName,
                    this._onListaArticulosServerSuccess, this._onListaArticulosServerError, ServiceData);
                    break;

                case "productos":
                    Devy.UI.Carousels.ProductosService.GetProductos(this._Criteria, NewPage + 1, this._HtmlViewTemplateName,
                    this._onListaArticulosServerSuccess, this._onListaArticulosServerError, ServiceData);
                    break;

                default: /* articulos */
                    Devy.UI.Carousels.ArticulosService.GetArticulos(this._Criteria, NewPage + 1, this._HtmlViewTemplateName,
                    this._onListaArticulosServerSuccess, this._onListaArticulosServerError, ServiceData);
                    break;
            }
        }
    },

    _EndPageChange: function (NewPage) {
        this._CurrentPos = NewPage;

        this._updateCommands();
        this._printCurrentPage();

        var eventDataArgs = new Array();
        eventDataArgs.pageChangeDirection = this._PageChangeDirection;

        this._raiseEvent('endPageChange', eventDataArgs);

        if (this._FadeTransitions) {
            this._doFadeTransition(false);
        }
    },

    _setLoading: function () {
        this._ItemsContainer.innerHTML = '<div class="AjaxLoading"></div>';
    },

    _setImageLoading: function () {
        var imagenesJQ = $('img', this._Container);
        imagenesJQ.hide();

        imagenesJQ.after('<p class="loadingImageItem"></p>');

        imagenesJQ.load(function () {
            $(this).next('.loadingImageItem').remove();
            $(this).fadeIn("fast");
        });
    },


    _printCurrentPage: function () {
        var carouselPageItems = this._PAGES[this._CurrentPos];
        var sb = new Sys.StringBuilder();
        for (var i = 0; i < carouselPageItems.length; i++) {
            sb.appendLine('<div class="CarouselItem">');
            sb.appendLine(carouselPageItems[i].HtmlView);
            sb.appendLine('</div>');
        }
        this._ItemsContainer.innerHTML = sb.toString();

        this._setImageLoading();

        this._fixAddToCarritoControlsIfNeeded();
    },


    _fixAddToCarritoControlsIfNeeded: function () {
        if (Devy.UI.Carrito && Devy.UI.Carrito.AddToCarrito && this._ObjectsType == "productos") {
            Devy.UI.Carrito.AddToCarrito.CreateAllObjectsInContainer(this._ItemsContainer);
        }
    },

    _updateCommands: function () {
        if (this._PagesCount == 1) {
            //No es necesario. hay solo una pagina
            if (this._cmdPlayPause) $(this._cmdPlayPause).hide();
            if (this._cmdAnterior) $(this._cmdAnterior).hide();
            if (this._cmdSiguiente) $(this._cmdSiguiente).hide();
        }
        else {
            if (this._cmdAnterior) {
                if (this._CurrentPos > 0) {
                    $(this._cmdAnterior).show();
                }
                else {
                    $(this._cmdAnterior).hide();
                }
            }

            if (this._cmdSiguiente) {
                if (this._RandomizeRecords) {
                    $(this._cmdSiguiente).show();
                }
                else {
                    if (this._CurrentPos < (this._PagesCount - 1)) {
                        $(this._cmdSiguiente).show();
                    }
                    else {
                        $(this._cmdSiguiente).hide();
                    }
                }
            }
        }
    },

    _doFadeTransition: function (fadeout, callback) {
        var duracion = 1000;

        if (jQuery.browser.msie) {
            this._ItemsContainer.style.removeAttribute("filter");
            this._ItemsContainer.style.zoom = 1;
        }

        if (fadeout) {
            $(this._ItemsContainer).fadeOut(duracion, callback);
        }
        else {
            $(this._ItemsContainer).fadeIn(duracion, callback);
        }
    },

    //Servicio Web
    _onListaArticulosServerSuccess: function (result, context, methodName) {
        context.Requester._PAGES[context.RequestedPage] = result.Items;
        context.Requester._PagesCount = result.PagesCount;
        context.Requester._TotalCount = result.TotalCount;
        context.Requester._EndPageChange(context.RequestedPage)
    },
    _onListaArticulosServerError: function (error, context, methodName) {
        //No hay nada por hacer
        Sys.Debug.trace("Carousel Error: " + error.get_message());
    },

    _initInterface: function () {
        var css = "Carousel";
        if (this._CSSClass) css += " " + this._CSSClass;

        var tmpContainer = $('<div class="' + css + '">');

        if (this._Titulo) {
            tmpContainer.append('<h3 class="CarouselTitulo">' + this._Titulo + '</h3>');
        }

        /*Commands*/
        var commandsContainer = $('<div class="CommandsContainer">');

        var tmp = $('<div class="cmdContainer Anterior">');
        this._cmdAnterior = $('<a class="Cmd cmdAnterior" href="#"><span>Anterior</span></a>')[0];
        tmp.append(this._cmdAnterior);
        commandsContainer.append(tmp);

        this._cmdPlayPauseContainer = $('<div class="cmdContainer PlayPause Play">')[0];
        this._cmdPlayPause = $('<a class="Cmd cmdPlayPause cmdPlay" href="#"><span>Play</span></a>')[0];
        $(this._cmdPlayPauseContainer).append(this._cmdPlayPause);
        commandsContainer.append(this._cmdPlayPauseContainer);

        tmp = $('<div class="cmdContainer Siguiente">');
        this._cmdSiguiente = $('<a class="Cmd cmdSiguiente" href="#"><span>Siguiente</span></a>')[0];
        tmp.append(this._cmdSiguiente);
        commandsContainer.append(tmp);

        tmpContainer.append(commandsContainer);

        /*Items Container*/
        var itemsContainerContainer = $('<div class="ItemsContainer">');
        tmpContainer.append(itemsContainerContainer);

        this._ItemsContainer = $('<div class="Items">')[0];
        itemsContainerContainer.append(this._ItemsContainer);

        $(this._Container).append(tmpContainer);
    }
}

Devy.UI.Carousel.registerClass('Devy.UI.Carousel', Sys.Component);


Devy.UI.Carousel.__Instances = new Array();
Devy.UI.Carousel.__RegisterInstance = function (instance) {
    Array.add(Devy.UI.Carousel.__Instances, instance);
}
Devy.UI.Carousel.GetInstanceByNombre = function (nombre) {
    try {
        for (var i = 0; i <= Devy.UI.Carousel.__Instances.length; i++) {
            var instance = Devy.UI.Carousel.__Instances[i];

            if (instance && instance.get_Nombre() == nombre)
                return instance;
        }
    } catch (e) {
        return null;
    }
}
