﻿/*=================================================================
*  文件：dialog.js
*  创建者：田真
*  创建日期：2010-2-15
*  最后修改：（楼下请注意保持队形）
*  ##############################################################
*  时间          修改人                      备注
*  2010-2-18    田真                  增加了Dialog对多个触发元素的支持
*  ##############################################################
* ================================================================*/

var externals = {};
var Dialog = function (tigger, opts) {
    // 默认选项
    this.options = {
        // overlay 选项
        overlay: {
            // 默认顶部居中
            top: 'center',
            // 定义遮罩样式
            mask: {
                color: '#ddd',
                loadSpeed: 200,
                opacity: 0.5
            },
            // 禁用模态窗口点击关闭
            closeOnClick: false,
            // 禁用构造后自动加载
            load: false
            //api: true
        },
        //使用的模板对象
        templateObj: Dialog.Template,
        texts: {
            // dialog的标题，可以被触发元素的title属性覆盖
            title: ''
        }
    };
    // 最后一个dialog的触发器对象实例
    this.trigger = false;

    opts = opts || {};
    // 复制用户选项
    $.extend(this.options, opts);
    // 实例方法
    $.extend(this, {
        initialize: function () {
            //创建模板对象
            this.template = new this.options.templateObj(this);
            this.template.__init__();
        },
        // 设置dialog标题
        setTitle: function (text) {
            this.template.setTitle(text);
        },
        // 显示dialog
        show: function () {
            var o = this._overlay();
            if (o) {
                o.load();
            }
        },
        // 关闭dialog
        close: function () {
            var o = this._overlay();
            if (o) {
                o.close();
            }
        },
        // 设置dialog内容
        setContent: function (html) {
            this.template.setContent(html);
            this.fixed();
        },
        // 清除dialog内容
        clearContent: function () {
            this.template.clearContent();
            this.fixed();
        },
        // 固定dialog的位置已经高度
        fixed: function () {
            // 固定模板内高度 
            this.template.fixedHeight();
            // 设置位置
            var pos = {
                top: this.fixedCenter()
            };
            this.handle.getOverlay().css(pos);
        },
        fixedCenter: function () {
            var conf = this.handle.getConf();
            // 获取真实高度
            var height = this.handle.getOverlay().outerHeight({ margin: true });
            // 计算坐标值
            return ($(window).height() - height) / 2;
        },
        // 当dialog被加载后出发
        // @e as event, e.data.tigger 获取当前Dialog的实例
        _onBeforeLoad: function (e) {
            var dialog = e.data.tigger;
            var t = $(this);
            var title = t.attr('title') || dialog.options.texts.title;
            // 设置title
            dialog.setTitle(title);
        },
        // 当dialog被加载后出发
        // @e as event, e.data.tigger 获取当前Dialog的实例
        _onLoad: function (e) {
            var t = e.data.tigger.trigger = $(this);
            if (t.attr('external')) {
                // 尝试构造外部对象
                var external = e.data.tigger._constructObject(t.attr('external'));
                // 判断外部对象及接口方法是否有效
                if (external && $.isFunction(external.load)) {
                    // 有效就调用外部的加载方法
                    external.load({ tigger: t, dialog: e.data.tigger });
                }
            } else if (t.attr('href') && t.attr('href').indexOf('/asmx/') > -1) {
                var url = t.attr('href');
                if (url && url.indexOf('/asmx/') > -1) {
                    var dialog = e.data.tigger;
                    // 获取新内容之前，先清除原内容
                    dialog.clearContent();
                    // 有效的url才进行ajax加载
                    $.get(url, null, function (result) { dialog._externalLoaded({ tigger: t, dialog: dialog, result: result }); }, 'html');
                }
            }
        },
        _externalLoaded: function (data) {
            this.setContent(data.result);
        },
        // 构造外部对象
        _constructObject: function (objectName) {
            if (!objectName)
                return false;
            if (externals[objectName])
                return externals[objectName];
            try {
                eval('var t = new ' + objectName + '();');
                return externals[objectName] = t;
            }
            catch (e) {
                return false;
            }
        },
        // 获取当前触发器的Overlay实例
        _overlay: function () {
            if (this.trigger) {
                return this.trigger.data('overlay');
            }
            return false;
        }
    });
    // init
    this.initialize();
    // dialog handler
    this.handle = $(tigger).overlay(this.options.overlay);
    if (this.handle) {
        var inst = this;
        this.handle.each(function () {
            var h = $(this);
            // 绑定加载前事件
            h.data('overlay').getTrigger().bind('onBeforeLoad', { tigger: inst }, inst._onBeforeLoad);
            // 绑定加载后事件
            h.data('overlay').getTrigger().bind('onLoad', { tigger: inst }, inst._onLoad);
            //h.data('overlay').bind('onLoad', { tigger: inst }, inst._onLoad);
        });

    }
};
// 默认的dialog模板
Dialog.Template = function (dialog) {
    // 持有Dialog对象的实例
    this.dialog = dialog;
    // 容器对象
    this.container = $('\
		        <div id="ui-dialog" class="dui-dialog" style="width: 560px; display:none; left: 423px; top: 173px; ">\
    		        <div class="dui-dialog-content">\
        		        <a href="javascript:;" class="close dui-dialog-close" style="display: ; ">X</a>\
        		        <div class="hd"><h3 class="dialog_title"></h3></div>\
        		        <div class="bd dialog_content" style="height: auto; overflow-x: visible; overflow-y: auto; "><p class="loading">Loading...</p></div>\
    		        </div>\
		        </div>');
    $.extend(this, {
        __init__: function (opts) {
            // 标题栏对象
            this.title = this.container.find('.dialog_title');
            // 正文对象
            this.content = this.container.find('.dialog_content');
            // loading对象
            this.loading = this.container.find('.loading');
            this.render();

        },
        render: function () {
            // 添加到body中
            $('body').append(this.container);
            // 尝试输出模板值
            this.renderTexts();
        },
        renderTexts: function () {
            var texts = this.dialog.options.texts;
            for (var name in texts) {
                this.container.find('.' + name).html(this.dialog.options.texts[name]);
            }
        },
        // 设置标题
        setTitle: function (html) {
            this.title.html(html);
        },
        // 覆盖正文内容
        setBody: function (html) {
            this.content.html(html);
        },
        // 设置正文内容
        setContent: function (html) {
            this.hideLoading();
            this.loading.before($(html));
        },
        hideLoading: function () {
            this.loading.hide();
        },
        showLoading: function () {
            this.loading.show();
        },
        // 清除正文内容
        clearContent: function () {
            // 显示loading
            this.showLoading();
            // 穷尽删除loading之前的所有兄弟节点
            var prev = null;
            while ((prev = this.loading.prev()) && prev.attr('tagName')) {
                prev.remove();
            }
        },
        fixed: function () {
            this.fixedHeight();
            // 返回top坐标
            return this.fixedCenter();
        },
        fixedHeight: function () {
            // 获取正文控件的高度
            var height = this.contentHeight();
            // 获取用于计算的窗口高度值, 100 是纠正值，dialog在窗口上下应该留有一定空间
            var validHeight = $(window).height() - 150;
            // 当高度大于有效高度时
            if (height > validHeight) {
                this.content.css('height', validHeight + 'px');
            }
        },
        fixedCenter: function () {
            var h1 = $(window).height();
            var h2 = this.height();
            return (h1 - h2) / 2;

        },
        height: function () {
            // 容器的有效高度应该算上border的尺寸
            return this.container.height() + 20;
        },
        contentHeight: function () {
            // 正文的正确高度应该算上上下的padding
            var p1 = parseInt(this.content.css('padding-top'));
            var p2 = parseInt(this.content.css('padding-bottom'));
            p1 = isNaN(p1) ? 0 : p1;
            p2 = isNaN(p2) ? 0 : p2;
            // 获取真实高度
            return (p1 + p2 + this.content.height());

        },
        resetHeight: function () {
            this.content.css('height', 'auto');
        },
        scrollTo: function (src) {
            // 移动滚动条到指定元素处
            this.content.animate({ scrollTop: src.offset().top }, 1000);
        }
    });
    //this.__init__();
};
//Dialog.isInitialized = false;

