(function($) {

    /**
     * This function updates the content of the favorites flyout.
     */
    function refreshFavoritesView() {
        EasyNavigation.reloadNavigationContent($("li[data-content-id='favorites']"));
    }

    function updatePageState(context) {
        var hash = location.hash;
        $.get(context.element.attr("data-href") + "/update", {
            update: false,
            hash: hash,
            itemName: ''
        }, function (data) {
            if (!data.error) {
                setCurrentPageAsFavorite(context, data.data == "on");
            }
        });
    }

    function setCurrentPageAsFavorite(context, state) {
        if (state) {
            context.element.addClass(context.element.attr("data-activeClass"));
        } else {
            context.element.removeClass(context.element.attr("data-activeClass"));
        }
    }

    function showMaxFavoritesPrompt() {
        var dialog = $("#localModal_maxFavorites");
        if (!dialog.length) {
            $.post(Application.contextPath() + "/navigation/ax_dialogues/maxFavorite/?decorator=empty", "favorite=true", function (data) {
                //BOOTSTRAP MODALS has to be placed outside a positioned (relative, absolute and fixed) container!!!
                $(data).appendTo("body");
                $("#localModal_maxFavorites").css("top", "50px").modal();
            });
        } else {
            dialog.modal();
        }
    }

    /**
     * Opens a modal and proposes a name based on the href
     */
    function showCreateFavoritesPrompt(context) {
        var arrPath = window.location.toString().split("/");
        var strProposal = arrPath[arrPath.length - 1];
        if (arrPath.length == 6) { //http://localhost:8082/solidweb/markets/ch (length = 6 // ;))
            if (arrPath[5].indexOf(",") > -1) {
                strProposal = arrPath[4];
            } else {
                strProposal = arrPath[4] + "_" + arrPath[5];
            }
        }
        if (strProposal.indexOf("#") > -1) {
            strProposal = strProposal.substring(0, strProposal.indexOf("#"));
        }
        if (strProposal.indexOf("?") > -1) {
            strProposal = strProposal.substring(0, strProposal.indexOf("?"));
        }
        var preSaveHash = window.location.hash;
        createEditDialog(function(strFavName, successCallback) {
            $.get(context.element.attr("data-href") + "/update", {
                update: true,
                hash: preSaveHash,
                itemName: strFavName
            }, function (data) {
                if (!data.error) {
                    setCurrentPageAsFavorite(context, data.data == "on");
                    refreshFavoritesView();
                    successCallback();
                } else {
                    switch (getErrorNumber(data.errorMessages[0])) {
                        case 1000:  //no user login
                            showNoLoginPrompt();
                            break;
                        case 1010: //max favorites reached
                            showMaxFavoritesPrompt();
                            break;
                        case 1020: //UserService is not available
                            break;
                        case 1030: //no item found to rename
                            break;
                    }
                }
            });
        }, strProposal);
    }

    /**
     * This function is used for both, create and edit a favorite.
     * @param saveCallback the callback to be executed to save the favorite.
     * @param strProposal the default favorite name to be set in the input field.
     */
    function createEditDialog(saveCallback, strProposal) {
        function bindSuccessAction(modalElement) {
            var descriptionField = modalElement.find(".favoritesDescription");
            modalElement.find(".editFavoritesTrigger").click(function () {
                // Field validation ..
                if ($.trim(descriptionField.val()) == "") {
                    var objFormGroup = descriptionField.closest(".form-group");
                    objFormGroup.addClass("has-error");
                    objFormGroup.find(".help-block").text(defaultSettings.texts.missingPageName).fadeIn();
                    descriptionField.focus();
                } else {
                    // Save favorite ..
                    var strFavName = descriptionField.val();
                    saveCallback(strFavName, function() {
                        modalElement.modal('hide');
                    });
                }
            });
        }

        var modalElement = $('#localModal_editFavorites');
        if (!modalElement.length) {
            $.post(Application.contextPath() + "/navigation/ax_dialogues/editFavorite/?decorator=empty", "favorite=true", function (data) {
                //BOOTSTRAP MODALS has to be placed outside a positioned (relative, absolute and fixed) container
                $(data).appendTo("body");
                var modalElement = $('#localModal_editFavorites');
                modalElement.find(".favoritesDescription").val(strProposal.toUpperCase());
                modalElement.css("top", "50px").modal();
                bindSuccessAction(modalElement);
            });
        } else {
            modalElement.find(".editFavoritesTrigger").off('click'); // Unbind any other success action ..
            bindSuccessAction(modalElement);
            // Update favorite description field and reset error (if any) ..
            modalElement.find(".favoritesDescription")
                .val(strProposal.toUpperCase())
                .closest(".form-group").removeClass('has-error').find('.help-block').empty();
            modalElement.modal();
        }
    }

    /**
     * Get the error number out of the error message
     */
    function getErrorNumber(strMessage) {
        //regex is like bf
        var intErrNr = 0;
        if (strMessage.indexOf("[") > -1 && strMessage.indexOf("]") > -1) {
            intErrNr = strMessage.substring(strMessage.indexOf("[") + 1, strMessage.lastIndexOf("]"));
            intErrNr = parseInt(intErrNr);
        }
        return intErrNr;
    }

    /**
     *  AddToFavorites
     */
    function init(context) {
        context.element.on("click", function (e, bln) {
            e.preventDefault();
            var blnUpdate = true;
            if (typeof bln === "boolean") {
                blnUpdate = bln;
            }
            if (context.element.data("href")) {
                if (blnUpdate && !(context.element.hasClass("favoritesOn"))) {
                    showCreateFavoritesPrompt(context);
                } else {
                    // Update the current page's favorite state ..
                    updatePageState(context);
                }
            }
        });
    }

    var defaultSettings = {
        texts: {
            missingPageName: "Missing Page Name"
        }
    };

    $.fn.SolidFavorites = function(settings) {
        return this.each(function(i, e) {
            var context = $.extend(true, {}, defaultSettings, settings);
            context.element = $(e);
            init(context);
        });
    };

    $.fn.SolidFavorites.updateFavorites = refreshFavoritesView;
    $.fn.SolidFavorites.createEditDialog = createEditDialog;

    $.fn.SolidFavorites.setDefaultSettings = function(settings) {
        $.extend(true, defaultSettings, settings);
    };
})(jQuery);
