/// class PD.Web.AjaxErrorHandler

PD.Web.AjaxErrorHandler = Class.extend({

    //===================================
    // FIELDS
    //===================================

    _options: null,
    _context: null,
    _data: null,

    //===================================
    // CONSTRUCTOR
    //===================================

    init: function (options) {

        this._options = _.extend({
            config: null,
            jqXHR: null
        }, options);

        if (this.isRedirect()) {
            return;
        }

        if (this.isHeaderError()) {
            return;
        }

        if (this._options != null && this._options.config != null) {
            this._context = this._options.config.contextData;
        }

        this.parseData();
        this.notify();

    },

    //===================================
    // PROPERTIES
    //===================================

    get_options: function () {
        return this._options;
    },

    get_context: function () {
        return this._context;
    },

    //===================================
    // METHODS
    //===================================
    
    parseData: function () {
    
        var options = this.get_options();

        try {
            this._data = options.jqXHR.responseJSON;
        }
        catch (ex) {
            this._data = [];
        }

    },

    notify: function () {

        var isErrorDataAnArray = _.isArray(this._data);

        var fieldErrors = _.filter(this._data, function (item) {
            return item.key != null;
        });

        var fieldlessErrors = _.filter(this._data, function (item) {
            return item.key == null;
        });

        var hasFieldErrors = isErrorDataAnArray && fieldErrors.length > 0;
        var hasFieldlessErrors = isErrorDataAnArray && fieldlessErrors.length > 0;
        var isErrorObject = _.has(this._data, "message");
        var isRequestAborted = this.get_options().jqXHR.statusText === "abort";

        if (this.hasControl()) {
            this.get_context().control.enable();
        }

        if (hasFieldErrors && this.get_context() != null) {
            new PD.Web.InvalidFieldHighlighter(fieldErrors, this.get_context().container);
        }

        if (hasFieldlessErrors) {
            this.showErrorsDialog(fieldlessErrors);
        }

        if (isErrorObject) {
            this.showErrorsDialog(this._data);
        }

        if (!hasFieldErrors && !hasFieldlessErrors && !isErrorObject && !isRequestAborted) {
            this.showCatchAllErrorDialog();
        }

    },

    hasFieldErrors: function () {
        return this._data != null
                && _.isArray(this._data)
                && _.find(this._data, function (item) {
                    return item.key != null
                });
    },

    hasContext: function () {
        return this.get_context() != null;
    },

    hasContainer: function () {
        return this.hasContext()
                && this.get_context().container != null;
    },

    hasControl: function () {
        return this.hasContext()
                && this.get_context().control != null
                && this.get_context().control.length > 0;
    },

    isRedirect: function () {

        var redirect = this.get_options().jqXHR.getResponseHeader('Http-Redirect');

        if (redirect != null) {
            window.location = redirect;
        }

        return redirect != null;

    },

    isHeaderError: function () {

        var errorMessage = this.get_options().jqXHR.getResponseHeader('error-message');

        if (errorMessage != null) {

            PD.Web.UI.MessageDialog.error({
                title: "Application Error",
                message: errorMessage
            });

        }

        return errorMessage != null;

    },

    showErrorsDialog: function (errors) {

        if (!_.isArray(errors)) {
            errors = [{ message: errors.message }]
        }

        PD.Web.UI.ErrorDialog.show({
            title: "Errors Detected",
            message: "The following errors were detected:",
            errors: errors,
            buttons: [
                {
                    label: "OK",
                    callback: function (e) {
                        e.close();
                    }
                }
            ]
        });

    },

    showCatchAllErrorDialog: function () {

        var message = [
            "The system is unable to complete your request due to an unspecified error.<br/><br/>",
            "Please try the operation again and contact your system administrator if the problem persists."
        ];

        PD.Web.UI.MessageDialog.error({
            title: "Unhandled Error",
            message: message.join("")
        });

    }

});