// Author: Darren West - darren.west@gmail.com
// Contributions: Nawaz Khan - nawazkhan@fastmail.fm
// version 0.13

if ( !GAME ) {
	var GAME = {};
};
if ( !GAME.UI ) {
	GAME.UI = {};
};

/**
* @class GAME.UI.Rotator
* Rotator class
* @param { string } id
* @param { object } options consisting of: sElement (list items parent), sShowClass, sHideClass, sFadeClass (class names for show, hide and fade) and sOrder (order of rotation / fade)
* @constructor
*/

GAME.UI.Rotator = Class.create({
    initialize: function(id, options) {
        this.element = $(id);
        this.options = Object.clone(options || {});
        this.items = this.element.select(this.options.sElement);

        if (this.options.sOrder == 'asc') {
            this.index = 0;
        }
        else {
            this.index = this.items.length - 1;
        }

        this.currentItem = null;

        if (this.options.sFadeClass == 'fade') {
            this.element.addClassName = this.options.sFadeClass;
            this.stack(this.items, this.options.sOrder);
        }
        else {
            for (var i = 0; i < this.items.length; i++) {
                this.items[i].className = this.options.sHideClass;
            }

            if (this.options.sOrder == 'asc') {
                this.items[0].className = this.options.sShowClass;
            }
            else {
                this.items[this.items.length - 1].className = this.options.sShowClass;
            }
        }

        this.controller = this.createController();
        this.timer = null;
        this.finished = false;
        this.observers = {
            start: this.start.bind(this),
            stop: this.stop.bind(this),
            mouseover: this.mouseover.bind(this),
            mouseout: this.mouseout.bind(this)
        };
        this.element.observe('rotator:start', this.observers.start);
        this.element.observe('rotator:stop', this.observers.stop);
        this.element.observe('mouseover', this.observers.mouseover);
        this.element.observe('mouseout', this.observers.mouseout);
        this.element.fire('rotator:start');
    },
    stack: function(aElement, sDir) {
        this.aElement = aElement;
        this.sDir = sDir;
        if (this.sDir == 'asc') {
            for (var i = this.aElement.length - 1; i >= 0; i--) {
                this.aElement[i].setStyle({
                    position: 'absolute',
                    top: '0',
                    left: '0',
                    zIndex: aElement.length - i
                });
            }
        }
        else {
            for (var i = 0; i < aElement.length; i++) {
                this.aElement[i].setStyle({
                    position: 'absolute',
                    top: '0',
                    left: '0',
                    zIndex: i
                });
            }
        }
    },
    start: function(event) {

        if (this.options.sFadeClass == 'fade') {

            if (this.options.sOrder == 'asc') {
                this.timer = setTimeout(this.fade.bind(this), 0);
            }
            else {
                this.timer = setTimeout(this.fadeBack.bind(this), 0);
            }
        }
        else {

            if (this.options.sOrder == 'asc') {
                this.timer = setTimeout(this.rotate.bind(this), 0);
            }
            else {
                this.timer = setTimeout(this.rotateBack.bind(this), 0);
            }
        }
    },
    stop: function(event) {
        clearTimeout(this.timer);
        this.timer = null;
        if (this.finished) {
            this.element.stopObserving('rotator:start', this.observers.start);
            this.element.stopObserving('rotator:stop', this.observers.stop);
            this.element.stopObserving('mouseover', this.observers.mouseover);
            this.element.stopObserving('mouseout', this.observers.mouseout);
        }
    },
    mouseover: function(event) {
        this.element.fire('rotator:stop');
    },
    mouseout: function(event) {
        this.element.fire('rotator:start');
    },
    rotate: function() {
        if (!this.finished) {
            if (this.index < this.items.length) {

                if (this.currentItem) {
                    this.currentItem.className = this.options.sHideClass;
                };

                this.currentItem = this.items[this.index];
                this.currentItem.className = this.options.sShowClass;
            }
            else {
                if (this.options.bLoop == 'false') {
                    this.finished = true;
                    this.element.fire('rotator:stop');
                }
                else {
                    this.index = -1;
                }
            };

            this.index++;
            this.timer = setTimeout(this.rotate.bind(this), this.options.sDelay * 1000);
        }
    },
    rotateBack: function() {
        if (!this.finished) {
            if (this.index > -1) {

                if (this.currentItem) {
                    this.currentItem.className = this.options.sHideClass;
                };

                this.currentItem = this.items[this.index];
                this.currentItem.className = this.options.sShowClass;

            }
            else {

                if (this.options.bLoop == 'false') {
                    this.finished = true;
                    this.element.fire('rotator:stop');
                }
                else {
                    this.index = this.items.length;
                }
            };
            this.index--;
            this.timer = setTimeout(this.rotateBack.bind(this), this.options.sDelay * 1000);
        }
    },
    fade: function() {
        if (!this.finished) {
            if (this.index < this.items.length) {

                if (this.currentItem) {
                    Effect.Fade(this.currentItem);
                };

                this.currentItem = this.items[this.index];
                this.changeListItem((this.index + 1));
                Effect.Appear(this.currentItem);
            }
            else {

                if (this.options.bLoop == 'false') {
                    this.finished = true;
                    this.element.fire('rotator:stop');
                }
                else {
                    this.index = -1;
                }

            };
            this.index++;
            this.timer = setTimeout(this.fade.bind(this), this.options.sDelay * 1000);
        }
    },
    fadeBack: function() {
        if (!this.finished) {
            if (this.index > -1) {

                if (this.currentItem) {
                    Effect.Fade(this.currentItem);
                };

                this.currentItem = this.items[this.index];
                this.changeListItem((this.index + 1));
                Effect.Appear(this.currentItem);

            }
            else {

                if (this.options.bLoop == 'false') {
                    this.finished = true;
                    this.element.fire('rotator:stop');
                }
                else {
                    this.index = this.items.length;
                }
            };
            this.index--;
            this.timer = setTimeout(this.fadeBack.bind(this), this.options.sDelay * 1000);
        }
    },
    createController: function() {

        var controller = document.createElement('ol');
        for (var i = 0; i < this.items.length; i++) {
            var item = document.createElement('li');
            $(item).update('<a href="javascript:void(0)">' + (i + 1) + '</a>');
            $(controller).insert(item);
        }

        $(controller).insert({
            top: '<li class="previous"><a href="javascript:void(0)"></a></li>',
            bottom: '<li class="next"><a href="javascript:void(0)"></a></li>'
        });

        var that = this;
        $(controller).childElements().each(function(el, index) {
            var e = el;
            var i = index;
            e.observe('click', function(event) {
                that.finished = true;
                that.element.fire('rotator:stop');
                if (that.index >= that.items.length) {
                    that.index = that.items.length;
                } else if (that.index < 1) {
                    that.index = 1;
                }
                if (this.hasClassName('previous')) {
                    if (that.index > 1) {
                        that.currentItem = that.currentItem.previous();
                        that.index = that.index - 1;
                        that.currentItem.show().siblings().each(function(el) {
                            el.hide();
                        });
                        that.changeListItem(that.index);
                    }
                    else {
                        that.currentItem = that.items[that.items.length -1];
                        that.index = that.items.length;
                        that.currentItem.show().siblings().each(function(el) {
                            el.hide();
                        });
                        that.changeListItem(that.index);
                    }                    
                } else if (this.hasClassName('next')) {
                    if (that.index <= that.items.length - 1) {
                        that.currentItem = that.currentItem.next();
                        that.index = that.index + 1;
                        that.currentItem.show().siblings().each(function(el) {
                            el.hide();
                        });
                        that.changeListItem(that.index);
                    }
                    else if (that.index == that.items.length) {
                        that.currentItem = that.items[0];
                        that.index = 1;
                        that.currentItem.show().siblings().each(function(el) {
                            el.hide();
                        });
                        that.changeListItem(that.index);
                    }
                } else {
                    if (!(e.hasClassName('on'))) {
                        e.addClassName('on');
                    }
                    e.siblings().each(function(el, index) {
                        el.removeClassName('on');
                    });
                    that.items.each(function(el, index) {
                        if (i - 1 == index) {
                            that.currentItem = el;
                            that.index = i;
                            el.show();
                        } else {
                            el.hide();
                        }
                    });
                }
            });
        });

        this.element.insert(controller);

        return $(controller);
    },
    changeListItem: function(index) {
        var i = index;
        $(this.controller).select('li').each(function(e, eIndex) {
            if (!(e.hasClassName('previous') || e.hasClassName('next'))) {
                if (i == eIndex) {
                    e.addClassName('on');
                } else {
                    e.removeClassName('on');
                }
            }
        });
    }
});