﻿
(function ($) {
	$.fn.ctWizard = function (action, args) {
		var wizard = $(this);
		var guid = wizard.attr("data-ct-wizard");

		switch (action) {
		    case "success":
		        //If there are any error messages in the validation summary then scroll to the top of the section and don't continue
		        //Check for the validation message (mvc) or the error message (ct)
		        var currentForm = $(args[0].trim());

		        if (currentForm.find('#ClearComplete').val() === "True") {
		            $(this).find("input[type=hidden][name=Status]").val("incomplete");
		            setStatus(this, "incomplete");
		            loadDependantWizardSteps(this);
		        }

		        if (currentForm.find('#StayOnStep').val() === "True" || currentForm.find(".validation-summary-errors").length > 0 || currentForm.find(".errorMessage:not(:empty):visible").length > 0) {
		            var id;
		            if (this.find(".subWizard").length > 0) {
		                id = this.find(".subWizard .wizardStepBody:visible").parent().find(".wizardStepHeader").attr("id");
		            } else {
		                id = this.find(".wizardStepBody").context.id;
		            }
		            scrollToSection(id);
		        } else {
		            //No Errors, update any dependent drop steps and continue to the next section
		            $(this).find("input[type=hidden][name=Status]").val("complete");
		            loadDependantWizardSteps(this);
		            setStatus(this);
		            nextHRSection(this);
		        }
		        break;
		    case "skip":
                var skipedForm = $(this).parents("form").length > 0 ? $(this).parents("form") : $(this);
		        $(skipedForm).find("input[type=hidden][name=Status]").val("skipped");
		        loadDependantWizardSteps(skipedForm);
		        setStatus(skipedForm);
		        nextHRSection(skipedForm);
		        break;
			case "failure":
			    //Don't know what happened, reload and hope it fixes it
				location.reload();
				break;
		    case "remove":
		        if (!$(this).is('form')) {
		            var updateTarget = $('#' + args);
		            var stepForm = updateTarget.parents('form');
		            var incompleteURL = stepForm.find('#MarkStepIncompleteURL');

		            if (incompleteURL && incompleteURL.length > 0) {
		                $.post(incompleteURL.val(), function () {
		                    setStatus(updateTarget.parents('.wizardStep'), "incomplete");
		                    loadDependantWizardSteps(stepForm);
		                });
		            } else {
		                setStatus(updateTarget.parents('.wizardStep'), "incomplete");
		                loadDependantWizardSteps(stepForm);
		            }
		        } else {
		            $(this).find("input[type=hidden][name=Status]").val("incomplete");
		            setStatus(this, "incomplete");
		            loadDependantWizardSteps(this);
		        }
		        break;
			default:
				if (!guid) {
					console.error("Couldn't setup a wizard for this control.");
					return this;
				}
				setupEvents(guid, wizard);
				break;
		}

		reloadControls();
		return this;
	};

	function reloadControls() {
	    CircuiTreeWeb.reloadCommonControls();
	    selectDefaultRowsForEdit();
	}

	function loadDependantWizardSteps(wizardStep) {
		/// <summary>
		/// Loads any other steps that need to be loaded because data on that step might have changed.
		/// </summary>
	    /// <param name="wizardStep">Wizard step to load dependent steps for</param>
	    $(wizardStep).find("[name=UpdateAction]").each(function (i1, updateAction) {
            $("form[action*='" + $(updateAction).val() + "']").each(function (i2, formUpdate) {
				$($(formUpdate).attr("data-ajax-update")).load($(formUpdate).attr("action"));
			});
	    });

	    $(wizardStep).find("[name=UpdateAttributeAction]").each(function (i1, updateAction) {
	        $($(updateAction).parents('form').attr("data-ajax-update") + "-attributes").load($(updateAction).val());
	    });
	}

	function nextHRSection(currentForm) {
		/// <summary>
		/// Hides the current wizard step and shows the next step
		/// </summary>
		/// <param name="currentForm">The current form that the wizard is showing right now.</param>

		//Try to find the next section
		var sectionFound = currentForm.next("form").find(".wizardStepBody").length > 0;

		//Hide this section, show the next
		hideSection(currentForm.find(".wizardStepBody:first"), sectionFound);
		showSection(currentForm.next("form").find(".wizardStepBody:first"), currentForm.next("form").find(".wizardStepHeader:first").attr("id"));
	}

	function setAsideHeight() {
		/// <summary>
		/// Sets the height of the text box that floats beside the wizard as the user scrolls up and down.
		/// </summary>
	    var aside = $("aside");

	    //If aside is undefined then just return nothing to do.
	    if (aside == undefined || aside.length == 0) { return true; }

	    var parentTop = aside.parent().offset().top;
	    var parentHeight = aside.parents(".articlecontent").height();
		var parentWidth = aside.parent().width();
		var windowTop = $(window).scrollTop();
		var animateSpeed = 100;
		var windowHeight = $(window).innerHeight();
		var margin = 40;

		if (windowTop < parentTop) {
			//Top of page
			aside.addClass("affix-top");
			aside.removeClass("affix-bottom");
			aside.removeClass("affix");
			aside.css("top", '');
		} else {
			var topCalc = (windowTop - parentTop + 10) + 'px';
			var heightCalc = 0;

			if ((windowTop + $(window).height()) === $(document).height()) {
				//Bottom of page, remove the footer
				aside.removeClass("affix-top");
				aside.addClass("affix-bottom");
				aside.css("top", topCalc);
				aside.removeClass("affix");
				var footerHeight = $(document).height() - parentHeight - parentTop;
				heightCalc = Math.min((windowHeight - footerHeight), parentHeight) - margin + 'px';
			}
			else {
				//Middle of the page
				aside.removeClass("affix-top");
				aside.removeClass("affix-bottom");
				aside.css("top", '');
				aside.addClass("affix");
				heightCalc = Math.min(windowHeight, parentHeight) - margin + 'px';
			}
		}

		//Manually set the width since the relative/fixed and absolute have different default widths
		aside.css("width", (parentWidth - margin) + 'px');
	}

	function setAsideTextDefault() {
		/// <summary>
		/// Sets the default text using reserved id's of existing divs
		/// </summary>

		$('#wizardAsideText > span').text($('#wizardDefaultAside').text());
	}

	function setAsideText(htmlText) {
		/// <summary>
		/// Sets the aside text with given text (html)
		/// </summary>
		/// <param name="htmlText">Html to be used as text</param>

		$('#wizardAsideText > span').html(htmlText);
	}

	function hideSection(sect, sectionFound) {
		/// <summary>
		/// Hides a given section and sets the default text if the next section was not found
		/// </summary>
		/// <param name="sect">Section to hide</param>
		/// <param name="sectionFound">If the next section was found.</param>

	    $('input[type="hidden"]').filter('[data-ct-stepid="' + sect.attr('data-ct-stepid') + '"]').val('False');

		sect.hide(750, function () {
			setAsideHeight();
		});

		//Set aside instruction back to default
		if (!sectionFound) {
			setAsideTextDefault();
		}
	}

	function scrollToSection(sectionID) {
		/// <summary>
		/// The id of the wizard step that needs to be scrolled into view.
		/// </summary>
		/// <param name="sectionID">The id of the step to be scrolled to.</param>
	    setTimeout(function () {
	        var $offset = $("#" + sectionID).offset();
	        if (!$offset) { return; }
	        var yOffset = $offset.top;

			$("html, body").animate({ scrollTop: yOffset }, 500, function () {
				setAsideHeight();
			});
		}, 300);//Random amount of time (trial and error) to allow the slideToggle to finish animating the UI
	}

	function showSection(sect, stepID) {
		/// <summary>
		/// Shows a given section and sets the aside text 
		/// </summary>
	    /// <param name="sect">Section to show</param>

	    if (!stepID) {
	        stepID = sect.context.id;
	    }
	    $('input[type="hidden"]').filter('[data-ct-stepid="' + sect.attr('data-ct-stepid') + '"]').val('True');

		sect.slideToggle(500, function () {
		    scrollToSection(stepID);
		});

		//Copy instructional text to aside
		setAsideText(sect.find('.wizardStepInstructionsAsideTemp').html());
	}

	function setStatus(sect, status) {
	    if (!status) { status = $(sect).find("input[type=hidden][name=Status]").val(); }
	    $(sect).find(".wizardStepStatus:first").attr("class", "wizardStepStatus " + status);
	}

	function validate(form) {
	    var validationInfo = $(form).data("unobtrusiveValidation");
	    return !validationInfo || !validationInfo.validate || validationInfo.validate();
	}

	function toggleSection(sectionHeader) {
		/// <summary>
		/// Shows the given wizard step and hides all other steps
		/// </summary>
	    /// <param name="sectionHeader">The wizard header that has been clicked on.</param>
	    var stepID = sectionHeader.attr('data-ct-stepid');
	    var headerID = sectionHeader.attr("id");
	    //Find all the current wizard steps that aren't sub wizard steps unless this is a sub wizard header.
	    //  This keeps the sub wizard steps expanded when its parent step is collapsed to keep track of where the user is in the sub wizard.
	    var wizardSteps = $(sectionHeader.parents('.sectionWizard')[0]).find('.wizardStepBody:not(.sectionWizard > .wizardStepBody)');
	    var sectionFound = false;

	    wizardSteps.each(function () {
	        var sect = $(this);

	        if (sect.attr('data-ct-stepid') === stepID && !sect.is(':visible')) {
	            showSection(sect, headerID);
	            sectionFound = true;
	        } else {
	            hideSection(sect, sectionFound);
	        }
	    });

        var subWizardStartNav = sectionHeader.parents('.wizardStepBody:first').find('.subWizardStartNavigation');
	    if (subWizardStartNav && subWizardStartNav.length > 0)
	    {
	        //If all section where hidden then show the sub wizard start navigation otherwise hide it.
	        if (!sectionFound) { subWizardStartNav.show(); }
	        else { subWizardStartNav.hide(); }
	    }
	}

	function submitForm(form, isSkipped) {
	    //Set all the meta-data on the form before it is submitted
	    //Open the saving dialog
	    form.attr("data-ajax-begin", "(function(){$('#savingDialog').dialog('open');})()");

	    //Close the saving dialog
	    form.attr("data-ajax-complete", "(function(){$('#savingDialog').dialog('close');})()");

	    //Call the wizard init method with a specific action (success or failure) 
        form.attr("data-ajax-failure", "(function(that, arguments){$(that).ctWizard('failure', arguments);})(this, arguments)");
        if (isSkipped) {
            form.attr("data-ajax-success", "(function(that, arguments){$(that).ctWizard('skip', arguments);})(this, arguments)");
        }
        else {
            form.attr("data-ajax-success", "(function(that, arguments){$(that).ctWizard('success', arguments);})(this, arguments)");
        }

	    //Validate the form
	    if (!validate(form)) {
	        return;
	    }

	    //Submit the form
	    form.trigger("submit");
	}

	function selectRowForEdit(el) {
	    var detailRow = $(el).parents('.detailRow');
	    var editRowID = detailRow.attr('data-ct-editRowID');
	    var parentForm = $(detailRow).parents('form');
	    var editRow = (editRowID ? parentForm.find('#' + editRowID) : parentForm.find('.editRow'));
        var currentEditID = editRow.attr('data-ct-currentObjectID');
        var newEditID = detailRow.attr('data-ct-objectID');

        if (currentEditID == newEditID) {
            //If the current edit object is the new edit object then we just need to hide the detail row.
            editRow.find('.cancelEditDetailRow').show();
            detailRow.hide();
            return;
        }

        //cancel any current edits
        cancelRowEdit(editRow.find('.cancelEditDetailRow'));

        //fade out sections
        editRow.fadeTo(750, 0);
        detailRow.fadeOut(750, function () {
            var detailInputs = detailRow.find('input');
            var editInputs = editRow.find('input, select, textarea');

            //Loop thru each of the inputs in the selected row
            for (i = 0; i < detailInputs.length; i++) {
                var detailInput = $(detailInputs[i]);
                var inputArray = detailInput.attr('id').split("_");
                var detailID = inputArray[inputArray.length - 1];

                $.each(editInputs.filter('[id$="' + detailID + '"]'), function (i, el) {
                    var editInput = $(el);

                    //If the control name in the selected row matches that of the edit row, copy over values
                    if (editInput.attr('type') == 'radio') {
                        if (editInput.val() == detailInput.val()) {
                            editInput.prop('checked', true);
                        }
                    } else if (editInput.is('select')) {
                        editInput.find('option[value="' + detailInput.val() + '"]').attr('selected', 'selected');
                    } else if (editInput.attr('type') === 'Date') {
                        editInput.val($.datepicker.formatDate("yy-mm-dd", new Date(detailInput.val())));
                    } else {
                        editInput.val(detailInput.val());
                    }
                });
            }

            editRow.attr('data-ct-currentObjectID', newEditID);
            editRow.find('.cancelEditDetailRow').show();
            editRow.find('.saveDetailRow').val("Save");
            editRow.fadeTo(750, 100);

            CircuiTreeWeb.loadShowHideOptions();
        });
	}

	function selectDefaultRowsForEdit() {
        $.each($('.defaultEditRow'), function (i, el) {
            selectRowForEdit(el);
            $(el).removeClass('defaultEditRow');
        });
    }

    function cancelRowEdit(el) {
        var editRow = $(el).parents('.editRow');

        editRow.fadeTo(750, 0, function () {
            var editInputs = editRow.find('input, select, textarea');

            //Loop thru each of the inputs in the edit row to clear
            for (j = 0; j < editInputs.length; j++) {
                var editInput = $(editInputs[j]);

                if (editInput.attr('type') === 'radio' || editInput.attr('type') === 'checkbox') {
                    if (editInput.attr('checked') === 'checked') {
                        editInput.prop('checked', true);
                    } else {
                        editInput.prop('checked', false);
                    }
                } else {
                    editInput.val('');
                }
            }

            editRow.attr('data-ct-currentObjectID', 0);
            editRow.find('.cancelEditDetailRow').hide();
            editRow.find('.saveDetailRow').val("Add");

            //show all hidden detail rows
            $('.editRow').parents('form').find('.detailRow:hidden').fadeIn(500);
            editRow.fadeTo(750, 100);
        });
    }

	function setupEvents(guid, wizard) {
		$(document).on("click", ".wizardStepHeader", function () {
			/// <summary>
			/// Event that is fired when a user clicks the wizard step header
			/// </summary>
			try {
			    $('#loadingDialog').dialog('open');

			    toggleSection($(this));
			} catch (e) {
			}
			finally {
				$('#loadingDialog').dialog('close');
			}

			return false;
		});

		$(document).on('click', '[data-ct-toggledisabled] ', function (e) {
		    if ($(this).is(":checked")) {
		        $.each($("." + $(this).attr("data-ct-toggledisabled")), function (i, e) {
		            $(e).removeClass("disabledInline");
		            $(e).find(".rate").removeClass("selected");
		            $(e).find("input[type!='hidden']").removeAttr("disabled");
		            $(e).find(".rateItem").removeAttr("disabled");
		            $(e).removeAttr("disabled");
		        });

		        CircuiTreeWeb.HR.fillRatings($(this).parents('tr').find('.rate:first'));
		    } else {
		        $.each($("." + $(this).attr("data-ct-toggledisabled")), function (i, e) {
		            $(e).addClass("disabledInline");
		            $(e).find(".rate").removeClass("selected");
		            $(e).find("input[type!='hidden']").attr("disabled", "disabled");
		            $(e).find("input[type=text]").val("");
		            $(e).find(".rateItem").attr("disabled", "disabled");
		            $(e).attr("disabled", "disabled");
		        });
		        $(this).parents('tr').find('.rate:first').siblings('[id$="__MyRating"]').val(0)
		    }
		});

        $(document).on("click", ".wizardSkipButton", function (e) {
			/// <summary>
			/// Event that is fired when a user clicks the skip button on a step
			/// </summary>
			/// <param name="e">jQuery Event Object</param>
			//e.preventDefault();
			//e.stopPropagation();

		    try {
		        $(this).attr("data-ajax-success", "(function(that, arguments){$(that).ctWizard('skip', arguments);})(this, arguments)");
			} catch (e) {
			}

			return false;
		});

		$(document).on("click", ".wizardPreviousButton", function (e) {
			/// <summary>
			/// Event that is fired when a user clicks on the previous button in the wizard step
			/// </summary>
			/// <param name="e">jQuery Event Object</param>
			/// <remarks>NOT Implemented</remarks>

			e.preventDefault();
			e.stopPropagation();

			//try {
			//	$('#savingDialog').dialog('open');
			//	console.log("Previous button clicked!");
			//} catch (e) {
			//	console.error(e);
			//}
			//finally {
			//	$('#savingDialog').dialog('close');
			//}

			return false;
		});

		$(document).on("click", ".wizardContinueButton,.saveDetailRow", function (e) {
			/// <summary>
			/// Event that is fired when a user clicks the continue button
			/// </summary>
			/// <param name="e">jQuery Event Object</param>
			e.preventDefault();
			e.stopPropagation();
            
			try {
			    submitForm($(this).parents("form"), false);
			} catch (e) {
			}

			return false;
		});

	    //Update Edit form with current row values
		$(document).on('click', '.editDetailRow', function (e) {
		    selectRowForEdit(this);
		});

	    //Update Edit form with current row values
		$(document).on('click', '.cancelEditDetailRow', function (e) {
		    CircuiTreeWeb.HR.cancelRowEdit(this);
		});

		$(document).on('click', '.subWizardStartButton', function (e) {
		    try {
		        $('#loadingDialog').dialog('open');

		        var subWizardContainer = $(this).parents('.wizardStepBody');
		        var firstSubStep = subWizardContainer.find('.wizardStepHeader:first');

		        toggleSection(firstSubStep);

		        $(this).parents('.subWizardStartNavigation').hide();
		    } catch (e) {
		    }
		    finally {
		        $('#loadingDialog').dialog('close');
		    }

		    return false;
		});

		$(document).on('click', '.subWizardSkipButton', function (e) {
		    e.preventDefault();
		    e.stopPropagation();

		    try {
                //Submit the form to handle the sub step.
                var parentForm = $(this).parents("form"),
                    skipForm = parentForm.find(".subWizard .wizardStep:last .subWizardSkipButton").is(this); //If this is the last step of the sub wizard then we need to move to the next main step
		        submitForm(parentForm, skipForm);

                //Set the sub wizard header icon as skipped
		        var subStepID = $(this).parents('.wizardStepBody:first').attr('data-ct-stepid');
		        var subWizHeader = $('.wizardStepHeader[data-ct-stepid="' + subStepID + '"]');
		        setStatus(subWizHeader, "skipped");
		    } catch (e) {
		    }

		    return false;
		});

		$(window).scroll(function () {
			/// <summary>
			/// When the window scrolls move the aside text box
			/// </summary>

			//Don't move it if it is already moving
			if ($("html, body").is(':animated')) { return; }

			//Don't move it if it isn't on the page
			if ($("#wizardAsideText").is(":not(:visible)")) { return; }

			CircuiTreeWeb.HR.setSideHeight();
		});
	}
}(jQuery));