
var GridSort = {
    currentOrder: null,
    newOrder: null,
    pairList: null,
    currentPair: 0,
    // Sorting algorithm for grid
    sort: function() {
        var pairCounter = 0;

        // Reset the global ReplacePair object
        GridSort.pairList = new Array();
        GridSort.currentPair = 0;

        var oldOrder = GridSort.currentOrder;
        var newOrder = GridSort.newOrder;

        // Find all the pairs via modified insertion sort
        for (var i = 0; i < newOrder.length; i++) {
            if (newOrder[i] != oldOrder[i]) {
                var pair = {};

                var currentIdList = new Array();

                $('#grid li').each(function() {
                    currentIdList.push(this.id.substr(7));
                });

                var movingDot = GridService.findDot(oldOrder[i]);
                var orderingDot = GridService.findDot(newOrder[i]);

                pair.movingData = GridSort.dotParse(movingDot);
                pair.orderingData = GridSort.dotParse(orderingDot);

                // Swap the two in the array
                var newIndex = $.inArray(pair.orderingData.id, oldOrder);
                var newData = oldOrder[newIndex];
                oldOrder[newIndex] = oldOrder[i];
                oldOrder[i] = newData;

                // Insert into the global pair list
                GridSort.pairList[pairCounter] = pair;
                pairCounter++;
            }
        }

        GridSort.currentOrder = oldOrder;

        // Run through all the pairs, and run the animations in the queue
        for (var i = 0; i < GridSort.pairList.length; i++) {
            $(GridService).queue(
                'grid', function() {
                    GridSort.animate();
            });
        }
    },
    animate: function() {
        var currentPair = GridSort.pairList[GridSort.currentPair];

        var movingDot = GridService.findDot(currentPair.movingData.id);
        var orderingDot = GridService.findDot(currentPair.orderingData.id);

        GridService.animate(
            movingDot,
            currentPair.orderingData
        );

        GridService.animate(
            orderingDot,
            currentPair.movingData,
            function() {
                $(GridService).dequeue('grid');
            }
        );

        GridSort.currentPair++;
    },
    // Parse an li dot element to tranfer data into a JSON object
    dotParse: function(dot) {
        dotData = {};
        dotData.style = dot.children('.flavor-dot').attr('style');
        dotData.name = dot.children('.flavor-data').children('p:first').text();
        dotData.description =
            dot.children('.flavor-data').children('p:last').text();
        dotData.id = dot.attr('id').substr(7);

        return dotData;
    }
}

// Replaces dots every 3 minutes, supplies animation for replacement, and reorder
var GridService = {
    url: '',
    isWall: false,
    animationSpeed: 800,
    currentOrder: null,
    newOrder: null,
    init: function() {
        this.start();
    },
    // Starts the AJAX update for the GridService for every 3 minutes
    start: function() {
        this.timer = setInterval('GridService.update()', 180000);
        //this.timer = setInterval('GridService.update()', 60000);
    },
    // AJAX update function
    update: function() {
        var self = this;
        ToolTips.hideAction();

        $.getJSON(
            this.url,
            {
                'format': 'json',
                'version': $('#cabinet-version').text()
            },
            function(data) {
                // Prepare GridSort arrays
                GridSort.currentOrder = new Array();
                GridSort.newOrder = data.orderedFlavors;

                $('#grid li').each(function() {
                    GridSort.currentOrder.push(this.id.substr(7));
                });

                if (data.removedFlavors.length > 0) {
                    ToolTips.hideAction();
                    // Queue up the replacement animation
                    $(self).queue('grid', function() {

                        if ($('#cabinet-version').text() != data.version) {
                            $('#cabinet-version').text(data.version);

                            for (var i = 0; i < data.removedFlavors.length; i++) {
                                var oldDot = self.findDot(data.removedFlavors[i]);
                                var newDot = data.addedFlavors[i];

                                var oldDotIndex = GridSort.currentOrder.indexOf(
                                    data.removedFlavors[i]
                                );

                                // Track changes in the GridSort
                                GridSort.currentOrder[oldDotIndex] =
                                    data.addedFlavors[i].id;

                                if (i == data.removedFlavors.length - 1) {
                                    self.animate(
                                        oldDot,
                                        newDot,
                                        function() {
                                            var currentIdList = new Array();

                                            $('#grid li').each(function() {
                                                currentIdList.push(
                                                    this.id.substr(7)
                                                );
                                            });

                                            $(self).dequeue('grid');
                                    });
                                } else {
                                    self.animate(oldDot, newDot);
                                }
                            }
                        }
                    });
                }

                $(self).queue('grid', function() {
                    // Run the Dot Sort Algorithm in the queue
                    if (self.isWall
                        && GridSort.newOrder != GridSort.currentOrder) {

                        $(self).queue('grid', function() {
                            GridSort.sort();
                            $(self).dequeue('grid');
                        });
                    }
                    $(self).dequeue('grid');
                });

                $(self).dequeue('grid');
            }
        );
    },
    // Find Dot li element
    findDot: function(id) {
        return $('#flavor_' + id);
    },
    // Replace Dot element with new dot data
    replaceDot: function(currentDot, newDot) {

        var dotStyle = "";

        if (newDot.color != null) {
            dotStyle = 'background-color: #' + newDot.color;
        } else if (newDot.image != null) {
            dotStyle = 'background-image: url(' + newDot.image + ')';
            if (newDot.id < 0) {
                dotStyle += ';border:none;';
            }
        } else {
            dotStyle = newDot.style;
        }

        currentDot.children('.flavor-dot').attr(
            'style', dotStyle
        );

        currentDot.children('.flavor-data').children('p:first').text(
            newDot.name
        );

        currentDot.children('.flavor-data').children('p:last').html(
            newDot.description
        );

        currentDot.children('.flavor-name').text(
            newDot.name
        );

        currentDot.attr('id', 'flavor_' + newDot.id);
    },
    // Replacement animation, run a callback if there (for queue)
    animate: function(currentDot, newDot) {
        var callback = arguments[2];

        var self = this;

        currentDot.animate(
            {
                opacity: 0
            },
            this.animationSpeed
        );

        currentDot.children('.flavor-dot').animate(
            {
                left: '+=45',
                top: '+=45',
                width: '-=90',
                height: '-=90'
            },
            this.animationSpeed
        );

        $(currentDot).queue(function() {
           self.replaceDot(currentDot, newDot);
           $(this).dequeue();
        });

        currentDot.animate(
            {
                opacity: 1
            },
            this.animationSpeed
        );
        currentDot.children('.flavor-dot').animate(
            {
                left: '-=45',
                top: '-=45',
                width: '+=90',
                height: '+=90'
            },
            this.animationSpeed
        );

        if (typeof(callback) == 'function') {
            $(currentDot).queue(function() {
                callback();
                $(this).dequeue();
            });
        }
    }
}

