/**
 * Do not remove or change this notice.
 * Matrix Slider - Prototype and Scriptaculous slider plug-in
 * Copyright (c) 2008 - 2009 Templates Master www.templates-master.com
 *
 * @author Templates Master www.templates-master.com
 * @version 1.0 
 */

var Matrix = Class.create();
Matrix.prototype = {
    config: 
    {
        cols: 5,                                                // visible columns count
        rows: 2,                                                // visible rows count
        left:  'move-left',                                     // DOM element id to scroll slider left
        right: 'move-right',                                    // DOM element id to scroll slider right
        list:  'matrix-slider',                                 // DOM element id that containing slides
        row: 'matrix-slider-row',                               // row class
        items: 'li',                                            // Slides tagName
        shift: 1,                                               // Move offset
        timeout: 200                                            // item swap change time
    },
    
    status: 
    {
        currentItemIndex: 0,                                    // do not modify this
        direction: 'left',                                      // do not modify this
        animating: false                                        // do not modify this
    },
    
    initialize: function(listId, options)
    {
        Object.extend(this.config, options);
        this.config.list = listId;
        if (!this.build()) {
            return false;
        }
        this.initControls();
    },
    
    initControls: function()
    {
        $(this.config.left).href = $(this.config.right).href = 'javascript:void(0)';
        
        Event.observe(this.config.left,  'click', this.moveLeft.bind(this));
        Event.observe(this.config.right, 'click', this.moveRight.bind(this));
    },
    
    build: function()
    {
        var items = $(this.config.list).select(this.config.items);
        
        if (this.config.rows * this.config.cols < this.config.shift) {
            console.log('Cannot scroll elements more than visible.');
            return false;
        }
        
        if (this.config.rows * this.config.cols > items.length) {
            console.log('Cannot build slider. Too few elements.');
            return false;
        }
        
        if ((items.length - this.config.rows * this.config.cols) < this.config.shift) {
            /*for (var i = 0, limit = this.config.shift - (items.length - this.config.rows * this.config.cols); i <= limit; i++) {
                $(this.config.list).insert({ 'bottom': items[i].cloneNode(true) })
            }*/
            console.log('To scroll elements, slider needs ' +
                (this.config.shift - (items.length - this.config.rows * this.config.cols))
                + ' more item(s)'
            );
            return false;
        }
        
        var itemWidth  = parseInt(items[0].getStyle('width')) + parseInt(items[0].getStyle('margin-left')) + parseInt(items[0].getStyle('margin-right'));

        var list = this._getList(itemWidth * this.config.cols);
        for (var i = 0, limit = this.config.rows * this.config.cols; i < limit; i++) {
            list.insert(items[i]);
        }
        
        $(this.config.list).up().insert(list);
        $(this.config.list).hide();
        
        return true;
    },
    
    moveLeft: function()
    {
        if (this.status.animating) {
            return false;
        } else {
            this.status.currentItemIndex = 0;
            this.status.animating = true;
            this.status.direction = 'left';
            var items = $(this.config.row).select(this.config.items);
            this._replace(this, items[this.status.currentItemIndex]);
        }
    },
    
    moveRight: function()
    {
        if (this.status.animating) {
            return false;
        } else {
            this.status.currentItemIndex = (this.config.rows * this.config.cols) - 1;
            this.status.animating = true;
            this.status.direction = 'right';
            var items = $(this.config.row).select(this.config.items);
            this._replace(this, items[this.status.currentItemIndex]);
        }
    },
    
    move: function()
    {
        var items = $(this.config.row).select(this.config.items);
        
        if (((this.status.direction == 'left') && (++this.status.currentItemIndex >= items.length)) ||
            (this.status.direction == 'right' && --this.status.currentItemIndex < 0)) 
        {
            this._clearClones();
            this._fillHiddenList();
            this.status.animating = false;
            this.status.currentItemIndex = 0;
            return;
        }
        
        setTimeout(function(obj){ return function(){ obj._replace(obj, items[obj.status.currentItemIndex]); };}(this), this.config.timeout);
    },
    
    _replace: function(that, item)
    {
        var replacement = that._getReplacement(item);
        item.insert({ 'bottom': replacement });
        that.move();
    },
    
    _clearClones: function()
    {
        var items = $(this.config.row).select(this.config.items);
        for (var i = items.length - 1; i >= 0; i--) {
            items[i].childElements()[0].remove();
        }
    },
    
    _fillHiddenList: function()
    {
        var items = this._getTemporaryContainer().childElements();
        if (this.status.direction == 'left') {
            for (var i = 0; i < items.length; i++) {
                $(this.config.list).insert({ 'top': items[i] })
            }
        } else {
            for (var i = 0; i < items.length; i++) {
                $(this.config.list).insert({ 'bottom': items[i] })
            }
        }
    },
    
    _getReplacement: function(item)
    {
        var items = $(this.config.row).select(this.config.items);
        var rowLength = items.length;
        
        if (this.status.direction == 'left') {
            if (this.status.currentItemIndex + this.config.shift >= items.length) {
                this._getTemporaryContainer().insert({ 'top': item.cloneNode(true) });
            }
            if (this.status.currentItemIndex - this.config.shift < 0) {
                var items = $(this.config.list).select(this.config.items);
                var replacementIndex = Math.abs(-this.status.currentItemIndex - items.length + this.config.shift);
                items[replacementIndex].remove();
            } else {
                var replacementIndex = this.status.currentItemIndex - this.config.shift;
            }
        } else {
            if (this.status.currentItemIndex - this.config.shift < 0) {
                this._getTemporaryContainer().insert({ 'top': item.cloneNode(true) });
            }
            if (this.status.currentItemIndex + this.config.shift >= items.length) {
                var items = $(this.config.list).select(this.config.items);
                var replacementIndex = Math.abs(this.status.currentItemIndex - rowLength + this.config.shift);
                items[replacementIndex].remove();
            } else {
                var replacementIndex = this.status.currentItemIndex + this.config.shift;
            }
        }
        
        var childs = items[replacementIndex].childElements();
        replacement = childs[0].cloneNode(true);
        return replacement;
    },
    
    _getList: function(width)
    {
        return new Element('ul', {
            'id': this.config.row,
            'style': 'width: ' + width + 'px;'
        })
    },
    
    _getTemporaryContainer: function()
    {
        if (!$('matrix-temporary-container')) {
            $(this.config.list).up().insert(new Element('ul', {
                'id': 'matrix-temporary-container',
                'style': 'display: none'
            }));
        }
        return $('matrix-temporary-container');
    }
    
}