$(function () {

    // Setup de funciones globales de AJAX jQuery
    $.ajaxSetup({ cache: false });
    $.ajaxSetup({ beforeSend:
                        function (xhr) {
                            AjaxHandlerSingleton.OnJQueryBeginHandler(this, xhr);
                        }
    });
    $.ajaxSetup({ complete:
                        function (xhr, status) {
                            AjaxHandlerSingleton.OnJQueryCompleteHandler(this, xhr, status);
                        }
    });
    $.ajaxSetup({ error:
                        function (xhr, textStatus, errorThrown) {
                            AjaxHandlerSingleton.OnJQueryErrorHandler(this, xhr, textStatus, errorThrown);
                        }
    });

});


var AjaxHandlerSingleton = function () {

    var logOnLocation = "";
    var sessionHasTimedOutMsg = "";
    var amountOfAjaxRequests = 0;
    var ajaxActityEnabled = true;
    var ajaxSessionExpiredErrorCode = 387;

    function handlePostSucceeded() {
        $('#post-succeeded').fadeIn("slow", function () {
            $(this).delay(3000).fadeOut("slow");
        });
    }

    function showAjaxActivity() {
        amountOfAjaxRequests++;

        if (ajaxActityEnabled) {
            $('#ajaxGeneralLoading').show();
        }
    }

    function hideAjaxActivity() {
        amountOfAjaxRequests--;

        if (amountOfAjaxRequests <= 0) {
            $('#ajaxGeneralLoading').hide();
        }
    }

    function popupResize() {
        //FancyboxHandlerSingleton.ResizePopupIfActive();
    }

    function checkIfPostShouldBeInformedAtAjaxMvc(data) {
        var cancelInform = false;

        $(data).each(function () {
            var $this = $(this);
            if ($this) {
                if ($this.attr('class') == 'enableCancelFeedbackMessageIfPostFailed') {
                    var val = $this.val();
                    if (val && val.toLowerCase() == "true") {
                        cancelInform = true;
                    }
                }
            }
        });

        return cancelInform;
    }

    function checkIfPostShouldBeInformed(data) {
        try {
            var cancel = $(data).find('.enableCancelFeedbackMessageIfPostFailed');
            if (cancel) {
                var atLeastACancel = false;

                cancel.each(function () {
                    if ($(this).val() == "true") {
                        atLeastACancel = true;
                    }
                });

                if (!atLeastACancel) {
                    return true;
                }
            } else {
                return true;
            }
        }
        catch (err) {
            return true;
        }

        return false;
    }

    return {

        EnableAjaxActivity: function () {
            ajaxActityEnabled = true;
        },

        DisableAjaxActivity: function () {
            ajaxActityEnabled = false;
        },

        Initialize: function (_logOnLocation, _sessionHasTimedOutMsg) {
            logOnLocation = _logOnLocation;
            sessionHasTimedOutMsg = _sessionHasTimedOutMsg;
        },

        OnMvcBeginHandler: function (ctx) {
            showAjaxActivity();
        },

        OnMvcCompleteHandler: function (ctx) {
            if (ctx) {
                var data = ctx.get_data();
                if (data && data == sessionHasTimedOutMsg) {
                    window.location = logOnLocation;
                    return false;
                }
            }
        },

        OnMvcSuccessHandler: function (ctx, extraSuccess) {
            popupResize();
            hideAjaxActivity();

            if (ctx) {
                var request = ctx.get_request();
                if (request) {
                    var httpMethod = request._httpVerb;
                    if (httpMethod && httpMethod.toLowerCase() == "post") {
                        var data = ctx.get_data();

                        if (!data || !checkIfPostShouldBeInformedAtAjaxMvc(data)) {
                            handlePostSucceeded();
                        }
                    }
                }

                if (extraSuccess) {
                    // Llamando dinamicamente a la funcion que se pasa como String y pasandole como parametro a CTX.
                    window[extraSuccess](ctx);
                }

            }
        },

        OnMvcFailureHandler: function (ctx) {
            popupResize();
            hideAjaxActivity();

            // Session expiration Handling from Ajax request
            if (ctx && ctx._response && ctx._response._xmlHttpRequest) {
                if (ctx._response._xmlHttpRequest.status == ajaxSessionExpiredErrorCode) {
                    location.reload();
                }
            }
        },

        OnJQueryBeginHandler: function (ajaxRequest, xhr) {
            showAjaxActivity();
        },

        OnJQueryCompleteHandler: function (ajaxRequest, xhr, status) {
            popupResize();
            hideAjaxActivity();

            if (xhr && xhr.responseText) {
                var data = xhr.responseText;

                if (data && data == sessionHasTimedOutMsg) {
                    window.location = logOnLocation;
                    return false;
                }

                if (ajaxRequest.type.toLowerCase() == 'post') {
                    if (checkIfPostShouldBeInformed(data)) {
                        handlePostSucceeded();
                    }
                }
            }

            return true;
        },

        OnJQueryErrorHandler: function (ajaxRequest, xhr, textStatus, errorThrown) {
            popupResize();
            hideAjaxActivity();

            // Session expiration Handling from Ajax request
            if (xhr.status == ajaxSessionExpiredErrorCode) {
                location.reload();
            }
        },

        PopupResize: function () {
            popupResize();
        },

        HandlePostSucceeded: function () {
            handlePostSucceeded();
        },

        ShowAjaxActivity: function () {
            showAjaxActivity();
        },

        HideAjaxActivity: function () {
            hideAjaxActivity();
        }

    };
} ();


