/**
 * QSF Slide Application
 * @uses JQuery, YAHOO.widget.Paginator
**/

var App_Slide = qs.create();

App_Slide.prototype = {
    __instances: [],
    _timer: null,
    _arrowTimer: null,
    _mouseTimer: null,
    _mouseOverStatus: null,
    _animated: false,
    _buttons: [{name: 'prev', title: 'Prev'}, {name: 'play', title: 'Play', arguments: [0]},
               {name: 'pause', title: 'Pause'}, {name: 'next', title: 'Next'}],
    arrowsSize: [24, 24], // [width, height]
    _paginatorTemplatePlaceholders: ['{FirstPageLink}', '{PreviousPageLink}', '{PageLinks}', '{NextPageLink}',
                                     '{LastPageLink}'],
    paginator: null,
    container: null,
    itemContainer: null,
    buttonsContainer: null,
    index: null,
    slides: null,
    idItem: null,
    status: null,
    autostart: true,
    direction: 'right',
    interval: 5000,
    effect: 'slide',
    effectDuration: 500,
    showArrows: true,
    enableButtons: true,
    enablePaginator: true,
    pageLinkWidth: 24,
    paginatorOptions: {
        firstPageLinkLabel: '&laquo;',
        previousPageLinkLabel: '&lsaquo;',
        nextPageLinkLabel: '&rsaquo;',
        lastPageLinkLabel: '&raquo; ',
        rowsPerPage       : 1
    },

    init: function (options)
    {
        new App_Slide(options);
    },

    initialize: function (options)
    {
        this.setOptions(options);
        if (!this.slides.length) {
            return false;
        }
        App_Slide.prototype.__instances[this.idItem] = this;
        var obj = this;

        // prepare HTML
        this.container.onmouseover = function (event) {obj.itemOnMouseOver(event);}
        this.container.onmouseout = function (event) {obj.itemOnMouseOut(event);}
        if (this.showArrows) {
            this.nextButton = document.createElement('div');
            this.nextButton.className = 'slide_next_button ie_png_bg';
            this.nextButton.style.display = 'none';
            this.nextButton.style.marginTop = Math.ceil((this.height - this.arrowsSize[1])/2) + 'px';
            this.nextButton.style.marginLeft = (this.width - this.arrowsSize[0]) + 'px';
            this.nextButton.onclick = function() {obj.next();}
            this.container.appendChild(this.nextButton);

            this.prevButton = document.createElement('div');
            this.prevButton.className = 'slide_prev_button ie_png_bg';
            this.prevButton.style.display = 'none';
            this.prevButton.style.marginTop = Math.ceil((this.height - this.arrowsSize[1])/2) + 'px';
            this.prevButton.style.marginLeft = '0px';
            this.prevButton.onclick = function() {obj.prev();}
            this.container.appendChild(this.prevButton);
        }
        this.itemContainer = document.createElement('div');
        this.itemContainer.className = 'slide_items_container';
        this.itemContainer.style.width = this.width + 'px';
        this.itemContainer.style.height = this.height + 'px';

        $('.slide_preload', this.container).remove();
        this.container.appendChild(this.itemContainer);
        if (this.enableButtons || this.enablePaginator) {
            this.toolbarContainer = document.getElementById('slides-toolbar-container-' + this.idItem);
            if (!this.toolbarContainer) {
                this.toolbarContainer = document.createElement('div');
                this.toolbarContainer.id = 'slides-toolbar-container-' + this.idItem;
                if (this.container.nextSibling) {
                    this.container.parentNode.insertBefore(this.toolbarContainer, this.container.nextSibling);
                } else {
                    this.container.parentNode.appendChild(this.toolbarContainer);
                }
            }
            this.toolbarContainer.className = 'slide_toolbar_container';
            this.paginatorContainer = document.createElement('div');
            this.paginatorContainer.className = 'slide_paginator';
            this.paginatorContainer.id = 'slide-toolbar-' + this.idItem;
            this.toolbarContainer.appendChild(this.paginatorContainer);

        }
        if (this.enableButtons) {
            this.buttonsContainer = document.createElement('div');
            this.buttonsContainer.className = 'slide_player';
            for (var i = this._buttons.length -1; i >=0 ; i--) {
                var button = this._buttons[i];
                var a = document.createElement('a');
                a.className = button.name;
                a.title = button.title;
                a.href = '#';
                var functionCode = 'var obj = App_Slide.prototype.getInstance(\'' + this.idItem + '\'); '
                                 + 'obj.' + button.name;
                if (typeof button.arguments != 'undefined' && button.arguments.length) {
                    functionCode += '.apply(obj, ' + json_encode(button.arguments) + ');';
                } else {
                    functionCode += '();';
                }
                functionCode += ' return false;';
                a.setAttribute('onclick', functionCode);
                this.buttonsContainer.appendChild(a);
            }
            this.toolbarContainer.appendChild(this.buttonsContainer);
        }
        if (this.toolbarContainer) {
            var clear = document.createElement('div');
            clear.className = 'clear';
            this.toolbarContainer.appendChild(clear);
        }
        // end of prepare HTML

        this.showToolbar();

        for (var i = 0; i < this.slides.length; i++) {
            this.slides[i].showTime = false;
            this.slides[i]._animated = true;
            this.setVisible(false, i);
        }
        this.slides[0].showTime = new Date().getTime();
        if (this.autostart) {
            this.play(0);
        } else {
            this.preload(0);
        }
        if ($('a#read-more-slide-link-' + this.idItem).size()) {
            $('#slides-container-' + this.idItem).css('cursor', 'pointer');            
        }
    },

    setOptions: function (options)
    {
        if (typeof options == 'object') {
            for (var field in options) {
                var value = options[field];
                if (typeof value == 'string' && !value.length) {
                    continue;
                }
                switch (field) {
                    case 'interval':
                        this.setInterval(value);
                        break;
                    case 'idContainer':
                        this.setContainer(value);
                        break;
                    case 'slides':
                        if (typeof value == 'object') {
                            this.setSlides(value)
                        }
                        break;
                    case 'paginatorOptions':
                        this.setPaginatorOptions(value);
                        break;
                    case 'idItem':
                        this.setIdItem(value);
                        break;
                    case 'effectDuration':
                        value = intval(value);
                        // break intentionally omitted
                    default:
                        this[field] = value;
                }
            }
        }
    },

    setPaginatorOption: function (name, value)
    {
        if (typeof value == 'string' && !value.length) {
            return false;
        }
        if (name == 'linkWidth' && intval(value)) {
            this.pageLinkWidth = intval(value);
            return false;
        }
        this.paginatorOptions[name] = value;
    },

    setPaginatorOptions: function (options)
    {
        for (var i in options) {
            this.setPaginatorOption(i, options[i]);
        }
    },

    isVisible: function (index)
    {
        if (typeof index == 'undefined') {
            index = this.index;
        }
        if (typeof this.slides[index] != 'undefined') {
            return this.slides[index].visible;
        }
        return false;
    },

    setVisible: function (visible, index)
    {
        if (typeof index == 'undefined') {
            index = this.index;
        }
        if (typeof this.slides[index] != 'undefined') {
            this.slides[index].visible = visible;
        }
        return false;
    },

    isPreloaded: function (index)
    {
        if (typeof index == 'undefined') {
            index = this.index;
        }
        if (typeof this.slides[index] != 'undefined' && typeof this.slides[index].containerObj != 'undefined') {
            return true;
        }
        return false;
    },

    getInstance: function(id)
    {
        if (typeof App_Slide.prototype.__instances[id] != 'undefined') {
            return App_Slide.prototype.__instances[id];
        }
        return false;
    },

    setInterval: function (interval)
    {
        interval = parseFloat(interval);
        if (!isNaN(interval) && interval != 0) {
            this.interval = interval * 1000;
            return true;
        }
        alert('App_Slide: time interval is wrong!');
        return false;
    },

    setIdItem: function (id)
    {
        id = parseInt(id);
        if (!isNaN(id) && id != 0) {
            this.idItem = id;
            this.setContainer('slides-container-' + id);
            return true;
        }
        alert('App_Slide: idItem is wrong!');
        return false;
    },

    setContainer: function(id)
    {
        this.container = document.getElementById(id);
        if (this.container) {
            return true;
        }
        this.container = null;
        alert('App_Slide: slides container is wrong!');
        return false;
    },

    prev: function ()
    {
        if (!this._animated) {
            return false;
        }
        this.stop();
        var direction = this.direction;
        this.direction = 'left';
        this.initNextShowTime(0);
        this.preload();
        this.direction = direction;
    },

    play: function (interval)
    {
        this._mouseOverStatus = null;
        this.log('play');
        this.status = 'play';
        this._mouseOverStatus = 'play';
        if (typeof interval != 'undefined') {
            this.initNextShowTime(interval);

        } else {
            this.initNextShowTime(interval);
        }
        this.preload();
        this.startTimer();
        this.hideButton('play');
        this.showButton('pause');
    },

    next: function ()
    {
        if (!this._animated) {
            return false;
        }
        this.stop();
        var direction = this.direction;
        this.direction = 'right';
        this.initNextShowTime(0);
        this.preload();
        this.direction = direction;
    },

    pause: function ()
    {
        this.stop();
        this.showButton('play');
        this.hideButton('pause');
    },

    hideButton: function (name)
    {
        $('a.' + name, this.buttonsContainer).hide();
    },

    showButton: function (name)
    {
        $('a.' + name, this.buttonsContainer).show();
    },

    setSlides: function(slides)
    {
        if (typeof slides == 'object') {
            this.slides = slides
            return true;
        }
        alert('App_Slide: slides are not object!');
        return false;
    },

    startTimer: function ()
    {
        if (this._timer != null) {
            clearTimeout(this._timer);
            this._timer = null;
        }
        this._timer = setTimeout('App_Slide.prototype.getInstance(\'' + this.idItem + '\').preload()', this.interval);
        return true;
    },

    stopTimer: function ()
    {
        if (this._timer != null) {
            clearTimeout(this._timer);
        }
        this._timer = null;
        if (null != this._mouseTimer) {
            clearTimeout(this._mouseTimer);
            this._mouseTimer = null;
        }
    },

    stop: function ()
    {
        this.status = 'stop';
        this._mouseOverStatus = 'stop';
        this.stopTimer();
        return true;
    },

    showBigArrows: function ()
    {
        if (this.showArrows) {
                $(this.prevButton).show();
                $(this.nextButton).show();
        }
        this.showToolbar();
    },

    hideBigArrows: function ()
    {
        if (this.showArrows) {
                $(this.prevButton).hide();
                $(this.nextButton).hide();
        }
        this.hideToolbar();
    },

    itemOnMouseOver: function (event)
    {
        if (null != this._arrowTimer) {
            clearTimeout(this._arrowTimer);
            this._arrowTimer = null;
        }
        this.showBigArrows();
        if (null == this._mouseOverStatus) {
            this._mouseOverStatus = this.status;
        }
        if (null != this._mouseTimer) {
            clearTimeout(this._mouseTimer);
            this._mouseTimer = null;
        }
        this.stopTimer();
        this.showButton('play');
        this.hideButton('pause');
    },

    itemOnMouseOut: function (event)
    {
        this._arrowTimer = setTimeout('App_Slide.prototype.getInstance(\'' + this.idItem + '\').hideBigArrows();', 50);

        if (this._mouseOverStatus == 'play') {
            this._mouseTimer = setTimeout('App_Slide.prototype.getInstance(\'' + this.idItem + '\').play();', 50);
        }
        if ('play' == this._mouseOverStatus) {
            this.hideButton('play');
            this.showButton('pause');
        }
    },

    show: function (index)
    {
        if (typeof index == 'undefined') {
            index = this.index;
        }
        if (this.slides[index] == null || this.slides[index] == 'undefined') {
            index = 0;
        }
        var slide = this.slides[index];
        var direction = -1;
        if ((index - this.index) >= 0) {
            direction = 1;
            if (index == this.slides.length - 1 && this.index == 0) {
                direction = -1;
            }
        } else {
            if (index == 0 && this.index == this.slides.length - 1) {
                direction = 1;
            }
        }
        this.log('direction=' + direction);
        if (this.index != null) {
            if ('slide' == this.effect) {
                slide.containerObj.style.left = direction * this.width + 'px';
            } else {
                this.slides[index].containerObj.style.display = 'none';
            }
        }
        slide.containerObj.style.marginLeft = 0;
        //$('.slide_preload', this.container).remove();
        $(this.itemContainer).append(slide.containerObj);
        this._animated = false;
        slide._animated = false;
        var obj = this;
        if (this.index != null) {
            if ('slide' == this.effect) {
                this.log('animation ' + (-1 * direction * this.width) + ' ' + this.effectDuration + ' ms');
                $('.slide_item:first').animate(
                                        {marginLeft:-1 * direction * this.width},
                                        {duration: this.effectDuration}
                                );
                $('.slide_item:last').animate(
                    {marginLeft:-1 * direction * this.width},
                    {
                        duration: this.effectDuration,
                        complete: function () {obj.animationComplete(index, direction);}
                    }
                );
            } else {
                $(this.slides[this.index].containerObj).fadeOut(this.effectDuration);
                $(slide.containerObj).fadeIn(
                    this.effectDuration,
                    function () {obj.animationComplete(index, direction);}
                );
            }
        } else {
            this.log('no animation');
            obj.animationComplete(index, direction);
        }
    },

    animationComplete: function (index, direction)
    {
        var slide = this.slides[index];
        if ($('.slide_item', this.container).size() > 1) {
            if (direction) {
                $('.slide_item:last', this.container).css({left: 0, marginLeft: 0});
                $('.slide_item:first', this.container).remove();
            } else {
                $('.slide_item:first', this.container).css({left: 0, marginLeft: 0});
                $('.slide_item:last', this.container).remove();
            }
        }
        this._animated = true;
        slide.showTime = false;
        this.setVisible(false, this.index); // mark previous bannas as invisible
        this.log('show ' + this.index + '->' + index);
        this.index = index;                 // set current index
        this.paginatorSetPage(index + 1);
        this.setVisible(true);              // mark current bannas as visible
        if (this.status == 'play') {
            this.initNextShowTime();
            this.preload();
            this.startTimer();
        } else {
            this.log('status = ' + this.status);
        }
    },

    hideToolbar: function ()
    {
        if (!this.enablePaginator && !this.enableButtons) {
            return false;
        }
        return false;
     },

    showToolbar: function ()
    {
        if (!this.enablePaginator && !this.enableButtons) {
            return false;
        }
        if (typeof this.toolbarContainer.positionFixed == 'undefined') {
            var pos = qs.getPosition(this.container);
            var style = {
                visibility: 'visible',
                top       : pos.y + (this.height - this.toolbarContainer.offsetHeight + 1) + 'px'
            };
            // $(this.toolbarContainer).css(style);
            if (this.enablePaginator) {
                var paginatorWidth = this.width;
                if (this.enableButtons) {
                    paginatorWidth -= this.buttonsContainer.offsetWidth;
                }
                // $(this.paginatorContainer).css({width: paginatorWidth + 'px'});
                this.paginatorOptions.containers = 'slide-toolbar-' + this.idItem;
                this.paginatorOptions.totalRecords = this.slides.length;
                this.paginatorOptions.totalRecords = this.slides.length;
                var additionalPages = 0;
                if (typeof this.paginatorOptions.pageLinks == 'undefined') {
                    if (typeof this.paginatorOptions.template == 'string' && this.paginatorOptions.template.length) {
                        for (var i = 0; i < this._paginatorTemplatePlaceholders.length; i++) {
                            var placeholder = this._paginatorTemplatePlaceholders[i];
                            if (placeholder == '{pageLinks}') {
                                continue;
                            }
                            if (-1 != this.paginatorOptions.template.indexOf(placeholder)) {
                                additionalPages++;
                            }
                        }
                    } else {
                        additionalPages = 4;
                    }
                    this.paginatorOptions.pageLinks = Math.floor(paginatorWidth / this.pageLinkWidth) - additionalPages;
                }
                this.paginator = new YAHOO.widget.Paginator(this.paginatorOptions);
                this.paginator.render();
                var obj = this;
                this.paginator.subscribe('changeRequest', function(state) {obj.paginatorChangeRequest(state)});
            }
            this.toolbarContainer.positionFixed = true;
        }
        $(this.toolbarContainer).show();
    },

    paginatorSetPage: function (page)
    {
        if (this.paginator) {
            this.paginator.setPage(page, true);
        }
        if ($('a#read-more-slide-link-' + this.idItem).size()) {
            $('#slides-container-' + this.idItem).css('cursor', 'pointer');
            var idItem = this.idItem;
            $('a#read-more-slide-link-' + this.idItem).click(function(){                
                App_Slide.prototype.readMoreClick(idItem);
                return false;
            });
        } else {
            $('#slides-container-' + this.idItem).css('cursor', 'default');
        }
    },

    paginatorChangeRequest: function (state)
    {
        if (!this._animated) {
            return false;
        }
        var index = state.page - 1;
        this.initShowTime(index, 0);
        this.preload(index);
        this.paginator.setState(state);
    },

    initShowTime: function (index, interval)
    {
        if (typeof interval == 'undefined') {
            interval = this.interval;
        }
        this.slides[index].showTime = new Date().getTime() + interval;
    },

    initNextShowTime: function (interval)
    {
        this.initShowTime(this.getNextIndex(), interval);
    },

    getNextIndex: function ()
    {
        var index;
        if (null == this.index) {
            return 0;
        } else if ('right' == this.direction) {
            index = (this.slides.length == this.index + 1) ? 0 : this.index + 1;
        } else if ('left' == this.direction) {
            index = (0 == this.index) ? this.slides.length - 1 : this.index - 1;
        }
        return index;
    },

    onabort: function (image)
    {
        return false;
    },

    onerror: function (image)
    {
        this.next();
    },

    preload: function (index, onloadCallback)
    {
        if (typeof index == 'undefined') {
            index = this.getNextIndex();
        }
        var obj = this;
        var slide = this.slides[index];
        if (typeof slide.containerObj == 'undefined')
        {
            this.log('preload ' + index);
            slide.containerObj = document.createElement('div');
            slide.containerObj.className = 'slide_item';
            slide.containerObj.style.width = this.width + 'px';
            slide.containerObj.style.height = this.height + 'px';
            if ('image' == slide.type) {
                var imageObj = new Image();
                imageObj.setAttribute('useMap', '#slide_map_' + slide.id);
                imageObj.setAttribute('alt', slide.title);
                imageObj.onabort = function () {obj.onabort(this)};
                imageObj.onerror = function () {obj.onerror(this)};
                imageObj.onload = function () {
                    this.style.marginLeft = Math.ceil((obj.width - this.width)/2) + 'px';
                    this.style.marginTop = Math.ceil((obj.height - this.height)/2) + 'px';
                    obj.preloaded(index);
                }
                imageObj.src = slide.image;
                slide.containerObj.appendChild(imageObj);
                if (slide.hotSpotMap != 'empty') {
                    var map = document.createElement('MAP');
                    map.name = 'slide_map_' + slide.id;
                    map.id = 'slide_map_' + slide.id;   // Fix IE6/IE7 area
                    for (var key in slide.hotSpotMap) {
                        var area = document.createElement( "AREA" );
                        area.shape = slide.hotSpotMap[key].shape;
                        area.coords = slide.hotSpotMap[key].coords;
                        area.href = slide.hotSpotMap[key].href;
                        area.target = slide.hotSpotMap[key].target;
                        area.alt = slide.hotSpotMap[key].alt;
                        map.appendChild(area);
                    }
                    slide.containerObj.appendChild(map);
                                }
            } else if ('html' == slide.type) {
                obj.log('preloaded ' + index);
                var htmlContainer = document.createElement('div');
                htmlContainer.style.width = (this.width - 20) + 'px';
                htmlContainer.style.padding = '10px';
                htmlContainer.className = 'slide_html';
                if (slide.backgroundImage) {
                    slide.containerObj.style.backgroundImage = "url('" + slide.backgroundImage + "')";
                    slide.containerObj.style.backgroundRepeat = 'no-repeat';
                    slide.containerObj.style.backgroundPosition = 'center center';
                }
                htmlContainer.innerHTML = slide.content;
                slide.containerObj.appendChild(htmlContainer);
                obj.preloaded(index);
            }
        } else {
            obj.preloaded(index);
        }
    },

    preloaded: function (index)
    {
        this.log('preloaded ' + index);
        var now = new Date();
        var slide = this.slides[index];
        if (false !== slide.showTime && Math.floor(now.getTime()/1000) >= Math.floor(slide.showTime/1000)) {
            this.show(index);
        } else {
            this.log(slide.showTime + '\n' + now.getTime());
        }
    },

    log: function (text)
    {
        if (!this.debug || typeof console == 'undefined') {
            return false;
        }
        var message = 'index=' + this.index + '. [' + text + '] ';
        console.info(message);
    },

    readMoreClick: function (idItem)
    {
        if ($('a#read-more-slide-link-' + idItem).size()) {
            var href = $('a#read-more-slide-link-' + idItem).attr('href');
            var target = $('a#read-more-slide-link-' + idItem).attr('target');            
            window.open(href, target);
        }
    }
}

