// itelligent.com.mx, Febrero 2011

var continuos = {
    __body: {
        panels: null,
        body: null,
        handlers: {
            keypress: function (e) {
                //console.log((document.all ? window.event.keyCode : e.which))
                switch((document.all ? window.event.keyCode : e.which)) {
                    // up key, prev cols
                    case 38:
                        if(continuos.row <= 0 || continuos.__in_process)
                            return false;

                        continuos.__in_process = true;

                        continuos.vSlice(continuos.__body.panels, continuos.getRow(continuos.row - 1), -1, continuos.row - 1)

                        return false;

                    // down key, next cols
                    case 40:
                        if(continuos.row >= continuos.conf.matrix.length - 1 || continuos.__in_process)
                            return false;

                        continuos.__in_process = true;

                        continuos.vSlice(continuos.__body.panels, continuos.getRow(continuos.row + 1), 1, continuos.row + 1);

                        return false;

                    // right key, next item
                    case 39:
                        if(continuos.cursor == continuos.__body.panels.find('> div').length - 3)
                            continuos.render(continuos.cursor + 3, 5, continuos.row)

                        if(continuos.cursor >= continuos.__body.panels.find('> div').length - 1 || continuos.__in_process)
                            return false;

                        continuos.__in_process = true;

                        continuos.hSlice(
                            continuos.__body.panels.find('> div:eq(' + continuos.cursor + ')'),
                            continuos.__body.panels.find('> div:eq(' + (++continuos.cursor) + ')'),
                            'right'
                        );

                        return false;
                    
                    // left key, prev item
                    case 37:
                        if(continuos.cursor <= 0 || continuos.__in_process)
                            return false;

                        continuos.__in_process = true;

                        continuos.hSlice(
                            continuos.__body.panels.find('> div:eq(' + continuos.cursor + ')'),
                            continuos.__body.panels.find('> div:eq(' + (--continuos.cursor) + ')'),
                            'left'
                        )

                        return false;
                    case 27:                // esc key
                        continuos.hide();
                        break;
                }

                return true;
            }
        }
    },
    __in_process: false,

    conf: {
        matrix: [[1, 2, 3], ['a', 'b', 'c'], ['uno', 'dos', 'tres']],
        draw: function (target) {
            return $('<div>' + target + '</div>')
                        .css({
                            'font-size': '60px',
                            'color': '#fff',
                            'text-align': 'center',
                            'line-height': Math.floor($(window).height() * .9) + 'px'
                        })
        }
    },

    cursor: null,
    row: null,

    hide: function () {
        bpage.hide();
        this.__body.body.remove();
        $(document).unbind('keydown', this.__body.handlers.keydown)
    },
    show: function (options) {
        $.extend(this.conf, options)

        if(typeof(options.row) == 'undefined')
            options.row = 0

        bpage.show({background: '#fff', opacity: 1});

        this.__body.body = $('<div></div>')
            .css({
                'position': 'fixed',
                'top': '0px',
                'left': '0px',
                'width': '100%',
                'height': '100%',
                'overflow': 'hidden',
                'z-index': '150'
            })
            .appendTo($('body'))

        bpage.hideMessage();

        this.__body.panels = this.getRow(options.row);
        this.row = options.row;
        this.cursor = 0;

        this.__body.panels.css('display', 'block')

        $(document).keydown(this.__body.handlers.keypress)

        return true;
    },

    getRow: function (r) {
        var nrow = null;
        if(this.__body.body.find('> div:eq(' + r + ')').length == 0) {
            var l = 0;
            if((l = this.__body.body.find('> div').length - 1) < r) {
                for(var i = l; i < r; i++)
                    this.__body.body.append(
                        $('<div></div>')
                            .css({
                                'position': 'absolute',
                                'top': '0px',
                                'left': '0px',
                                'display': 'none',
                                'width': '100%',
                                'height': '100%',
                                'overflow': 'hidden',
                                'z-index': '150'
                            })
                    )
            }
        }

        nrow = this.__body.body.find('> div:eq(' + r + ')');

        if(nrow.length == 0) {
            alert('Error');
            return null;
        }

        this.render(0, 5, r);

        nrow.find('> div:eq(0)').css({
                'display': 'block',
                'left': '5%'
            })
        .end()

        return nrow;
    },
    render: function (start, limit, row) {
        if(!this.conf.matrix[row])
            return;

        var content = this.__body.body.find(' > div:eq(' + row + ')')

        var length = content.find('> div').length;

        // check and load interval
        if(start + limit > length) {
            limit = (start + limit) - length
            start = length

            switch(typeof(this.conf.matrix[row])) {
                case 'object':
                    cols = this.conf.matrix[row].slice(start, start + limit)
                    break
                case 'function':
                    cols = this.conf.matrix[row].apply(content, [start, limit, row])
                    break
                default:
                    return
            }

            var draw = this.conf.draw;
    
            $(cols).each(function () {
                item = $('<div></div>')
                    .css({
                        'width': '90%',
                        'height': '90%',
                        'position': 'absolute',
                        'top': '5%',
                        'left': '5%',
                        'display': 'none',
                        'border': '1px solid #fff'
                    })
                    .appendTo(content)

                item.html(draw.apply(item, [this]))
            })
        }
    },
    hSlice: function (actual, other, direction) {
        var left = Math.floor(actual.offset().left);

        actual.css({
            'left': left
        })

        var margin_left = Math.floor(this.__body.panels.width() * .05 * 2);

        other.css({
            'left': (direction == 'right' ? this.__body.panels.outerWidth() + margin_left : (other.outerWidth() + margin_left) * -1 ) + 'px',
            'display': 'block'
        })

        var factor = 50 * (direction == 'right' ? 1 : -1);
        var sto = 10;
        
        var slice = function () {
            var nl = parseInt(other.css('left'), 10)

            if(direction == 'right' ? nl <= left : nl >= left) {
                continuos.__in_process = false;

                actual.css('display', 'none')

                return;
            }

            nl = direction == 'right' ?
                    (nl - factor < left ? left : nl - factor) :
                    (nl - factor > left ? left : nl - factor)

            actual.css('left', parseInt(actual.css('left'), 10) - factor)
            other.css('left', nl)

            setTimeout(slice, sto);
        }

        setTimeout(slice, sto);
    },
    vSlice: function (actual, other, direction, row) {
        var h = $(window).height();
        h += Math.floor(h * .05);

        // limite
        var top = 0;

        other.css({
            'top': (direction > 0 ? h : h * -1 ),
            'display': 'block'
        })

        actual.css({
            'top': '0px'
        })


        var factor = 10 * direction;
        var sto = 10;

        var slice = function () {
            var nt = parseInt(other.css('top'), 10)

            if(direction > 0 ? nt <= 0 : nt >= top) {
                continuos.__body.panels
                    .css('display', 'none')
                    .find('> div')
                        .css('display', 'none')
                        .end()

                continuos.__body.panels = other
                continuos.cursor = 0;
                continuos.row = row;

                continuos.__in_process = false;

                return;
            }

            nt = direction > 0 ?
                    (nt - factor < top ? top : nt - factor) :
                    (nt - factor > top ? top : nt - factor)

            actual.css('top', parseInt(actual.css('top'), 10) - factor)
            other.css('top', nt)

            setTimeout(slice, sto);
        }

        setTimeout(slice, sto);
    }
}
