﻿// *** SlideFader **********************************
(function($) {

    // Add a function for jQuery object events and chaining
    // itemQuery - query expression for items
    $.slideFader = function(appHolder, itemsQuery) {

        var init = function(items) {

            //Init first img
            currIndex = 0;

            //Set base z-index
            $(items).css('z-index', zLevel);

            var firstItem = $($(items).get(0));

            //set new img to 102
            firstItem.css("z-index", zLevel + 2);
        };

        var setupButtons = function() {

            var buttons = { prev: null, next: null };

            buttons.prev = $('<div id="slide-prev" class="button"/>');
            buttons.next = $('<div id="slide-next" class="button"/>');

            buttons.prev.appendTo('#imgScreen');
            buttons.next.appendTo('#imgScreen');

            buttons.prev.click(function() {
                if (!$(this).hasClass("disabled")) {
                    movePrev();
                }
            });

            buttons.next.click(function() {
                if (!$(this).hasClass("disabled")) {
                    moveNext();
                }
            });

            //Not working
            /*
            buttons.applyToAll = function(fnc, args) {
            for (var button in buttons) {
            fnc.apply(button, args);
            }
            }
            */

            return buttons;
        };

        var moveNext = function() {
            //If at end, set state
            if (currIndex >= items.length) {
                return;
            }
            //Else in middle or start, go to next
            else if ((currIndex + 1) < items.length) {
                currState = states.middle;
                switchImg(currIndex + 1);
            }

        };

        var movePrev = function() {
            //If at start, set state
            if (currIndex < 1) {
                return;
            }
            //Else in middle or end, go to prev
            else if ((currIndex - 1) < items.length) {
                currState = states.middle;
                switchImg(currIndex - 1);
            }

        };

        var switchImg = function(index) {
            if (index === currIndex) {
                return;
            }

            var newImg = $(items.get(index));
            var currImg = $(items.get(currIndex));

            //set new img to 101
            newImg.css("z-index", zLevel + 1);

            //fade out curr img
            $(items[currIndex]).fadeTo(800, 0, function() {

                //set new img to 102
                newImg.css("z-index", zLevel + 2);

                //set curr img to 100        
                currImg.css("z-index", zLevel);

                //turn curr img back on (should now be below new)
                currImg.fadeTo(0, 1);
            });

            //set new currIndex
            currIndex = index;

            //Update states based on new currIndex
            updateStates();

            //Button UI based on new states
            refreshButtons();

            //Throw a "changed" event for other stuff to tie into img switches
            //@TODO: Include index or item data in event
            appHolder.trigger("changed");
        };

        var updateStates = function() {
            if (items.length === 1) {
                currState = states.single;
            }
            else if (currIndex < 1) {
                currState = states.start;
            }
            else if (currIndex >= items.length - 1) {
                currState = states.end;
            }
            else {
                currState = states.middle;
            }
        };

        var refreshButtons = function() {

            switch (currState) {
                case states.start:
                    buttons.next.removeClass("disabled");
                    buttons.prev.addClass("disabled");
                    break;
                case states.end:
                    buttons.next.addClass("disabled");
                    buttons.prev.removeClass("disabled");
                    break;
                case states.middle:
                    buttons.next.removeClass("disabled");
                    buttons.prev.removeClass("disabled");
                    break;
                case states.single:
                    buttons.next.addClass("disabled");
                    buttons.prev.addClass("disabled");
                    break;
            }
        };

        var runButtonTimer = function() {

            var timer;
            var buttonsVisible = false;

            //Events causing show
            $(appHolder).mousemove(showAll);
            $(appHolder).mouseenter(showAll);
            $(appHolder).click(showAll);

            //Events causing hide
            $(appHolder).mouseout(hideAll);

            function stopTimer() {
                clearTimeout(timer);
            }

            //Timer calls hide when timed out
            function restartTimer() {
                clearTimeout(timer);
                timer = setTimeout(hideAll, 1500);
            }

            function showAll() {
                //If hidden, show buttons and restart timer
                if (!buttonsVisible) {
                    buttons.next.stop();
                    buttons.next.fadeTo(300, 1);
                    buttons.prev.stop();
                    buttons.prev.fadeTo(300, 1);
                    /* broken
                    buttons.applyToAll(function() {
                    $(this).fadeTo(400, 1);
                    });
                    */
                    visible = true;
                    restartTimer();
                }
            }

            function hideAll() {
                stopTimer();
                buttons.next.stop();
                buttons.next.fadeTo(1000, .25);
                buttons.prev.stop();
                buttons.prev.fadeTo(1000, .25);
                visible = false;
            }

            return restartTimer();

        };

        // * Main *
        var items = $(appHolder).find(itemsQuery);
        var states = { start: 0, end: 1, middle: 2, single: 3 };
        var zLevel = 100;

        var currState = items.length > 1 ? states.start : states.single;
        var currIndex = 0;

        var buttons = setupButtons();

        init(items);
        refreshButtons();
        runButtonTimer();

        //Return an object with access to current item
        return {
            getCurrItem: function() { return items[currIndex]; },
            getCurrFullLink: function() { return $(items[currIndex]).find('a.fullImage').attr("href"); }
        };

    };

})(jQuery);
