﻿/*
* SmartWizard 2.0 plugin
* jQuery Wizard control Plugin
* by Dipu 
* 
* http://www.techlaboratory.net 
* http://tech-laboratory.blogspot.com
*/

(function ($) {
    $.fn.smartWizard = function (action) {
        var options = $.extend({}, $.fn.smartWizard.defaults, action);
        var args = arguments;

        return this.each(function () {
            var obj = $(this);
            var curStepIdx = options.selected;
            var steps = $("a.stepButton", obj); // Get all anchors in this array
            var contentWidth = 0;
            var loader, msgBox, elmActionBar, elmStepContainer, btNext, btPrevious, btFinish, btStart, btCart, ajaxLoading;

            elmActionBar = $('.actionBar', obj);
            if (elmActionBar.length == 0) {
                elmActionBar = $('<div></div>').addClass("actionBar");
            }

            msgBox = $('.msgBox', obj);
            if (msgBox.length == 0) {
                msgBox = $('<div class="msgBox"><div class="content"></div><a href="#" class="close">X</a></div>');
                elmActionBar.append(msgBox);
            }

            $('.close', msgBox).click(function () {
                msgBox.fadeOut("normal");
                return false;
            });

            // Method calling logic
            if (!action || action === 'init' || typeof action === 'object') {
                init();
            } else if (action === 'showMessage') {
                //showMessage(Array.prototype.slice.call( args, 1 ));
                var ar = Array.prototype.slice.call(args, 1);
                showMessage(ar[0]);
                return true;
            } else if (action === 'setError') {
                var ar = Array.prototype.slice.call(args, 1);
                setError(ar[0].stepnum, ar[0].iserror);
                return true;
            } else if (action == 'moveForward') {
                obj.find('a.buttonNext').click();
            } else if (action == 'reset') {
                obj.find('a.buttonStart').click();
            } else if (action == 'cart') {
                obj.find('a.buttonCart').click();
            } 
            else {
                $.error('Method ' + action + ' does not exist');
            }

            function init() {
                var allDivs = obj.children('div:not(.shopNavSection)'); //$("div", obj);                

                allDivs.addClass("content");
                // Create Elements
                loader = $('<div>Loading</div>').addClass("loader");
                elmActionBar = $('<div></div>').addClass("actionBar");
                elmStepContainer = $('<div></div>').addClass("stepContainer");
                btNext = $('<a>' + options.labelNext + '</a>').attr("href", "#").addClass("buttonNext");
                btPrevious = $('<a>' + options.labelPrevious + '</a>').attr("href", "#").addClass("buttonPrevious");
                //btFinish = $('<a>' + options.labelFinish + '</a>').attr("href", "#").addClass("buttonFinish");
                btStart = $('<a>' + options.labelStart + '</a>').attr("href", "#").addClass("buttonStart hide");
                btCart = $('<a>' + options.labelCart + '</a>').attr("href", "#").addClass("buttonCart hide");
                ajaxLoading = $('<img src="' + applicationRoot + 'UserControls/Images/loading.gif" alt=" " class="ajaxLoading hide" />');

                // highlight steps with errors
                if (options.errorSteps && options.errorSteps.length > 0) {
                    $.each(options.errorSteps, function (i, n) {
                        setError(n, true);
                    });
                }

                elmStepContainer.append(allDivs);
                elmActionBar.append(loader);
                obj.append(elmStepContainer);
                obj.append(elmActionBar);
                elmActionBar.append(btFinish).append(btNext).append(btPrevious).append(btStart).append(btCart).append(ajaxLoading);
                contentWidth = elmStepContainer.width();

                $(btNext).click(function () {
                    doForwardProgress();
                    return false;
                });
                $(btPrevious).click(function () {
                    doBackwardProgress();
                    return false;
                });
                $(btStart).click(function () {
                    resetSteps();
                    return false;
                });
                $(btCart).click(function () {
                    steps.filter('.milestoneStepComplete').click();
                    return false;
                });

                $(steps).bind("click", function (e) {
                    if (steps.index(this) == curStepIdx) {
                        return false;
                    }
                    var nextStepIdx = steps.index(this);
                    var step = steps.eq(nextStepIdx);
                    var isDone = step.attr("isDone") - 0;
                    if (isDone == 1 && !step.hasClass('disabled')) {
                        LoadContent(nextStepIdx);
                    }
                    return false;
                });

                // Enable keyboard navigation                 
                if (options.keyNavigation) {
                    $(document).keyup(function (e) {
                        if (e.which == 39) { // Right Arrow
                            doForwardProgress();
                        } else if (e.which == 37) { // Left Arrow
                            doBackwardProgress();
                        }
                    });
                }
                //  Prepare the steps
                prepareSteps();
                // Show the first slected step
                LoadContent(curStepIdx);
            }

            function prepareSteps() {
                if (!options.enableAllSteps) {
                    $(steps, obj).removeClass("selected").removeClass("done").addClass("disabled");
                    $(steps, obj).attr("isDone", 0);
                } else {
                    $(steps, obj).removeClass("selected").removeClass("disabled").addClass("done");
                    $(steps, obj).attr("isDone", 1);
                }

                $(steps, obj).each(function (i) {
                    $($(this).attr("href"), obj).hide();
                    $(this).attr("rel", i + 1);
                });
            }

            function LoadContent(stepIdx) {
                var selStep = steps.eq(stepIdx);
                var ajaxurl = options.contentURL;
                var hasContent = selStep.data('hasContent');
                stepNum = stepIdx + 1;
                if (ajaxurl && ajaxurl.length > 0) {
                    if (options.contentCache && hasContent) {
                        showStep(stepIdx);
                    } else {
                        $.ajax({
                            url: ajaxurl,
                            type: "POST",
                            data: ({ step_number: stepNum }),
                            dataType: "text",
                            beforeSend: function () { loader.show(); },
                            error: function () { loader.hide(); },
                            success: function (res) {
                                loader.hide();
                                if (res && res.length > 0) {
                                    selStep.data('hasContent', true);
                                    $($(selStep, obj).attr("href"), obj).html(res);
                                    showStep(stepIdx);
                                }
                            }
                        });
                    }
                } else {
                    showStep(stepIdx);
                }
            }

            function showStep(stepIdx) {
                var selStep = steps.eq(stepIdx);
                var curStep = steps.eq(curStepIdx);
                var isMovingForward = stepIdx > curStepIdx;
                if (stepIdx != curStepIdx) {
                    if ($.isFunction(options.onLeaveStep)) {
                        if (!options.onLeaveStep.call(this, $(curStep))) {
                            return false;
                        }
                    }
                    // if user has reached a milestone step (has a persistIsDone class), 
                    // allow them to go to it without validating otherwise if moving forward and forward only event exists, fire it. 
                    if (!selStep.hasClass('persistIsDone') && stepIdx > curStepIdx && $.isFunction(options.onForwardStep)) {
                        if (!options.onForwardStep.call(this, $(curStep))) {
                            return false;
                        }
                    }
                }
                elmStepContainer.height($($(selStep, obj).attr("href"), obj).outerHeight());
                if (options.transitionEffect == 'slide') {
                    $($(curStep, obj).attr("href"), obj).slideUp("fast", function (e) {
                        $($(selStep, obj).attr("href"), obj).slideDown("fast");
                        curStepIdx = stepIdx;
                        SetupStep(curStep, selStep, isMovingForward);
                    });
                } else if (options.transitionEffect == 'fade') {
                    $($(curStep, obj).attr("href"), obj).fadeOut("fast", function (e) {
                        $($(selStep, obj).attr("href"), obj).fadeIn("fast");
                        curStepIdx = stepIdx;
                        SetupStep(curStep, selStep, isMovingForward);
                    });
                } else if (options.transitionEffect == 'slideleft') {
                    var nextElmLeft = 0;
                    var curElementLeft = 0;
                    if (stepIdx > curStepIdx) {
                        nextElmLeft1 = contentWidth + 10;
                        nextElmLeft2 = 0;
                        curElementLeft = 0 - $($(curStep, obj).attr("href"), obj).outerWidth();
                    } else {
                        nextElmLeft1 = 0 - $($(selStep, obj).attr("href"), obj).outerWidth() + 20;
                        nextElmLeft2 = 0;
                        curElementLeft = 10 + $($(curStep, obj).attr("href"), obj).outerWidth();
                    }
                    if (stepIdx == curStepIdx) {
                        nextElmLeft1 = $($(selStep, obj).attr("href"), obj).outerWidth() + 20;
                        nextElmLeft2 = 0;
                        curElementLeft = 0 - $($(curStep, obj).attr("href"), obj).outerWidth();
                    } else {
                        $($(curStep, obj).attr("href"), obj).animate({ left: curElementLeft }, "fast", function (e) {
                            $($(curStep, obj).attr("href"), obj).hide();
                        });
                    }

                    $($(selStep, obj).attr("href"), obj).css("left", nextElmLeft1);
                    $($(selStep, obj).attr("href"), obj).show();
                    $($(selStep, obj).attr("href"), obj).animate({ left: nextElmLeft2 }, "fast", function (e) {
                        curStepIdx = stepIdx;
                        SetupStep(curStep, selStep, isMovingForward);
                    });
                } else {
                    $($(curStep, obj).attr("href"), obj).hide();
                    $($(selStep, obj).attr("href"), obj).show();
                    curStepIdx = stepIdx;
                    SetupStep(curStep, selStep, isMovingForward);
                }
                return true;
            }

            function resetSteps() {
                steps.removeClass('disabled')
                    .removeClass('done')
                    .removeClass('selected')
                    .not('.persistIsDone')
                    .attr('isDone', 0)
                    .eq(0)
                    .addClass("selected");

                LoadContent(0);
            }

            function SetupStep(curStep, selStep, isMovingForward) {
                $(curStep, obj).removeClass("selected");

                if (isMovingForward) {
                    $(curStep, obj).addClass("done");
                }
                var exists = $(curStep, obj).filter('.persistIsDone').addClass('milestoneStepComplete').length > 0;
                if (exists) {
                    btCart.show();
                }

                $(selStep, obj).removeClass("disabled");
                $(selStep, obj).removeClass("done");
                $(selStep, obj).addClass("selected");
                $(selStep, obj).attr("isDone", 1);
                adjustButton();
                if ($.isFunction(options.onShowStep)) {
                    if (!options.onShowStep.call(this, $(selStep))) {
                        return false;
                    }
                }
            }

            function doForwardProgress() {
                var nextStepIdx = curStepIdx + 1;
                if (steps.length <= nextStepIdx) {
                    if (!options.cycleSteps) {
                        return false;
                    }
                    nextStepIdx = 0;
                }
                LoadContent(nextStepIdx);
            }

            function doBackwardProgress() {
                var nextStepIdx = curStepIdx - 1;
                // find the first previous step that has been done
                while (nextStepIdx > 0) {
                    if (steps.eq(nextStepIdx).is('.done')) {
                        break;
                    }
                    nextStepIdx--;
                }
                LoadContent(nextStepIdx);
            }

            function adjustButton() {
                if (!options.cycleSteps) {
                    if (0 >= curStepIdx) {
                        $(btPrevious).addClass("buttonDisabled");
                    } else {
                        $(btPrevious).removeClass("buttonDisabled");
                    }
                    if ((steps.length - 1) <= curStepIdx) {
                        $(btNext).addClass("buttonDisabled");
                    } else {
                        $(btNext).removeClass("buttonDisabled");
                    }
                }
                // Finish Button 
                //                if (!steps.hasClass('disabled') || options.enableFinishButton) {
                //                    $(btFinish).removeClass("buttonDisabled");
                //                } else {
                //                    $(btFinish).addClass("buttonDisabled");
                //                }
            }

            function showMessage(msg) {
                $('.content', msgBox).html(msg);
                msgBox.show();
            }

            function setError(stepnum, iserror) {
                if (iserror) {
                    $(steps.eq(stepnum - 1), obj).addClass('error')
                } else {
                    $(steps.eq(stepnum - 1), obj).removeClass("error");
                }
            }
        });
    };

    // Default Properties and Events
    $.fn.smartWizard.defaults = {
        selected: 0,  // Selected Step, 0 = first step   
        keyNavigation: true, // Enable/Disable key navigation(left and right keys are used if enabled)
        enableAllSteps: false,
        transitionEffect: 'fade', // Effect on navigation, none/fade/slide/slideleft
        contentURL: null, // content url, Enables Ajax content loading
        contentCache: true, // cache step contents, if false content is fetched always from ajax url
        cycleSteps: false, // cycle step navigation
        enableFinishButton: false, // make finish button enabled always
        errorSteps: [],    // Array Steps with errors
        labelNext: 'Next',
        labelPrevious: 'Previous',
        labelFinish: 'Finish',
        labelStart: 'Start',
        labelCart: 'Review your basket',
        onCartClick: null,
        onLeaveStep: null, // triggers when leaving a step
        onForwardStep: null, // triggers when leaving a step and going forward
        onShowStep: null,  // triggers when showing a step
        onFinish: null  // triggers when Finish button is clicked
    };

}
)(jQuery);
