/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

var SessionError = Class.create();

SessionError.prototype = {
    initialize: function (errorText) {
        this.errorText = errorText;
    },
    toString: function () {
        return 'Session Error:' + this.errorText;
    }
};

Ajax.Request.addMethods({
    initialize: function ($super, url, options) {
        $super(options);
        this.transport = Ajax.getTransport();

        if (!url.match(new RegExp('[?&]isAjax=true',''))) {
            url = url.match(new RegExp('\\?','g')) ? url + '&isAjax=true' : url + '?isAjax=true';
        }

        if (Object.isString(this.options.parameters) &&
            this.options.parameters.indexOf('form_key=') == -1
        ) {
            this.options.parameters += '&' + Object.toQueryString({
                form_key: FORM_KEY
            });
        } else {
            if (!this.options.parameters) {
                this.options.parameters = {
                    form_key: FORM_KEY
                };
            }

            if (!this.options.parameters.form_key) {
                this.options.parameters.form_key = FORM_KEY;
            }
        }

        this.request(url);
    },
    respondToReadyState: function (readyState) {
        var state = Ajax.Request.Events[readyState],
 response = new Ajax.Response(this);

        if (state == 'Complete') {
            try {
                this._complete = true;

                if (response.responseText.isJSON()) {
                    var jsonObject = response.responseText.evalJSON();

                    if (jsonObject.ajaxExpired && jsonObject.ajaxRedirect) {
                        window.location.replace(jsonObject.ajaxRedirect);
                        throw new SessionError('session expired');
                    }
                }

                (this.options['on' + response.status] ||
                 this.options['on' + (this.success() ? 'Success' : 'Failure')] ||
                 Prototype.emptyFunction)(response, response.headerJSON);
            } catch (e) {
                this.dispatchException(e);

                if (e instanceof SessionError) {
                    return;
                }
            }

            var contentType = response.getHeader('Content-type');

            if (this.options.evalJS == 'force' ||
                this.options.evalJS && this.isSameOrigin() && contentType &&
                contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)) {
                this.evalResponse();
            }
        }

        try {
            (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
            Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
        } catch (e) {
            this.dispatchException(e);
        }

        if (state == 'Complete') {
            // avoid memory leak in MSIE: clean up
            this.transport.onreadystatechange = Prototype.emptyFunction;
        }
    }
});

Ajax.Updater.respondToReadyState = Ajax.Request.respondToReadyState;

var varienLoader = new Class.create();

varienLoader.prototype = {
    initialize: function (caching) {
        this.callback = false;
        this.cache   = $H();
        this.caching = caching || false;
        this.url     = false;
    },

    getCache: function (url) {
        if (this.cache.get(url)) {
            return this.cache.get(url);
        }

        return false;
    },

    load: function (url, params, callback) {
        this.url      = url;
        this.callback = callback;

        if (this.caching) {
            var transport = this.getCache(url);

            if (transport) {
                this.processResult(transport);

                return;
            }
        }

        if (typeof params.updaterId != 'undefined') {
            new varienUpdater(params.updaterId, url, {
                evalScripts: true,
                onComplete: this.processResult.bind(this),
                onFailure: this._processFailure.bind(this)
            });
        } else {
            new Ajax.Request(url,{
                method: 'post',
                parameters: params || {},
                onComplete: this.processResult.bind(this),
                onFailure: this._processFailure.bind(this)
            });
        }
    },

    _processFailure: function (transport) {
        location.href = BASE_URL;
    },

    processResult: function (transport) {
        if (this.caching) {
            this.cache.set(this.url, transport);
        }

        if (this.callback) {
            this.callback(transport.responseText);
        }
    }
};

if (!window.varienLoaderHandler)
    var varienLoaderHandler = new Object();

varienLoaderHandler.handler = {
    onCreate: function (request) {
        if (request.options.loaderArea === false) {
            return;
        }

        jQuery('body').trigger('processStart');
    },
    onException: function (transport) {
        jQuery('body').trigger('processStop');
    },
    onComplete: function (transport) {
        jQuery('body').trigger('processStop');
    }
};

/**
 * @todo need calculate middle of visible area and scroll bind
 */
function setLoaderPosition() {
    var elem = $('loading_mask_loader');

    if (elem && Prototype.Browser.IE) {
        var elementDims = elem.getDimensions();
        var viewPort = document.viewport.getDimensions();
        var offsets = document.viewport.getScrollOffsets();

        elem.style.left = Math.floor(viewPort.width / 2 + offsets.left - elementDims.width / 2) + 'px';
        elem.style.top = Math.floor(viewPort.height / 2 + offsets.top - elementDims.height / 2) + 'px';
        elem.style.position = 'absolute';
    }
}

function toggleSelectsUnderBlock(block, flag) {
    if (Prototype.Browser.IE) {
        var selects = document.getElementsByTagName('select');

        for (var i = 0; i < selects.length; i++) {
            /**
             * @todo: need check intersection
             */
            if (flag) {
                if (selects[i].needShowOnSuccess) {
                    selects[i].needShowOnSuccess = false;
                    // Element.show(selects[i])
                    selects[i].style.visibility = '';
                }
            } else if (Element.visible(selects[i])) {
                // Element.hide(selects[i]);
                selects[i].style.visibility = 'hidden';
                selects[i].needShowOnSuccess = true;
            }
        }
    }
}

Ajax.Responders.register(varienLoaderHandler.handler);

var varienUpdater = Class.create(Ajax.Updater, {
    updateContent: function ($super, responseText) {
        if (responseText.isJSON()) {
            var responseJSON = responseText.evalJSON();

            if (responseJSON.ajaxExpired && responseJSON.ajaxRedirect) {
                window.location.replace(responseJSON.ajaxRedirect);
            }
        } else {
            $super(responseText);
        }
    }
});