// Global array for pair list (Used during queues)
var ReplacePair = {
    pairList: null,
    current: 0,
    next: function() {
        return ReplacePair.pairList[ReplacePair.current++];
    }
}

// Sortable Cabinet to allow users to play with dots
var SortableCabinet = {
    init: function() {
        $('#grid ul').sortable({
            start: function(event, ui) {
                ToolTips.isMoving = true;
                ToolTips.hideAction();
                ToolTips.unbind();
            },
            stop: function(event, ui) {
                ToolTips.init();
                ToolTips.isMoving = false;
            }
        });
    },
    // Randomly place all the elements around the grid (unused)
    randomizePlacement: function() {
        var currentOrder     = $('#grid li');
        var newOrder         = new Array();
        var newOrderPosition = 0;

        while(currentOrder.length > 0) {
            var random = Math.floor(Math.random()*currentOrder.length);

            newOrder[newOrderPosition++] = currentOrder[random];

            currentOrder.splice(random, 1);
        }

        var cabinet = $('#cabinet-version');

        $('#grid ul').html(cabinet);
        $('#grid ul').append(newOrder);
    }
}

// Tooltip Object
var ToolTips = {
    timeoutTime: 300,
    timer: null,
    isMoving: false,
    init: function() {
        var hoverIntentConfig = {
            sensitivity: 4, // number = sensitivity threshold (must be 1 or higher)
            interval: 300, // number = milliseconds for onMouseOver polling interval
            over: ToolTips.showEvent,
            out: ToolTips.hideEvent
        }
        $('.flavor-dot').hoverIntent(hoverIntentConfig);

        $('#tooltip').hover(function() {
            clearTimeout(ToolTips.timer);
            ToolTips.timer = null;
        }, function() {
            ToolTips.hideAction();
        });
    },
    unbind: function() {
        $('.flavor-dot').unbind('mouseenter');
        $('.flavor-dot').unbind('mouseleave');
        $('.flavor-dot').unbind('mouseover');
        $('.flavor-dot').unbind('mouseout');
    },
    // Event-called "show" action, keeps on screen if over to left
    showEvent: function() {
        if (ToolTips.isMoving) {
            return;
        }
        clearTimeout(ToolTips.timer);

        var position = $(this).parent().position();
        var screenOffset = $(this).parent().offset();
        var boxWidth = $('#tooltip-body').css('width');
        var arrowWidth = $('.tooltip-arrow-base').css('width');

        var leftOffset = 5 + parseInt(boxWidth) + parseInt(arrowWidth);

        var screenPosition = screenOffset.left - leftOffset
        var gridPosition = position.left - leftOffset;

        if (screenPosition < 0) {
            gridPosition = position.left +
                parseInt($(this).parent().css('width')) + 10;

            $('.tooltip-arrow-base').attr('id', 'tooltip-arrow-left');
            $('.tooltip-arrow-base').css('left', '-16px');
        } else {
            $('.tooltip-arrow-base').attr('id', 'tooltip-arrow');
            $('.tooltip-arrow-base').css('left', '185px');
        }

        $('#tooltip').css({
            'top': position.top,
            'left': gridPosition
        });

        $('#tooltip-body').html($(this).siblings('.flavor-data').html());
        $('#tooltip').fadeIn('fast');
    },
    // Event-called "hide" action, utilizes a timeout to add "waiting"
    hideEvent: function() {
        ToolTips.timer = setTimeout(function() {
                ToolTips.timer = null;
                ToolTips.hideAction();
            }, ToolTips.timeoutTime
        );
    },
    // Hide Action
    hideAction: function() {
        $('#tooltip').fadeOut('fast');
    }
}

