;
(function ($) {
    var otherButton = [];
    var d = $("<div style='position:absolute;top:-1000px;width:100px;height:100px;padding:5px'></div>").appendTo("body");
    $._boxModel = parseInt(d.width()) === 100;
    d.remove();

    $.fn._outerWidth = function (el) {
        if (el == undefined) {
            if (this[0] == window) {
                return this.width() || document.body.clientWidth;
            }
            return this.outerWidth() || 0;
        }
        return this.each(function () {
            if ($._boxModel) {
                $(this).width(el - ($(this).outerWidth() - $(this).width()));
            } else {
                $(this).width(el);
            }
        });
    };
    $.fn._outerHeight = function (el) {
        if (el == undefined) {
            if (this[0] == window) {
                return this.height() || document.body.clientHeight;
            }
            return this.outerHeight() || 0;
        }
        return this.each(function () {
            if ($._boxModel) {
                $(this).height(el - ($(this).outerHeight() - $(this).height()));
            } else {
                $(this).height(el);
            }
        });
    };
    /**
     * 面板容器
     *
     *     @example
     *     var $root = $("<div>").css({position:'absolute',top:5,left:10}).appendTo('body');
     *     var p = new FR.Panel({
     *          renderEl : $root,
     *          contentHtml : "Hello",
     *          width : 300,
     *          height : 100,
     *          title : "Test",
     *          border : true,
     *          doSize : true,
     *          closable : true
     *     });
     *
     * @class FR.Panel
     * @extends FR.Widget
     * @since 6.5.3
     *
     * @cfg {JSON} options 配置属性
     * @cfg {Number} [options.titleHeight=25] 标题高度(如果有标题)
     * @cfg {String} [options.headerBackground=null] 标题背景色
     * @cfg {Number/String} [options.borderRadius=false] 边框的圆角
     * @cfg {Boolean} [options.fit=false] 是否根据父容器自适应大小
     * @cfg {Boolean} [options.doSize=true] 是否需要在初始化的时候计算大小
     * @cfg {Boolean} [options.border=false] 是否需要边框
     * @cfg {Number} [options.borderWidth=1] 边框宽度,仅在border=true时生效。
     * @cfg {Boolean} [options.closable=false] 是否需要关闭按钮
     * @cfg {Boolean} [options.maximizable=false] 是否可以最大化
     * @cfg {Boolean} [options.minimizable=false] 是否可以最小化
     * @cfg {Boolean} [options.collapsible=false] 是否可以收缩和下拉
     * @cfg {Boolean} [options.autoScroll=true] 是否根据内容的多少自动显示滚动条
     * @cfg {Boolean} [options.closed=false] 初始化完成以后是否直接显示组件
     * @cfg {Boolean/Number} [options.animate=true] 显示和隐藏的时候是否需要动画效果,参数可以为一个整数表示动画持续的时间
     * @cfg {Number} [options.width=300] 控件的初始宽度
     * @cfg {Number} [options.height=200] 控件的初始高度
     * @cfg {String} [options.contentUrl=null] 容器内容(从给定的服务器地址获取。注意:该url不能跨域)
     * @cfg {String} [options.contentHtml=null] 容器内容(html文本)
     * @cfg {String} [options.contentText=null] 容器内容(普通文本)
     * @cfg {FR.Widget} [options.contentWidget=null] 容器内容(控件)
     * @cfg {"blue"/"green"/"gray"} [options.style="blue"] 控件的样式
     * @cfg {Array} [options.tools] 控件的工具栏按钮组,可以设置按钮的样式,宽度以及事件
     * @cfg {Number} [options.tools.width=24] 按钮的宽度
     * @cfg {String} options.tools.iconCls 按钮的css样式表
     * @cfg {Boolean} [options.tools.invisible=false] 按钮的不可见性
     * @cfg {String} options.tools.text 按钮上的文字
     * @cfg {Function} options.tools.handler 按钮点击时触发的事件
     */
    FR.Panel = FR.extend(FR.Widget, {

        _defaultConfig: function () {
            return $.extend(FR.Panel.superclass._defaultConfig.apply(this, arguments), {
                baseCls: "fr-core-panel",  // 基本样式
                titleHeight: 25,          // 标题栏的高度
                headerBackground: null,
                borderRadius: false,          // 边框的圆角
                fit: false,                // 是否根据父容器自适应大小
                doSize: true,             // 是否需要再初始化的时候计算大小
                border: false,             // 是否需要边框
                borderWidth: 1,            // 边框宽度
                closable: false,           // 是否需要关闭按钮
                maximizable: false,        // 是否可以最大化
                minimizable: false,        // 是否可以最小化
                collapsible: false,        // 是否可以收缩和下拉
                autoScroll: true,          // 是否根据内容的多少自动显示滚动条
                closed: false,             // 初始化完成以后是否直接显示组件
                animate: true,            // 显示和隐藏的时候是否需要动画效果,参数可以为一个整数表示动画持续的时间
                width: 300,                // 控件的初始宽度
                height: 200,               // 控件的初始高度
                tools: null,              // 控件的工具栏按钮,可以设置按钮的样式,宽度以及事件
                style: null               // 控件的样式,默认为blue,具有blue,green以及gray共3种样式
            });
        },
        _init: function () {
            var o = this.options;
            this.headerHeight = (!FR.isEmpty(o.title)) ? o.titleHeight : (o.miniExpand ? 8 : 0);
            // wei : 如果panel有可收缩的工具栏,那么先调整下它的高度。
            // 这里得考虑下传过来的o.height是不是"auto"或者百分比
            if (typeof o.height == 'number') {
                o.height += (!FR.isEmpty(o.title)) ? o.titleHeight : 0;
            }
            FR.Panel.superclass._init.apply(this, arguments);
            var self = this;
            var defaultStyle = "blue";
            $.each(["gray", "green", "blue"], function (i, item) {
                if (o.style && item == o.style.toLowerCase()) {
                    defaultStyle = o.style.toLowerCase();
                }
            });
            o.style = defaultStyle;
            this.element.addClass(o.baseCls);
            // 注意,这里需要先调用_addContent(),再调用_addHeader()方法
            this._addContent();
            if ((typeof o.height == 'number' && o.height > this.headerHeight) || typeof o.height != 'number') {
                this._addHeader();
            }
            this._addBorder();
            // 注意:必须要先doResize才能关闭,否则无法正确计算宽度和高度
            if (o.doSize === true) {
                this.doResize({
                    width: o.width,
                    height: o.height
                });
            }
            if (o.closed === true) {
                this.element.hide();
            }
            if (o.css) {
                this.element.css(o.css);
            }
            this.on("_resize", function () {
                if (self.options._resize) {
                    self.options._resize();
                }
            })
        },
        /**
         * autoScroll:是否显示panel内容的滚动条 url:数据加载有地址 html:包含html标签的内容 text:普通文本内容
         * url,html和text三种数据获取方式只能选一种
         * @private
         */
        _addContent: function () {
            var opts = this.options;
            // 先给panel的content套一层标识
            var top = FR.isEmpty(opts.title) ? 0 : opts.titleHeight;

            /**
             * @property {jQuery} panelBody 容器内容所在的dom
             */
            this.panelBody = $('<div class="fr-core-panel-body"></div>').css({
                position: 'absolute',
                top: top,
                left: 0
            }).appendTo(this.element);

            /**
             * @property {jQuery} $contentPane 容器内容所在的dom
             */
            this.$contentPane = this._createContentPane();

            this._loadContent(false);
        },

        /**
         * @private
         */
        _createContentPane: function () {
            if (this.options.autoScroll === false) {
                this.panelBody.css({
                    overflow: 'hidden'
                });
            }
            return this.panelBody;
        },

        /**
         * @private
         */
        _addBorder: function () {
            var o = this.options;
            if (o.border === true) {
                // 如果没有标题,那么样式也就没有意义了,所以这里不用加载css,只在有标题的时候加载css
                if (this.$header) {
                    /**
                     * @property {jQuery} $header 标题所在的dom元素
                     */
                    this.$header.removeClass('fr-core-panel-header-noborder');
                }
                this.borderFix4width = o.borderWidth * 2;
                this.borderFix4height = o.borderWidth * 2;
                this.panelBody
                    .addClass("fr-core-panel-body-border")
                    .removeClass('fr-core-panel-body-noborder')
                    .css({borderWidth: o.borderWidth});
                if (!FR.isEmpty(o.title)) {
                    this.borderFix4height = o.borderWidth;
                    this.panelBody.css({
                        borderTop: 'none'
                    });
                }
            } else {
                if (this.$header) {
                    this.$header
                        .addClass('fr-core-panel-header-noborder');
                }
                this.panelBody
                    .removeClass('fr-core-panel-body-border')
                    .addClass('fr-core-panel-body-noborder');
            }
        },
        _loadContent: function (forced) {
            var opts = this.options;
            var ct = this.$contentPane;
            // url不为空,需要强制加载或者还没有加载过时使用ajax异步加载内容
            if (opts.contentUrl && (!opts.isLoaded || forced === true)) {
                opts.isLoaded = false;
                ct.html($('<div class="fr-core-panel-loading"></div>')
                    .html("loading..."));
                FR.ajax({
                    url: opts.contentUrl,
                    type: "POST",
                    complete: function (res, status) {
                        var ht = res.responseText;

                        if ($.isFunction(opts.callback)) {
                            opts.callback(ct, ht);
                        } else {
                            ct.html(ht);
                        }
                        opts.isLoaded = true;
                    }
                });
            } else if (opts.contentWidget) {
                if (opts.contentWidget.type) {
                    opts.contentWidget.style = opts.style;
                    opts.contentWidget = FR.createWidget(opts.contentWidget);
                }
                $.extend(opts.resultWidgets, opts.contentWidget.options.resultWidgets);
                ct.append(opts.contentWidget.element);
            } else if (opts.contentHtml) {
                ct.html(opts.contentHtml);
                if (typeof opts.contentHtml === 'object') {
                    var newEl = $(opts.contentHtml)[0];
                    //wikky:$(newEl)如果hide后然后show,由于$loading的原因,会导致IE9的标准模式下$(newEl)大小为100*100。
                    if (newEl.tagName == 'IFRAME') {
//                        $(newEl).hide();
                        var topHeight = FR.isEmpty(opts.title) ? 0 : opts.titleHeight;
                        var loadTop = topHeight - opts.height;
                        var $loading = $('<div class="fr-core-panel-loading" style="position: relative"></div>')
                            .css({
                                width: opts.width,
                                height: 30,
                                top: loadTop
                            }).html(FR.i18nText("FR-Basic_Loading") + "...");
                        if (!opts.noLoading) {
                            ct.append($loading);
                        }
                        if (newEl.attachEvent) {
                            newEl.attachEvent("onload", function () {
//                                $(newEl).show();
                                $loading.remove();
                            });
                        } else {
                            newEl.onload = function () {
//                                $(newEl).show();
                                $loading.remove();
                            };
                        }
                    }
                }
            } else if (opts.contentText) {
                ct.text(opts.contentText);
            }
        },

        /**
         * title : 标题 tools : 自定义的工具栏 closable : 是否可关闭 maximizable : 是否可最大化
         * minimizable :是否可最小化 collapsible : 是否可收缩与伸展 miniExpand : 只带箭头的收缩按钮
         * @private
         */
        _addHeader: function () {
            var self = this;
            var opts = this.options;
            if (!FR.isEmpty(opts.title)) {
                this.$header = $('<div class="fr-core-panel-header"></div>')
                    .addClass("fr-core-panel-style-" + opts.style)
                    .css({
                        position: 'absolute',
                        top: 0,
                        left: 0
                    }).appendTo(this.element);
                if (!opts.borderRadius) {
                    this.$header.css({borderRadius: 0});
                }
                if (opts.headerBackground) {
                    this.$header.css({background: opts.headerBackground});
                }
                var fix = $.support.boxModel ? 2 : 0;
                this.$innerHeader = $('<div class="fr-core-panel-header-inner"></div>').css({
                    position: 'absolute',
                    top: 0,
                    left: 0
                }).appendTo(this.$header);
                this.$titleText = $('<div></div>')
                    .text(opts.title)
                    .addClass('fr-core-panel-title')
                    .appendTo(this.$innerHeader);
                this.rightDistance = 7;
                if (opts.closable) {
                    $('<div class="fr-core-panel-tool-close"></div>')
                        .css({
                            position: 'absolute',
                            top: 0,
                            right: this.rightDistance,
                            width: 25,
                            height: opts.titleHeight - fix
                        })
                        .mouseout(function () {
                            $(this).removeClass("fr-core-panel-tool-close-hover")
                                .removeClass("fr-core-panel-tool-close-down")
                                .removeClass("fr-core-panel-tool-over")
                                .addClass("fr-core-panel-tool-close");
                        }).mousedown(function (e) {
                            //Sean:这里要取消冒泡,否则点击关闭按钮时会触发拖动。
                            //wei:没什么影响,就不取消冒泡了,不然定义在document上的下拉菜单收起事件就不执行了。
                            $(this).removeClass("fr-core-panel-tool-close-hover")
                                .addClass("fr-core-panel-tool-close-down");
//                            e.stopEvent();
                        }).mouseover(function () {
                            $(this).removeClass("fr-core-panel-tool-close")
                                .addClass("fr-core-panel-tool-over")
                                .addClass("fr-core-panel-tool-close-hover");
                        }).bind("click", function () {
                            self.doClose();
                        }).appendTo(this.$innerHeader);
                    this.rightDistance += 24;
                }

                if (opts.tools) {
                    for (var i = opts.tools.length - 1; i >= 0; i--) {
                        var item = opts.tools[i];
                        var itemWidth = item.width || 24,
                            itemHeight = item.height || opts.titleHeight - fix;
                        var t = $('<div></div>').css({
                            position: 'absolute',
                            top: 0,
                            width: itemWidth,
                            height: itemHeight,
                            lineHeight: itemHeight + 'px'
                        }).addClass(item.iconCls).hover(function () {
                            $(this).addClass("fr-core-panel-tool-over");
                            $(this).addClass(item.iconCls + "-over");
                        }, function () {
                            $(this).removeClass("fr-core-panel-tool-over");
                            $(this).removeClass(item.iconCls + "-over");
                        }).mousedown(function () {
                            $(this).addClass(item.iconCls + '-click');
                        }).mouseleave(function () {
                            $(this).removeClass(item.iconCls + '-over');
                            $(this).removeClass(item.iconCls + '-click');
                        }).mouseup(function () {
                            $(this).removeClass(item.iconCls + '-click');
                        })
                            .appendTo(this.$innerHeader);
                        item.el = t;
                        item.width = itemWidth;
                        if (item.invisible) {
                            t.hide();
                        }
                        if (item.handler) {
                            if ($.isFunction(item.handler)) {
                                t.bind('click', item.handler.createDelegate(t));
                            } else if (typeof(item.handler) === 'object') {
                                //扩展成可以将click动作拆分成3个动作,这样可以满足实现tool的点击效果。
                                if ($.isFunction(item.handler.mousedown)) {
                                    t.mousedown(item.handler.mousedown.createDelegate(t));
                                }
                                if ($.isFunction(item.handler.mouseleave)) {
                                    t.mouseleave(item.handler.mouseleave.createDelegate(t));
                                }
                                if ($.isFunction(item.handler.mouseup)) {
                                    t.mouseup(item.handler.mouseup.createDelegate(t));
                                }
                            } else {
                                t.bind('click', eval(item.handler));
                            }
                        }
                        if ($.isArray(item.hover) && item.hover.length > 1) {
                            t.hover(item.hover[0].createDelegate(t), item.hover[1].createDelegate(t));
                        }
                        if (item.text) {
                            t.text(item.text);
                        }
                        if (item.styleText) {
                            FR.applyStyles(t, item.styleText);
                        }

                    }
                    this._modifyToolsPosition();
                }
                this.panelBody.removeClass('fr-core-panel-body-noheader');
            } else if (opts.miniExpand) {
                var header = $("<div class='parameter-container-collapse'></div>")
                    .appendTo(self.element);
                header.css({
                    position: 'absolute',
                    top: opts.height - 8,
                    left: 0,
                    'width': '100%',
                    'height': '8px',
                    'background': 'none repeat scroll 0 0 #EEEEEE'
                });
                var collapseImagWrapper = $("<div/>").css({
                    width: '112px',
                    height: '8px',
                    'margin-left': 'auto',
                    'margin-right': 'auto',
                    'position': 'relative'
                }).appendTo(header);
                var collapseImag = $("<div class='parameter-container-collapseimg-up'/>")
                    .appendTo(collapseImagWrapper)
                    .click(eval(opts.miniExpand.handler));
            } else {
                this.panelBody.addClass('fr-core-panel-body-noheader');
            }
        },

        /**
         * 设置面板容器的标题
         * @param {String} title 要设置的新的标题
         */
        setTitle: function (title) {
            if (this.$innerHeader) {
                this.$innerHeader.find(">div.fr-core-panel-title")
                    .html(title);
            }
        },
        /**
         * 设置指定的工具栏按钮的可见性
         * @param {Number} index 要设置的按钮的索引
         * @param {Boolean} visible 是否设置为可见
         */
        setToolVisible: function (index, visible) {
            var opts = this.options;
            var ct = opts.tools[index];
            if (ct && ct.el && ct.el.isVisible() != visible) {
                visible ? ct.el.show() : ct.el.hide();
                this._modifyToolsPosition();
            }
        },

        _modifyToolsPosition: function () {
            var rd = this.rightDistance, opts = this.options;
            for (var i = opts.tools.length - 1; i >= 0; i--) {
                var item = opts.tools[i];
                if (item.el && item.el.isVisible()) {
                    item.el.css({right: rd});
                    rd += item.width;
                }
            }
        },

        /**
         * 展示面板
         */
        doOpen: function () {
            this.element.show();
            this.options.closed = false;
            if ($.isFunction(this.options.onOpen)) {
                this.options.onOpen.call(this);
            }
        },
        /**
         * 关闭面板
         */
        doClose: function () {
            var self = this;
            this.element.hide(self.options.animate ? "fast" : 0, function () {
                self.options.closed = true;
                if ($.isFunction(self.options.onClose)) {
                    self.options.onClose.call(self);
                }
            });
        },
        /**
         * 面板新的位置
         * @param {Point} give 要移动到的新的位置
         * @param {Number} give.left 新位置距离父容器的左边距
         * @param {Number} give.top 新位置距离父容器的上边距
         */
        doMove: function (give) {
            var opts = this.options;
            if (give) {
                if (give.left != null) {
                    opts.left = give.left;
                }
                if (give.top != null) {
                    opts.top = give.top;
                }
            }
            this.element.css({
                left: opts.left,
                top: opts.top
            });

            if ($.isFunction(opts.onMove)) {
                opts.onMove.apply(this, [opts.left, opts.top]);
            }
        },
        enable: function () {
            if (this.mask) {
                this.mask.hide();
            }
        },

        disable: function () {
            if (!this.mask) {
                this.mask = $("<div/>").addClass("fr-core-window-mask").appendTo(this.element);
                this.mask.css({
                    zIndex: FR.widget.opts.zIndex++,
                    width: this.element.width() ? this.element.width() : this.options.width,
                    height: this.element.height() ? this.element.height() : this.options.height,
                    background: 'gray'
                });
            }
            this.mask.show();
        },

        doResize: function (give) {
            var opts = this.options;
            var self = this;
            // 如果有给定的尺寸,那么久使用给定的尺寸大小
            if (give) {
                if (give.width) {
                    opts.width = give.width;
                }
                if (give.height) {
                    opts.height = give.height;
                }
                if (give.left != null) {
                    opts.left = give.left;
                }
                if (give.top != null) {
                    opts.top = give.top;
                }
            }
            // 如果是自适应大小的,那么就根据父元素的大小的确定panel的大小
            if (opts.fit === true) {
                var p = this.element.parent();
                opts.width = p.width();
                opts.height = p.height();
            }
            this.element.css({
                left: opts.left,
                top: opts.top
            });
            if (opts.cls) {
                this.element.addClass(opts.cls);
            }
            if (this.$header && opts.headerCls) {
                this.$header.addClass(opts.headerCls);
            }
            if (opts.bodyCls) {
                this.panelBody.addClass(opts.bodyCls);
            }
            if (!isNaN(opts.width)) {
                if ($.support.boxModel === true) {
                    var panelWidth = opts.width - (this.element.outerWidth() - this.element.width());
                    this.element.width(panelWidth);
                    if (!FR.isEmpty(opts.title) && this.$header) {
                        this.$header.width(panelWidth - (this.$header.outerWidth() - this.$header.width()));
                        this.$innerHeader.width(panelWidth - (this.$header.outerWidth() - this.$header.width()));
                    }
                    this.panelBody.width(panelWidth - (this.panelBody.outerWidth() - this.panelBody.width()));
                } else {
                    this.element.width(opts.width);
                    if (!FR.isEmpty(opts.title) && this.$header) {
                        this.$header.width(opts.width);
                        this.$innerHeader.width(opts.width);
                    }
                    this.panelBody.width(opts.width - this.borderFix4width);
                }
            } else {
                this.element.width('auto');
                this.panelBody.width('auto');
            }
            if (!isNaN(opts.height)) {
                if ($.support.boxModel === true) {
                    var panelHeight = opts.height - (this.element.outerHeight() - this.element.height());
                    this.element.height(panelHeight);
                    if (!FR.isEmpty(opts.title) && this.$header) {
                        this.$header.height(this.headerHeight - (this.$header.outerHeight() - this.$header.height()));
                        this.$innerHeader.height(this.headerHeight - (this.$header.outerHeight() - this.$header.height()));
                        this.$titleText.css({lineHeight: this.headerHeight - (this.$header.outerHeight() - this.$header.height()) + "px"});
                    }
                    this.panelBody.height(panelHeight - this.headerHeight - (this.panelBody.outerHeight() - this.panelBody.height()));
                } else {
                    this.element.height(opts.height);
                    if (!FR.isEmpty(opts.title) && this.$header) {
                        this.$header.height(this.headerHeight);
                        this.$innerHeader.height(this.headerHeight);
                        this.$titleText.css({lineHeight: this.headerHeight + "px"});
                    }
                    this.panelBody.height(opts.height - this.headerHeight - this.borderFix4height);
                }
            } else {
                this.element.height('auto');
                this.$contentPane.height('auto');
            }
            if ($.isFunction(opts.onResize)) {
                opts.onResize.apply(this, [opts.width, opts.height]);
            }
            this._resizeContentWidget();
            // 触发panel的resize事件
            this.fireEvent(FR.Events.RESIZE);
            this.element.doLayout();
        },
        /**
         * @protected
         */
        _resizeContentWidget: function () {
            var opts = this.options;
            // alex:不知道为什么IE下面也要用这样的方式才可以取到height,但width却不需要用这种方式
            //wei : 宽度也会出问题..
            var pbodystylestring = this.$contentPane.attr("style");
            var pbodyheight = parseInt(pbodystylestring.replace(
                /.*height\:\s*(\d+).*/gi, "$1"));
            // ie6下iframeDialog时,iframe标签取宽度会受border-left-width等影响
            var pbodywidth = parseInt(pbodystylestring.replace(
                /.* width\:\s*(\d+).*/gi, "$1"));

            if (opts.contentWidget) {
                opts.contentWidget.doResize({
                    width: this.$contentPane.width(),
                    height: pbodyheight
                });
            } else if (opts.contentHtml && FR.Browser.isIE6()) {
                $(opts.contentHtml).css({
                    width: pbodywidth,
                    height: pbodyheight
                });
            }
        }
    });
    $.shortcut("panel", FR.Panel);

    /**
     * 带“确定”以及“取消”按钮的容器
     *
     *     @example
     *     var $root = $("<div>").css({position:'absolute',top:10,left:10}).appendTo('body');
     *     var editor = new FR.ConfirmPane({
     *               renderEl:$root,
     *               title: "ConfirmPane",
     *               width : 250,
     *               closable:true,
     *               height : 100,
     *               doSize:true,
     *               border:true,
     *     });
     *
     * @class FR.ConfirmPane
     * @extends FR.Panel
     * @since 7.0.5
     *
     * @cfg {JSON} options 配置属性
     * @cfg {String} [options.text4OK="确定"] “确定”按钮的文字
     * @cfg {String} [options.text4Cancel="取消"] “取消”按钮的文字
     * @cfg {Number} [options.width4OK=80] “确定”按钮的宽度
     * @cfg {Number} [options.width4Cancel=80] “取消”按钮的宽度
     * @cfg {Number} [options.height4OK=28] “确定”按钮的高度
     * @cfg {Number} [options.height4Cancel=80] “取消”按钮的高度
     * @cfg {Number} [options.controlPaneHeight=40] “确定”和“取消”按钮所在的区域的高度
     * @cfg {Number} [options.btnsGap=20] “确定”和“取消”按钮之间的距离
     * @cfg {Number} [options.firstBtnMargin=20] 第一个按钮与panel边界的距离,居左就是firstBtn为左边按钮,居右firstBtn为右边按钮
     * @cfg {Boolean/Number} [options.needSeparate=false] 是否显示分割线, 直接写分割线距离底下按钮的高度
     * @cfg {'right'/'left'/'center'} [options.btnsAlignment='right'] 按钮位置,默认在右边,右对齐时新添按钮从右向左添加,其他是从左向右添加
     * @cfg {Boolean} [options.closeAfterAction=true] 是否点击按钮事件结束后关闭Panel,默认关闭
     * @cfg {Function} [options.onOK] "确定"按钮点击事件
     * @cfg {Function} [options.onCancel] "取消"按钮点击事件
     */
    FR.ConfirmPane = FR.extend(FR.Panel, /**@class FR.ConfirmPane */{
        _defaultConfig: function () {
            return $.extend(FR.ConfirmPane.superclass._defaultConfig.apply(this, arguments), {
                text4OK: FR.i18nText("FR-Basic_OK"),
                text4Cancel: FR.i18nText("FR-Basic_Cancel"),
                width4OK: 80,
                width4Cancel: 80,
                height4OK: 28,
                height4Cancel: 28,
                controlPaneHeight: 40,
                btnsGap: 20,
                firstBtnMargin: 20,
                needSeparate: false,
                btnsAlignment: 'right',
                closeAfterAction: true,
                onOK: null,
                onCancel: null
            });
        },
        _init: function () {
            FR.ConfirmPane.superclass._init.apply(this, arguments);
        },

        _createContentPane: function () {
            var opts = this.options;
            var $contentPane = $('<div class="fr-core-panel-content">').css({
                position: 'absolute',
                top: 0,
                left: 0
            }).appendTo(this.panelBody);
            var self = this;
            //Sean: 为了兼容IE6必须再套一层
            this.okdiv = $('<div style="position:absolute"/>').appendTo(this.panelBody);
            this.canceldiv = $('<div style="position:absolute"/>').appendTo(this.panelBody);
            if (!FR.isEmpty(opts.text4OK)) {
                /**
                 * @property {FR.Widget} okButton “确定”按钮
                 */
                self.okButton = new FR.createWidget({
                    type: 'quickbutton',
                    text: opts.text4OK,
                    width: opts.width4OK,
                    height: opts.height4OK,
                    style: opts.style,
                    handler: function () {
                        if ($.isFunction(self.options.onOK)) {
                            var result = self.options.onOK.apply(self);
                            if (result === false) {
                                //不关闭对话框
                                return;
                            }
                        }
                        if (self.options.closeAfterAction) {
                            self.doClose();
                        }
                    }
                });
                this.okButton.element.appendTo(this.okdiv);
                this.okdiv.css({width: opts.width4OK, height: opts.height4OK});
            }

            if (!FR.isEmpty(opts.text4Cancel)) {
                /**
                 * @property {FR.Widget} cancelButton “取消”按钮
                 */
                self.cancelButton = new FR.createWidget({
                    type: 'quickbutton',
                    text: opts.text4Cancel,
                    //              style : opts.style, //Sean:取消按钮采用默认'gray'样式,不随主题样式变化
                    width: opts.width4Cancel,
                    height: opts.height4Cancel,
                    handler: function () {
                        if ($.isFunction(self.options.onCancel)) {
                            self.options.onCancel.apply(self);
                        }
                        if (self.options.closeAfterAction) {
                            self.doClose();
                        }
                    }
                });
                this.cancelButton.element.appendTo(this.canceldiv);
                this.canceldiv.css({width: opts.width4Cancel, height: opts.height4Cancel});
            }
            if (opts.needSeparate) {
                $contentPane.addClass("fr-core-panel-content-separate");
                this.okdiv && this.okdiv.css('margin-top', opts.needSeparate + 'px');
                this.canceldiv && this.canceldiv.css('margin-top', opts.needSeparate + 'px');
            }
            return $contentPane;
        },

        doResize: function (give) {
            FR.ConfirmPane.superclass.doResize.apply(this, arguments);
            var opts = this.options;
            var alignment = opts.btnsAlignment;
            var oktop = 0, canceltop = 0, okalign = 0, cancelalign = 0;
            var height = opts.height;
            if (opts.needSeparate) {
                height = height - opts.needSeparate;
            }
            if (!isNaN(height)) {
                if ($.support.boxModel === true) {
                    this.$contentPane.css({
                        height: height - this.headerHeight - opts.controlPaneHeight - (this.$contentPane.outerHeight() - this.$contentPane.height()),
                        width: opts.width - (this.panelBody.outerWidth() - this.panelBody.width())
                    });
                } else {
                    this.$contentPane.css({
                        height: height - this.headerHeight - opts.controlPaneHeight,
                        width: opts.width
                    });
                }
            }
            oktop = height - this.headerHeight - opts.controlPaneHeight;
            canceltop = height - this.headerHeight - opts.controlPaneHeight;
            if (alignment == 'right') {
                okalign = opts.width4Cancel + opts.firstBtnMargin + opts.btnsGap;
                cancelalign = opts.firstBtnMargin;
            }
            else if (alignment == 'left') {
                okalign = opts.firstBtnMargin;
                cancelalign = opts.width4OK + opts.firstBtnMargin + opts.btnsGap;
            }
            else {
                var allWidth = opts.width4OK + opts.width4Cancel + opts.btnsGap;
                var Left = (opts.width - allWidth) / 2;
                okalign = Left;
                cancelalign = Left + opts.width4OK + opts.btnsGap;
                alignment = 'left'; //center的时候,用left的距离来计算
            }
            if (this.okButton) {
                this.okdiv.css('top', oktop);
                this.okdiv.css(alignment, okalign);
            }
            if (this.cancelButton) {
                this.canceldiv.css('top', canceltop);
                this.canceldiv.css(alignment, cancelalign);
            }
            this._resizeContentWidget();
        }
    });
    $.shortcut("confirm", FR.ConfirmPane);

    /**
     * 装载按钮的容器
     * @class FR.ButtonPane
     * @extends FR.Panel
     * @private
     */
    FR.ButtonPane = FR.extend(FR.Panel, {
        _defaultConfig: function () {
            return $.extend(FR.ButtonPane.superclass._defaultConfig.apply(this, arguments), {
                text4Cancel: FR.i18nText("FR-Basic_Cancel"),
                width4Cancel: 80,
                button4Other: [],           //wikky:添加两个以上的按钮[{bT:文字,bW:宽度,默认80,bF:按钮点击动作,bC:点击按钮后是否关闭Panel,默认false},{…}}]
                controlPaneHeight: 40,
                btnsAlignment: 'right',
                closeAfterAction: true //Sean: 是否点击按钮事件结束后关闭Panel,默认关闭
            });
        },
        _init: function () {
            FR.ButtonPane.superclass._init.apply(this, arguments);
        },

        _createContentPane: function () {
            var opts = this.options;
            var $contentPane = $('<div class="fr-core-panel-content">').css({
                position: 'absolute',
                top: 0,
                left: 0
            }).appendTo(this.panelBody);
            var other = opts.button4Other;
            this.otherButton = [];
            this.otherButtonWrap = [];
            for (var i = 0; i < other.length; i++) {
                this.otherButtonWrap[i] = $('<div style="position:absolute"/>').appendTo(this.panelBody);
                this.otherButton[i] = new FR.createWidget({
                    type: 'quickbutton',
                    text: other[i].bT,
                    width: other[i].bW ? other[i].bW : 80,
                    baseCls: other[i].baseCls ? other[i].baseCls : '',
                    invisible: other[i].invisible,
                    style: opts.style,
                    handler: function () {
                        var onAct = this.element.data("func");
                        if ($.isFunction(onAct)) {
                            onAct.apply(self);
                        }
                        var aftAct = this.element.data("aftfunc");
                        if (aftAct) {
                            self.doClose();
                        }
                    }
                });
                this.otherButton[i].element.appendTo(this.otherButtonWrap[i]);
                this.otherButtonWrap[i].css({width: other[i].bW, height: opts.height4Cancel});

                this.otherButton[i].element.data("func", other[i].bF ? other[i].bF : FR.emptyFn());
                this.otherButton[i].element.data("aftfunc", other[i].bC ? other[i].bC : false);
            }
            var self = this;
            this.canceldiv = $('<div style="position:absolute"/>').appendTo(this.panelBody);
            this.cancelButton = new FR.createWidget({
                type: 'quickbutton',
                text: opts.text4Cancel,
                //              style : opts.style, //Sean:取消按钮采用默认'gray'样式,不随主题样式变化
                width: opts.width4Cancel,
                height: opts.height4Cancel,
                handler: function () {
                    if ($.isFunction(self.options.onCancel)) {
                        self.options.onCancel.apply(self);
                    }
                    if (self.options.closeAfterAction) {
                        self.doClose();
                    }
                }
            });
            this.cancelButton.element.appendTo(this.canceldiv);
            this.canceldiv.css({width: opts.width4Cancel, height: opts.height4Cancel});

            if (opts.needSeparate) {
                $contentPane.addClass("fr-core-panel-content-separate");
                this.canceldiv && this.canceldiv.css('margin-top', opts.needSeparate + 'px');
                for (var i = 0; i < this.otherButtonWrap.length; i++) {
                    this.otherButtonWrap[i] && this.otherButtonWrap[i].css('margin-top', opts.needSeparate + 'px');
                }
            }
            return $contentPane;

        },

        doResize: function (give) {
            FR.ButtonPane.superclass.doResize.apply(this, arguments);
            var opts = this.options;
            var other = opts.button4Other;
            var alignment = opts.btnsAlignment;
            var canceltop = 0, cancelalign = 0;
            var height = opts.height;
            if (opts.needSeparate) {
                height = height - opts.needSeparate;
            }
            if (!isNaN(height)) {
                if ($.support.boxModel === true) {
                    this.$contentPane.css({
                        height: height - this.headerHeight - opts.controlPaneHeight - (this.$contentPane.outerHeight() - this.$contentPane.height()),
                        width: opts.width - (this.panelBody.outerWidth() - this.panelBody.width())
                    });
                } else {
                    this.$contentPane.css({
                        height: height - this.headerHeight - opts.controlPaneHeight,
                        width: opts.width
                    });
                }
            }
            canceltop = height - this.headerHeight - opts.controlPaneHeight;
            var alignment = opts.btnsAlignment;
            if (alignment == 'right') {
                var right = opts.width4Cancel + 40;
                this.canceldiv.css(alignment, 20);
                this.canceldiv.css('top', canceltop);
                for (var i = 0; i < other.length; i++) {
                    this.otherButtonWrap[i].css(alignment, right);
                    this.otherButtonWrap[i].css('top', canceltop);
                    right = right + other[i].bW + 20;
                }

            }
            else if (alignment == 'left') {
                var left = opts.width4Cancel + 40;
                this.canceldiv.css(alignment, 20);
                this.canceldiv.css('top', canceltop);
                for (var i = 0; i < other.length; i++) {
                    this.otherButtonWrap[i].css(alignment, left);
                    this.otherButtonWrap[i].css('top', canceltop);
                    left = left + other[i].bW + 20;
                }
            }
            else {
                var allWidth = 0;
                for (var i = 0; i < other.length; i++) {
                    allWidth = allWidth + other[i].bW + 20;
                }
                allWidth = allWidth + opts.width4Cancel;
                var otherLeft = (opts.width - allWidth) / 2;
                for (var i = 0; i < other.length; i++) {
                    this.otherButtonWrap[i].css('left', otherLeft);
                    this.otherButtonWrap[i].css('top', canceltop);
                    otherLeft = otherLeft + other[i].bW + 20;
                }
                this.cancelButton.element.css('left', otherLeft);
            }
            this._resizeContentWidget();

        }
    });
    $.shortcut("otherbutton", FR.ButtonPane);

    /**
     * 窗体控件
     * @class FR.Window
     * @extends FR.Widget
     * @since 6.5.3
     *
     * @cfg {JSON} options 配置属性
     * @cfg {String} [options.title='Window'] 窗体的标题
     * @cfg {Number} [options.titleHeight=30] 窗体的标题高度
     * @cfg {Boolean} [options.modal=true] 是否为模态窗体,模态窗体不允许点击对话框下层的区域
     * @cfg {Boolean} [options.confirm=false] 是否为带“确定”和“取消”按钮的窗体
     * @cfg {Object} options.otherButton
     * @cfg {Boolean} [options.closable=true] 窗体是否可以关闭,如果可以关闭将会在左上角显示关闭按钮
     * @cfg {Boolean} [options.collapsible=false] 窗体是否可以收缩
     * @cfg {Boolean} [options.closed=true] 初始化完成后是否将窗体置为关闭状态
     * @cfg {Boolean} [options.destroyOnClose=false] 窗体关闭后是否立即销毁窗体对象
     * @cfg {Number} [options.width=300] 窗体的宽度
     * @cfg {Number} [options.height=200] 窗体的高度
     * @cfg {Boolean} [options.resizeable=true] 窗体是否可以拖拽调整大小
     * @cfg {Boolean} [options.draggable=true] 窗体是否可以被拖动
     * @cfg {JSON} [options.override] 覆盖内部FR.Panel属性的配置属性
     * @cfg {Function} [options.onDialogResize] 窗体调整大小时触发的函数
     */
    FR.Window = FR.extend(FR.Widget, {
        _defaultConfig: function () {
            return $.extend(FR.Window.superclass._defaultConfig.apply(), {
                baseCls: "fr-core-window",
                title: "Window",
                titleHeight: 30,
                modal: true,
                confirm: false,
                otherButton: false,
                closable: true,
                collapsible: false,
                closed: true,
                destroyOnClose: false,
                width: 300,
                height: 200,
                resizeable: true,
                draggable: true
            });
        },
        _init: function () {
            FR.Window.superclass._init.apply(this, arguments);
            var o = this.options;
            var win = this.win;
            if (!$.support.boxModel) {
                win.doResize({
                    // marro :这里比较特殊 win = this.el,
                    // 生成win的的时候大小由o确定了,而FR.Widget初始化时也会对this.el大小进行改变,并且还考虑了boxModel.因此,再reszie下。
                    width: o.width,
                    height: o.height
                })
            }
            var self = this;
            if (this.mask) {
                this.mask.remove();
            }
            if (o.modal === true) {
                this.mask = $('<div class="fr-core-window-mask"></div>')
                    .appendTo('body');
                this.mask.css({
                    zIndex: FR.widget.opts.zIndex++,
                    width: this._getPageArea().width,
                    height: this._getPageArea().height,
                    display: 'none'
                });
                $(window).resize(function () {
                    self.mask.css({
                        width: self._getPageArea().width,
                        height: self._getPageArea().height
                    })
                });
            }
            this.element.css({
                zIndex: FR.widget.opts.zIndex++
            });
            if (win.options.left == null) {
                var width = win.options.width;
                if (isNaN(width)) {
                    width = this.element.outerWidth();
                }
                //  var l = $(window.document).width() bug64304,ie,ff下不能取document高度
                var l = $(window).width();
                if (FR.Browser.isIE8Before()) {
                    l = $(window.document).width();
                }
                win.options.left = (l - width) / 2
                + $(document).scrollLeft();
            }
            if (win.options.top == null) {
                var height = win.options.height;
                if (isNaN(height)) {
                    height = this.element.outerHeight();
                }
                var h = $(window).height();
                if (FR.Browser.isIE8Before()) {
                    h = $(window.document).height();
                }
                win.options.top = (h - height) / 2
                + $(document).scrollTop();
            }
            win.doMove();
            this.setVisible(!o.closed);
            if (this.options.draggable) {
                this.element.draggable({
                    handle: ">div.fr-core-panel-header",
                    onStartDrag: function (e) {
                        if (self.mask) {
                            self.mask.css('z-index', FR.widget.opts.zIndex.zIndex++);
                        }
                        if (self.shadow) {
                            self.shadow.css('z-index', FR.widget.opts.zIndex.zIndex++);
                        }
                        self.element.css('z-index', FR.widget.opts.zIndex.zIndex++);
                        var $contentDiv = $(self.element.children()[0]);
                        $contentDiv.css('z-index', 0);
                        var top = $contentDiv.css("top");
                        var height = $contentDiv.css("height");
                        var width = $contentDiv.css("width");
                        var $transparentDiv = $('<div id="transparent-background" style="position:absolute;filter:alpha(opacity=50);opacity:0.5;"></div>');
                        $transparentDiv.css('left', "0px").css('top', top).css('width', width).css('height', height);
                        $transparentDiv.css('z-index', 1);
                        self.element.append($transparentDiv);

                        if (!self.proxy) {
                            self.proxy = $('<div class="fr-core-window-proxy"></div>').insertAfter(self.element);
                        }
                        self.proxy.css({
                            display: 'none',
                            zIndex: FR.widget.opts.zIndex.zIndex++,
                            left: e.data.left,
                            top: e.data.top
                        });
                        self.proxy._outerWidth(self.element._outerWidth());
                        self.proxy._outerHeight(self.element._outerHeight());
                        setTimeout(function () {
                            if (self.proxy) {
                                self.proxy.show();
                            }
                        }, 500);
                    },
                    onDrag: function (e) {
                        var pluginLimit = FR.Window.PluginDialogLimit;
                        if(pluginLimit){
                            e.data.top = pluginLimit.onDrag.pluginTopFn(e.data.top,self.element._outerHeight(),self._getPageArea().height);
                            e.data.left = pluginLimit.onDrag.pluginLeftFn(e.data.left,self.element._outerWidth(),self._getPageArea().width);
                        }

                        self.proxy.css({
                            display: 'block',
                            left: e.data.left,
                            top: e.data.top
                        });
                        return false;
                    },
                    onStopDrag: function (e) {
                        $("#transparent-background").remove();
                        self.proxy.remove();
                        self.proxy = null;
                    }
                });
            }
            if (this.options.resizeable) {
                this.element.resizable({
                    onStartResize: function (e) {
                        if (!self.pmask) {
                            self.pmask = $('<div class="fr-core-window-proxy-mask"></div>').insertAfter(self.element);
                        }

                        self.pmask.css({
                            zIndex: FR.widget.opts.zIndex++,
                            left: e.data.left,
                            top: e.data.top,
                            width: self.element._outerWidth(),
                            height: self.element._outerHeight()
                        });
                        if (!self.proxy) {
                            self.proxy = $('<div class="fr-core-window-proxy"></div>').insertAfter(self.element);
                        }
                        self.proxy.css({
                            zIndex: FR.widget.opts.zIndex++,
                            left: e.data.left,
                            top: e.data.top
                        });
                        self.proxy._outerWidth(e.data.width);
                        self.proxy._outerHeight(e.data.height);
                    },
                    onResize: function (e) {
                        if(!self.proxy){
                            return;
                        }

                        self.proxy.css({
                            left: e.data.left,
                            top: e.data.top
                        });
                        self.proxy._outerWidth(e.data.width);
                        self.proxy._outerHeight(e.data.height);
                        return false;
                    },
                    onStopResize: function (e) {
                        var pluginLimit = FR.Window.PluginDialogLimit;
                        if (pluginLimit) {
                            e.data.height = pluginLimit.onResize.pluginHeightFn(e.data.top, self.element._outerHeight(), self._getPageArea().height);
                            e.data.width = pluginLimit.onResize.pluginWidthFn(e.data.left, self.element._outerWidth(), self._getPageArea().width);
                            e.data.top = pluginLimit.onResize.pluginTopFn(e.data.top, self.element._outerHeight(), self._getPageArea().height);
                            e.data.left = pluginLimit.onResize.pluginLeftFn(e.data.left, self.element._outerWidth(), self._getPageArea().width);
                        }
                        $.extend(self.options, {
                            left: e.data.left,
                            top: e.data.top,
                            width: e.data.width,
                            height: e.data.height
                        });
                        self.doResize({
                            top: self.options.top,
                            left: self.options.left,
                            width: self.options.width,
                            height: self.options.height
                        });
                        self.pmask.remove();
                        self.pmask = null;
                        if(self.proxy) {
                            self.proxy.remove();
                            self.proxy = null;
                        }
                    }
                });
            }
        },

        _defaultRoot: function () {
            var o = this.options, override = o.override;
            // PIE ie8标准模式有黑框
            if (FR.Browser.isIE() && !FR.Browser.r.quirks) {
                o.baseCls += " fr-core-window-no-hack";
            }
            var self = this;
            var panelType;
            if (o.confirm) {
                panelType = "confirm";
            } else if (o.otherButton) {
                panelType = "otherbutton";
            } else {
                panelType = "panel";
            }
            var winOpts = $.extend({}, o, {
                type: panelType,
                height: o.height - o.titleHeight,
                fit: false,
                renderEl: $('<div/>').appendTo("body"),
                doSize: true,
                border: true,
                borderRadius: 'auto',
                cls: o.baseCls,
                headerCls: 'fr-core-window-header',
                bodyCls: 'fr-core-window-body',
                onClose: function () {
                    if (self.mask) {
                        self.mask.hide();
                    }
                    if (o.destroyOnClose) {
                        self.destroy();
                    }
                },
                onOpen: function () {
                    if (self.mask) {
                        self.mask.show();
                    }
                },
                onResize: function (width, heigh) {
                    if ($.isFunction(o.onDialogResize)) {
                        o.onDialogResize();
                    }
                },
                onMove: function (left, top) {

                }
            }, override);
            this.win = FR.createWidget(winOpts);
            return this.win.element;
        },

        _getPageArea: function () {
            if (document.compatMode == 'BackCompat') {
                return {
                    width: Math.max(document.body.scrollWidth,
                        document.body.clientWidth),
                    height: Math.max(document.body.scrollHeight,
                        document.body.clientHeight)
                }
            } else {
                return {
                    width: Math.max(document.documentElement.scrollWidth,
                        document.documentElement.clientWidth),
                    height: Math.max(
                        document.documentElement.scrollHeight,
                        document.documentElement.clientHeight)
                }
            }
        },

        /**
         * 关闭窗体
         */
        doClose: function () {
            this.win.doClose();

        },
        doResize: function (give) {
            this.win.doResize(give);

        },
        /**
         * 设置窗体的标题文本
         * @param title 新的标题
         */
        setTitle: function (title) {
            this.win.setTitle(title);
        },
        /**
         * 设置窗体的显示内容
         * @param {Object} c 新的窗体内容
         * @param {String} c.type 新内容的类型
         * @param {String} c.content 新内容的具体文本
         *
         *          setContent({type : "contentText" ,content : "1111"});
         *          setContent({type : "contentHtml" ,content : "<p><i>test</i></p>"});
         */
        setContent: function (c) {
            this.win.options[c.type] = c.content;
            // 强制加载对话框内容
            this.win._loadContent(true);
            if (FR.Browser.isIE8Before()) {
                var self = this;
                setTimeout(function () {
                    self.doResize({'width': undefined, 'height': undefined});
                }, 150);
            }
        },
        setVisible: function (flag) {
            // 需要设置为可见,并且该对话框当前是不可见的才去打开
            if (flag === true && this.win.options.closed === true) {
                this.win.doOpen();
            } else if (flag === false && this.win.options.closed === false) {
                this.win.doClose();
            }
        },
        // 销毁整个FR.Window
        destroy: function () {
            this.element.remove();
            this.mask.remove();
        }
    });
    $.shortcut("window", FR.Window);

    /**
     * 对话框。可以同时显示多了对话框,但是只有最上层的活跃状态
     *
     *     @example
     *     var dlg = new FR.Dialog({
     *            title : 'Dialog',
     *            height : 100,
     *            contentHtml : '<p>Hello Dialog!</p>'
     *     });
     *     dlg.setVisible(true);
     *
     * @class FR.Dialog
     * @extends FR.Window
     * @since 6.5.3
     */
    FR.Dialog = FR.extend(FR.Window, {});
    $.shortcut("dialog", FR.Dialog);

})(jQuery);