
(function () {

    // 正在进行中的AJAX请求个数
    var __ajaxUnderwayCount = 0;

    F.ajax = {

        timeoutErrorMsg: "Request timeout, please refresh the page and try again!",
        errorMsg: "Error! {0} ({1})",
        errorWindow: null,

        hookPostBack: function () {
            if (typeof (__doPostBack) != 'undefined') {
                __doPostBack = f__doPostBack;
            }
        }

    };

    function enableAjax() {
        if (typeof (F.controlEnableAjax) === 'undefined') {
            return F.enableAjax;
        }
        return F.controlEnableAjax;
    }

    function enableAjaxLoading() {
        if (typeof (F.controlEnableAjaxLoading) === 'undefined') {
            return F.enableAjaxLoading;
        }
        return F.controlEnableAjaxLoading;
    }

    function ajaxLoadingType() {
        if (typeof (F.controlAjaxLoadingType) === 'undefined') {
            return F.ajaxLoadingType;
        }
        return F.controlAjaxLoadingType;
    }


    function f__doPostBack_internal() {
        //if (typeof (F.util.beforeAjaxPostBackScript) === 'function') {
        //    F.util.beforeAjaxPostBackScript();
        //}
		
		// 如果显式返回false，则阻止AJAX回发
        if(F.util.triggerBeforeAjax() === false) {
			return;
		}


        // Ext.encode will convert Chinese characters. Ext.encode({a:"你好"}) => '{"a":"\u4f60\u597d"}'
        // We will include the official JSON object from http://json.org/
        // 现在还是用的 Ext.encode，在 IETester的 IE8下 JSON.stringify 生成的中文是\u9009\u9879形式。
        //F.util.setHiddenFieldValue('F_STATE', encodeURIComponent(JSON.stringify(getFState())));

        var fstate = Ext.encode(getFState());
        if (Ext.isIE6 || Ext.isIE7) {
            F.util.setHiddenFieldValue('F_STATE_URI', 'true');
            fstate = encodeURIComponent(fstate);
        } else {
            fstate = Base64.encode(fstate);
        }
        F.util.setHiddenFieldValue('F_STATE', fstate);
        //F.util.setHiddenFieldValue('F_STATE', encodeURIComponent(Ext.encode(getFState())));
        if (!enableAjax()) {
            // 当前请求结束后必须重置 F.controlEnableAjax
            F.controlEnableAjax = undefined;
            F.util.setHiddenFieldValue('F_AJAX', 'false');
            theForm.submit();
        } else {
            // 当前请求结束后必须重置 F.controlEnableAjax
            F.controlEnableAjax = undefined;
            F.util.setHiddenFieldValue('F_AJAX', 'true');
            var url = document.location.href;
            var urlHashIndex = url.indexOf('#');
            if (urlHashIndex >= 0) {
                url = url.substring(0, urlHashIndex);
            }

            var viewStateBeforeAJAX = F.util.getHiddenFieldValue('__VIEWSTATE');
            var disabledButtonIdBeforeAJAX = F.getHidden('F_TARGET');

            function ajaxSuccess(data, viewStateBeforeAJAX) {
                /*
                try {
                    new Function(data)();
                } catch (e) {
                    createErrorWindow({
                        statusText: "Execute JavaScript Exception",
                        status: -1,
                        responseText: util.htmlEncode(data)
                    });
                }
                */

                function processEnd() {
                    // 启用AJAX发起时禁用的按钮
                    if (disabledButtonIdBeforeAJAX) {
                        F.enable(disabledButtonIdBeforeAJAX);
                    }

                    //隐藏正在加载提示
                    ajaxStop();
                }


                // 如果显式返回false，则阻止AJAX回发
                if (F.util.triggerBeforeAjaxSuccess(data) === false) {
                    processEnd();
                    return;
                }

                try {
                    new Function('__VIEWSTATE', data)(viewStateBeforeAJAX);

                    // 有可能响应返回后即关闭本窗体
                    if (F && F.util) {
                        F.util.triggerAjaxReady();
                    }
                } catch (e) {

                    // 重新抛出异常
                    throw e;

                } finally {

                    processEnd();
                }

            }

            ajaxStart();


            // 判断是否有文件上传
            var isFileUpload = !!Ext.get(theForm).query('input[type=file]').length;

            Ext.Ajax.request({
                form: theForm.id,
                url: url,
                isUpload: isFileUpload, //F.form_upload_file,
                //params: serializeForm(theForm) + '&X_AJAX=true',
                success: function (data) {
                    var scripts = data.responseText;

                    if (scripts && isFileUpload) {
                        // 文件上传时，输出内容经过encodeURIComponent编码（在ResponseFilter中的Close函数中）
                        //scripts = scripts.replace(/<\/?pre[^>]*>/ig, '');
                        scripts = decodeURIComponent(scripts);
                    }


                    // 因为这里调用后（可能会关闭当前页面），extjs还有代码要执行（Ext.callback...），所以这里要延迟一下，等 extjs 代码执行完毕后再执行这里代码
                    window.setTimeout(function () {
                        ajaxSuccess(scripts, viewStateBeforeAJAX);
                        /*
                        if (scripts) {
                            if (F.form_upload_file) {
                                // 文件上传时，输出内容经过encodeURIComponent编码（在ResponseFilter中的Close函数中）
                                //scripts = scripts.replace(/<\/?pre[^>]*>/ig, '');
                                scripts = decodeURIComponent(scripts);
                            }


                            new Function(scripts)();
                            

                        }
                        // 有可能响应返回后即关闭本窗体
                        if (F && F.util) {
                            F.util.triggerAjaxReady();
                        }
                        */
                    }, 0);
                },
                failure: function (data) {
                    //var lastDisabledButtonId = F.util.getHiddenFieldValue('F_TARGET');
                    if (disabledButtonIdBeforeAJAX) {
                        F.enable(disabledButtonIdBeforeAJAX);
                    }
                    createErrorWindow(data);
                },
                callback: function (options, success, response) {
                    // AJAX结束时需要清空此字段，否则下一次的type=submit提交（ASP.NET回发方式之一）会被误认为是AJAX提交
                    if (F && F.util) {
                        F.util.setHiddenFieldValue('F_AJAX', 'false');
                    }
                }
            });
        }
    }


    // 如果启用 Ajax，则所有对 __doPostBack 的调用都会到这里来
    function f__doPostBack(eventTarget, eventArgument) {
        var enableAjax;
        if (typeof (eventTarget) === 'boolean') {
            enableAjax = eventTarget;
            eventTarget = eventArgument;
            eventArgument = arguments[2];
        }

        // 回发页面之前延时 100 毫秒，确保页面上的操作完成（比如选中复选框的动作）
        window.setTimeout(function () {
            
            // theForm variable will always exist, because we invoke the GetPostBackEventReference in PageManager.
            if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
                theForm.__EVENTTARGET.value = eventTarget;
                theForm.__EVENTARGUMENT.value = eventArgument;

                // 设置当前请求是否为AJAX请求
                if (typeof (enableAjax) === 'boolean') {
                    F.controlEnableAjax = enableAjax;
                }

                f__doPostBack_internal();
            }
        }, 100);
    }


    function writeContentToIFrame(iframe, content) {
        // http://stackoverflow.com/questions/1477547/getelementbyid-contentdocument-error-in-ie
        // contentWindow is always there.
        if (iframe) {
            var doc = iframe.contentWindow.document;
            if (doc) {
                doc.open();
                doc.write(content);
                doc.close();
            }
        }
    }

    // 创建出错窗口
    function createErrorWindow(data) {
        // 如果是请求超时错误，则弹出简单提醒对话框
        if (data.isTimeout) {
            F.util.alert(F.ajax.timeoutErrorMsg);
            return;
        }

        // 如果响应正文为空，则弹出简单提醒对话框
        if (!data.responseText) {
            F.util.alert(Ext.String.format(F.ajax.errorMsg, data.statusText, data.status));
            return;
        }

        if (!F.ajax.errorWindow) {
            F.ajax.errorWindow = Ext.create('Ext.window.Window', {
                id: "FINEUI_ERROR",
                renderTo: window.body,
                width: 550,
                height: 350,
                border: true,
                animCollapse: true,
                collapsible: false,
                collapsed: false,
                closeAction: "hide",
                plain: false,
                modal: true,
                draggable: true,
                minimizable: false,
                minHeight: 100,
                minWidth: 200,
                resizable: true,
                maximizable: true,
                closable: true
            });
        }

        F.ajax.errorWindow.show();
        F.ajax.errorWindow.body.dom.innerHTML = F.wnd.createIFrameHtml('about:blank', 'FINEUI_ERROR');
        F.ajax.errorWindow.setTitle(Ext.String.format(F.ajax.errorMsg, data.statusText, data.status));
        writeContentToIFrame(F.ajax.errorWindow.body.query('iframe')[0], data.responseText);
    }

    // 序列化表单为 URL 编码字符串，除去 <input type="submit" /> 的按钮
    var extjsSerializeForm = Ext.Element.serializeForm;
    Ext.Element.serializeForm = function (form) {
        var el, originalStr = extjsSerializeForm(form);
        for (var i = 0; i < form.elements.length; i++) {
            el = form.elements[i];
            if (el.type === 'submit') {
                var submitStr = encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
                if (originalStr.indexOf(submitStr) == 0) {
                    originalStr = originalStr.replace(submitStr, '');
                } else {
                    originalStr = originalStr.replace('&' + submitStr, '');
                }
            }
        }
        return originalStr;
    };


    function getFState() {
        var state = {};
        Ext.ComponentManager.each(function (key, cmp) {
            if (cmp.isXType) {
                // f_props store the properties which has been changed on server-side or client-side.
                // Every FineUI control should has this property.
                var fstate = cmp['f_state'];
                if (fstate && Ext.isObject(fstate)) {
                    var cmpState = getFStateViaCmp(cmp, fstate);
                    if (!F.util.isObjectEmpty(cmpState)) {
                        state[cmp.id] = cmpState;
                    }
                }
            }
        });
        return state;
    }

    F.ajax.getFState = getFState;

    function getFStateViaCmp(cmp, fstate) {
        var state = {};

        Ext.apply(state, fstate);

        function saveInHiddenField(property, currentValue) {
            // Save this client-changed property in a form hidden field. 
            F.util.setHiddenFieldValue(cmp.id + '_' + property, currentValue);
        }
        function removeHiddenField(property) {
            F.util.removeHiddenField(cmp.id + '_' + property);
        }

        // 如果存在Gzip压缩的属性，就删除原来的属性
        function resolveGZProperty(property) {
            var gzProperty = property + '_GZ';
            if (state[gzProperty]) {
                delete state[property];
            } else {
                delete state[gzProperty];
            }
        }



        // 有些属性可以在客户端改变，因此需要在每个请求之前计算
        if (cmp.isXType('menucheckitem')) {
            saveInHiddenField('Checked', cmp.checked);
        }

        if (cmp.isXType('checkbox')) {
            // 包含RadioButton
            saveInHiddenField('Checked', cmp.getValue());
        }

        if (cmp.isXType('checkboxgroup')) {
            var selected = cmp.f_getSelectedValues();
            if (selected.length > 0) {
                saveInHiddenField('SelectedValueArray', selected.join(','));
            } else {
                removeHiddenField('SelectedValueArray');
            }
        }

        if (cmp.isXType('panel') || cmp.isXType('fieldset')) {
            saveInHiddenField('Collapsed', cmp.f_isCollapsed());
        }

        if (cmp.isXType('datepicker')) {
            saveInHiddenField('SelectedDate', Ext.Date.format(cmp.getValue(), cmp.initialConfig.format));
        }

        if (cmp.isXType('button')) {
            if (cmp.initialConfig.enableToggle) {
                saveInHiddenField('Pressed', cmp.pressed);
            }
        }

        if (cmp.isXType('grid')) {

            //if (cmp.getPlugin(cmp.id + '_celledit')) {
            if(cmp.f_cellEditing) {
                // 可编辑单元格的表格
                // 选中单元格
                //saveInHiddenField('SelectedCell', cmp.f_getSelectedCell().join(','));
				
				 // 选中单元格
				var selectedCell = cmp.f_getSelectedCell();
				if (selectedCell && selectedCell.length) {
					saveInHiddenField('SelectedCell', JSON.stringify(selectedCell));
				} else {
					removeHiddenField('SelectedCell');
				}

                //// 新增行
                //var newAddedRows = cmp.f_getNewAddedRows();
                //if (newAddedRows.length > 0) {
                //    saveInHiddenField('NewAddedRows', newAddedRows.join(','));
                //} else {
                //    removeHiddenField('NewAddedRows');
                //}

                // 修改的数据
                var modifiedData = cmp.f_getModifiedData();
                if (modifiedData.length > 0) {
                    saveInHiddenField('ModifiedData', Ext.encode(modifiedData));
                } else {
                    removeHiddenField('ModifiedData');
                }

                /*
                // 删除的行索引列表
                var deletedRows = cmp.f_getDeletedRows();
                if (deletedRows.length > 0) {
                    saveInHiddenField('DeletedRows', deletedRows.join(','));
                } else {
                    removeHiddenField('DeletedRows');
                }
                */

            } else {
                // 普通的表格
                // 选中行索引列表
                //saveInHiddenField('SelectedRowIndexArray', cmp.f_getSelectedRows().join(','));
                // 选中行标识符列表
                var selectedRows = cmp.f_getSelectedRows();
                if (selectedRows && selectedRows.length) {
                    saveInHiddenField('SelectedRows', JSON.stringify(selectedRows));
                } else {
                    removeHiddenField('SelectedRows');
                }
            }


            // 隐藏的列索引列表
            var gridHiddenColumns = cmp.f_getHiddenColumns();
            if (gridHiddenColumns.length > 0) {
                saveInHiddenField('HiddenColumns', gridHiddenColumns.join(','));
            } else {
                removeHiddenField('HiddenColumns');
            }

            // 目前States仅用于CheckBoxField
            var gridStates = cmp.f_getStates();
            if (gridStates.length > 0) {
                saveInHiddenField('States', Ext.encode(gridStates));
            } else {
                removeHiddenField('States');
            }

            // 如果存在 GZIPPED 的属性，就用 GZIPPED 属性
            resolveGZProperty('F_Rows');
        }

        if (cmp.isXType('combo') || cmp.isXType('checkboxgroup') || cmp.isXType('radiogroup')) {

            // 如果存在 GZIPPED 的属性，就用 GZIPPED 属性
            resolveGZProperty('F_Items');
        }

        if (cmp.isXType('field')) {

            // 如果存在 GZIPPED 的属性，就用 GZIPPED 属性
            resolveGZProperty('Text');
        }

        if (cmp.isXType('treepanel')) {
            saveInHiddenField('ExpandedNodes', cmp.f_getExpandedNodes(cmp.getRootNode().childNodes).join(','));
            saveInHiddenField('CheckedNodes', cmp.f_getCheckedNodes().join(','));
            saveInHiddenField('SelectedNodeIDArray', cmp.f_getSelectedNodes().join(','));

            // 如果存在 GZIPPED 的属性，就用 GZIPPED 属性
            resolveGZProperty('F_Nodes');
        }

        if (cmp.isXType('tabpanel')) {
            saveInHiddenField('ActiveTabIndex', cmp.f_getActiveTabIndex());
        }

        if (cmp.isXType('panel') && cmp.getLayout().type === 'accordion') {
            saveInHiddenField('ActivePaneIndex', cmp.f_getActiveIndex());
        }

        if (cmp['f_type'] && cmp['f_type'] === 'tab') {
            saveInHiddenField('Hidden', cmp.tab.isHidden());
        }

        return state;
    }



    // 显示“正在载入...”的提示信息
    function _showAjaxLoading(ajaxLoadingType) {
        // 延迟后，要再次检查当前有 AJAX 正在进行，才显示提示信息
        if (__ajaxUnderwayCount > 0) {

            if (ajaxLoadingType === "default") {
                F.ajaxLoadingDefault.setStyle('left', (Ext.getBody().getWidth() - F.ajaxLoadingDefault.getWidth()) / 2 + 'px');
                F.ajaxLoadingDefault.show();
            } else {
                F.ajaxLoadingMask.show();
            }

        }
    }

    // 隐藏“正在载入...”的提示信息
    function _hideAjaxLoading(ajaxLoadingType) {
        if (__ajaxUnderwayCount === 0) {

            if (ajaxLoadingType === "default") {
                F.ajaxLoadingDefault.hide();
            } else {
                F.ajaxLoadingMask.hide();
            }

        }
    }

    function ajaxStart() {

        // 计数加一
        __ajaxUnderwayCount++;

        // 仅在第一个 AJAX 发起时，延迟显示提示信息
        if (__ajaxUnderwayCount !== 1) {
            return;
        }

        if (!enableAjaxLoading()) {
            // Do nothing
        } else {
            Ext.defer(_showAjaxLoading, 50, window, [ajaxLoadingType()]);
        }

    }

    function ajaxStop() {
        // 计数减一
        __ajaxUnderwayCount--;
        if (__ajaxUnderwayCount < 0) {
            __ajaxUnderwayCount = 0;
        }

        if (!enableAjaxLoading()) {
            // ...
        } else {
           Ext.defer(_hideAjaxLoading, 0, window, [ajaxLoadingType()]);
        }

        if (__ajaxUnderwayCount === 0) {
            F.controlEnableAjaxLoading = undefined;
            F.controlAjaxLoadingType = undefined;
        }
    }

    /*
    // 当前 Ajax 的并发请求数
    //var _requestCount = 0;
    var _ajaxStarted = false;

    // 发起 Ajax 请求之前事件处理
    Ext.Ajax.on('beforerequest', function (conn, options) {
        //_requestCount++;

        _ajaxStarted = true;
        ajaxStart();
    });

    // Ajax 请求结束
    Ext.Ajax.on('requestcomplete', function (conn, options) {
        //_requestCount--;
        _ajaxStarted = false;
        
    });

    // Ajax 请求发生异常
    Ext.Ajax.on('requestexception', function (conn, options) {
        //_requestCount--;
        _ajaxStarted = false;
        

    });
    */





    //        // 不适用于所有Extjs控件（比如Toolbar中放置按钮，这个按钮就没有ownerCt对象）
    //        // 更新一个Javascript对象
    //        updateObject: function(obj, newObjFunction, renderImmediately) {
    //            var id = obj.id;
    //            if (Ext.type(renderImmediately) == 'boolean' && !renderImmediately) {

    //                // 1.取得父容器
    //                var owner = obj.ownerCt;
    //                // 2.本控件在父容器的位置
    //                var insertIndex = owner.items.indexOf(obj);
    //                // 3.从父容器中销毁此控件
    //                owner.remove(obj);
    //                // 4.创建新的控件
    //                newObjFunction();
    //                // 5.将新的控件添加到删除的位置
    //                owner.insert(insertIndex, Ext.getCmp(id));
    //                // 6.父容器重新布局
    //                owner.doLayout();

    //            }
    //            else {

    //                // 1.销毁此控件
    //                obj.destroy();
    //                // 2.新建此控件
    //                newObjFunction();
    //            }
    //        }

})();