// Dim/Reveal of the Footer colors
var FooterHover = {
    init: function() {
        var self = this;

        $('#footer').hover(
            self.dimOff, self.dimOn
        );
    },
    // Reveal and color the footer section
    dimOff: function() {
        $('#footer a').css({
            'color': '#FF6600'
        });

        $('#map-link, #last-address-line').css({
            'color': '#FF0011'
        });

        $('#home-link').css({
            'color': '#669911'
        });

        $('#footer-follow a').css({
            'background-position': '0 0'
        });

        $('#footer, .footer-title').css({
            'color': '#333333'
        });
    },
    // Dim the footer section
    dimOn: function() {
        $('#footer a, #last-address-line').css({
            'color': '#CCCCCC'
        });

        $('#footer-follow a').each(function() {
            var width = $(this).css('width');

            $(this).css({
                'background-position': '-' + width + ' 0'
            });
        });

        $('#footer').css({
            'color': '#AAAAAA'
        });

        $('.footer-title').css({
            'color': '#888888'
        });
    }
}

// Hide Text from the "hide text & play"
var HideTextButton = {
    textVisible: true,
    runningLock: false,
    init: function() {
        var self = this;

        $('.toggle_show').click(function(event) {
            event.preventDefault();
            self.toggleText();
        });
    },
    // Fade the text, and fade the replacement header while locking
    toggleText: function() {
        var self = this;

        if (self.runningLock == true) {
           return;
        }

        if (self.textVisible == true) {
            self.runningLock = true;

            // Turn off tooltips
            ToolTips.hideAction();
            ToolTips.unbind();

            $('.flavor-name').fadeOut("slow");

            $('#header').fadeOut("slow");
            $('#header').queue(function() {
                $('#header-swap').fadeIn("slow");
                $(this).dequeue();
            });

            $('#footer').fadeOut("slow");

            $('#header').queue(function() {
                $('#grid').css({
                    'background':'#ffffff'
                });

                self.textVisible = false;
                self.runningLock = false;
                $(this).dequeue();
            });

        } else {
            self.runningLock = true;

            $('#header-swap').fadeOut("slow");
            $('#header-swap').queue(function() {
                $('.flavor-name').fadeIn("slow");
                $('#footer').fadeIn("slow");
                $('#header').fadeIn("slow");
                $(this).dequeue();
            });

            $('#header-swap').queue(function() {
                self.textVisible = true;
                self.runningLock = false;

                $('#grid').css({
                    'background':'#ffffff url(../img/bg-dotted-line.png) repeat scroll left top'
                });

                $(this).dequeue();
            });

            ToolTips.init();
        }
    }
}

var MobileDescription = {
    init: function() {
        $('.flavor-dot').click(function() {
            MobileDescription.show(this);
        });
        $('#back-button').click(function(event) {
            event.preventDefault();
            MobileDescription.hide();
        });
    },
    show: function(dot) {
        var scrollX = window.pageXOffset;
        var scrollY = window.pageYOffset;
        $('#mobile-dot').attr('style', $(dot).attr('style'));
        $('#mobile-description').html($(dot).siblings('.flavor-data').html());
        $tip = $('#mobile-tip');
        $tip.css('top', scrollY);
        $tip.css('left', window.innerWidth);
        $tip.show();
        $tip.animate({
            left: 0
        }, 300);
    },
    hide: function() {
        $tip = $('#mobile-tip');
        $tip.css('left', 0);
        $tip.animate({
            left: window.innerWidth
        }, 300,
        function() {
            $('#mobile-tip').hide();
        });
    }
}
if (!Array.indexOf) {
    Array.prototype.indexOf = function(obj) {
        for (var i=0; i<this.length; i++) {
            if (this[i]==obj) {
                return i;
            }
        }
        return -1;
    }
}


