var giant = {};
var __userAgent__ = navigator.userAgent.toLowerCase();
var __tostr__ = Object.prototype.toString;
/** 
 * @class 浏览器判断的便捷工具类。
 * 另一个引用的快捷方式：<code>B.msie、B.version、B.safari……</code>
 * @name giant.B */
giant.B = {};
/** 浏览器版本。
 * @type String */
giant.B.version = (__userAgent__.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1];
/** 是否是Safari浏览器。
 * @type Boolean */
giant.B.safari = /webkit/.test( __userAgent__ );
/** 是否是Opera浏览器。
 * @type Boolean */
giant.B.opera = /opera/.test( __userAgent__ );
/** 是否是IE浏览器。
 * @type Boolean */
giant.B.msie = /msie/.test( __userAgent__ ) && !/opera/.test( __userAgent__ );
/** 是否是Mozilla浏览器。
 * @type Boolean */
giant.B.mozilla = /mozilla/.test( __userAgent__ ) && !/(compatible|webkit)/.test( __userAgent__ );
window.B = giant.B;

/**
 * 一个空函数引用。
 * @field
 * @type Function
 */
giant.EmptyFn = function() {};
/**
 * 若指定的对象 <tt>o</tt> 是一个布尔值对象，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isBool = function(o) { return typeof o === 'boolean'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个HTMLElement对象，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isElement = function(o) { return o && o.nodeType === 1; };
/**
 * 若指定的对象 <tt>o</tt> 是一个空字符串或者是一个长度为0的数组，则返回 <code>true</code>，否则返回 <code>false</code> .
 * @param {Object} o 要检查的对象 .
 * @type Boolean
 */
giant.isEmpty = function(o) {
    return giant.isArray(o) ? o.length === 0 : (giant.isString(o) ? o === String.Empty : false);
};
/**
 * 若指定的对象 <tt>o</tt> 是一个null值或者空字符串或者是一个长度为0的数组，则返回 <code>true</code>，否则返回 <code>false</code> .
 * @param {Object} o 要检查的对象 .
 * @type Boolean
 */
giant.isNullOrEmpty = function(o) {
    return (o == null || this.isEmpty(o));
};
/**
 * 若指定的对象 <tt>o</tt> 是一个字符串，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isString = function(o) { return typeof o === 'string'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个数组，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isArray = function(o) { return __tostr__.call(o) === '[object Array]'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个函数，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isFunction = function(o) { return __tostr__.call(o) === '[object Function]'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个数字，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isNumber = function(o) { return typeof o === "number" && isFinite(o); };
/**
 * 若指定的对象 <tt>o</tt> 是一个undefined，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isUndef = function(o) { return typeof o === 'undefined'; };
/**
 * 用于对象属性的快速复制(继承)。将<tt>source</tt>的属性或方法复制(继承)到对象
 * <tt>target</tt>中，若<tt>deep</tt>为<code>true</code>，则子对象的子属性
 * 也一起被复制(继承)。相同属性的将会被<tt>source</tt>中的新属性覆盖。
 * @example
 * var source = {id:1, name:'Jack Source'}, target = {name:'Jack Target', gender:1};
 * var newObj1 = Object.extend(target, source);
 * // newObj1  --&gt;&gt;  {id:1, name:'Jack Source', gender:1}
 * Object.extend(target);
 * // Object.name   --&gt;&gt;  'Jack Target'
 * // Object.gender --&gt;&gt;  1
 * 
 * @param {Object} target 目标对象。
 * @param {Object} source 源对象。
 * @param {boolean} deep 是否复制(继承)对象中的对象。
 * @returns {Object} 返回继承了<tt>source</tt>对象属性的新对象。
 */
Object.extend = function(target, /*optional*/source, /*optional*/deep) {
    target = target || {};
    var sType = typeof source, i = 1, options;
    if( sType === 'undefined' || sType === 'boolean' ) {
        deep = sType === 'boolean' ? source : false;
        source = target;
        target = this;
    }
    if( typeof source !== 'object' && 
            __tostr__.call(source) !== '[object Function]' )
        source = {};
    
    while(i <= 2) {
        options = i === 1 ? target : source;
        if( options != null ) {
            for( var name in options ) {
                var src = target[name], copy = options[name];
                if(target === copy)
                    continue;
                if(deep && copy && typeof copy === 'object' && !copy.nodeType)
                    target[name] = this.extend(src || 
                            (copy.length != null ? [] : {}), copy, deep);
                else if(copy !== undefined)
                    target[name] = copy;
            }
        }
        i++;
    }
    return target;
};

Object.extend(String.prototype,
/** @lends String */
{
    /**
     * 返回字符串的副本，<strong>用引号引用此字符串</strong>。
     * @returns {String} 被双引号引用的字符串。
     */
    quote: function() {
        var reEscapeable = /[\"\\\x00-x1f\x7f-\x9f]/g;
        if( reEscapeable.test(this) ) {
            return '"' + this.replace(reEscapeable, function(a) {
                var c = String.SpecialChars[a];
                if( typeof c === 'string' )
                    return c;
                c = a.charCodeAt();
                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
            }) + '"';
        }
        return '"' + this + '"';
    },
    /**
     * 返回字符串的副本，忽略前导空白和尾部空白。
     * @returns {String} 此字符串移除了前导和尾部空白，如果没有前导和尾部空白字符，则返回此字符串。
     */
    trim: function() { return this.replace(/^\s+|\s+$/g, ''); },
    /**
     * 返回字符串的副本，忽略前导空白。
     * @returns {String} 此字符串移除了前导空白，如果没有前导空白字符，则返回此字符串。
     */
    ltrim: function() { return this.replace(/^\s+/g, ''); },
    /**
     * 返回字符串的副本，忽略尾部空白。
     * @returns {String} 此字符串移除了尾部空白，如果没有尾部空白字符，则返回此字符串。
     */
    rtrim: function() { return this.replace(/\s+$/g, ''); },
    /**
     * 返回字符串的副本，忽略前导空白和尾部空白。
     * @returns {String} 
     * @see 见<a href="#trim">trim()<a>
     */
    strip: function() { return this.trim(); },
    /**
     * 返回字符串的副本，忽略字符串内部的含有的所有标签字符串。
     * @param {String} replacement 用于替换标签的指定字符串。
     * @returns {String} 此字符串移除了所有的表为HTML标签的字符，如没有标签字符，则返回此字符串。
     */
    stripTags: function(replacement) {
        return this.replace(/<\/?[^>]+>/ig, (replacement || ''));
    },
    /**
     * 返回字符串的副本，忽略字符串内部的含有的所有标签字符串包括忽略标签里有一些JS事件。
     * @param {String} replacement 用于替换标签的指定字符串。
     * @returns {String} 此字符串移除了所有的表为HTML标签的字符，如没有标签字符，则返回此字符串。
     */
    stripAllTags: function (replacement) {
        return this.replace(/<(?:\"[^\"]*\"|\'[^\']*\'|[^><])*>/igm, (replacement || ''));
    },
    /**
     * 返回字符串的副本，忽略字符串的HTML的Script标签字符串。
     * @param {String} replacement 用于替换标签的指定字符串。
     * @returns {String} 此字符串移除了所有的表示为HTML的Script标签的字符，如没有Script标签，则返回此字符串。
     */
    stripScript: function(replacement) {
        return this.replace(new RegExp(RegExp.ScriptExpr), (replacement || ''));
    },
    /**
     * 返回字符串的副本，忽略字符串的HTML标签中的JS事件如onload,onclick等。
     * @param {String} replacement 用于替换标签的指定字符串。
     * @returns {String} 此字符串移除了所有的表示为HTML的JS事件的字符，如没有JS事件，则返回此字符串。
     */
    striptJsEvents:function(replacement){
    	return this.replace(/<[a-z][^>]*\s*on[a-z]+\s*=[^>]+/ig, function($0, $1) {
            return $0.replace(/\s*on[a-z]+\s*=\s*("[^"]+"|'[^']+'|[^\s]+)\s*/ig, replacement||"");
        });
    	
    },
    /**
     * 返回字符串的副本，字符串中的特定字符将被转换。<a href="#unescapeHTML">unescapeHTML</a> 方法可还原经该方法转换的字符串。
     * @example
     * <pre>
     * &amp;  --&gt;  &amp;amp;
     * &lt;  --&gt;  &amp;lt;
     * &gt;  --&gt;  &amp;&gt;
     * &quot;  --&gt;  &amp;quot;
     * &#39;  --&gt;  &amp;#39;
     * </pre>
     * @returns {String} 此字符串将转换特定的字符，如没有那些字符，则返回此字符串。
     */
    escapeHTML: function() {
        return this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
                .replace(/\"/g, '&quot;').replace(/\'/g, '&#39;');
    },
    /**
     * 返回字符串的副本，字符串中的特定字符将被转换，<a href="#escapeHTML">escapeHTML</a> 方法可还原经该方法转换的字符串。
     * @example
     * <pre>
     * &amp;amp;  --&gt;  &amp;
     * &amp;lt;   --&gt;  &lt;
     * &amp;gt;   --&gt;  &gt;
     * &amp;quot; --&gt;  &quot;
     * &amp;#39;  --&gt;  &#39;
     * </pre>
     * @returns {String} 此字符串将转换特定的字符，如没有那些字符，则返回此字符串。
     */
    unescapeHTML: function() {
        return this.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>')
                .replace(/&quot;/g, '"').replace(/&#39;/g, '\'');
    },
    /**
     * 返回字符串的副本，字符串中的格式字符将被转换。
     * @example
     * <pre>
     * // <strong>reverse == true</strong>时，以下字符将被转换：
     * &lt;br /&gt;  --&gt;  \n
     * &amp;nbsp;  --&gt;  _ (表示一个空格)
     * &amp;       --&gt;  &amp;amp;
     * // <strong>reverse == false</strong>时，以下字符将被转换：
     * &amp;amp;       --&gt;  &amp;
     * _(blank)    --&gt;  &amp;nbsp;
     * \r\n        --&gt;  \n
     * \n          --&gt;  &lt;br /&gt;
     * </pre>
     * @param {Boolean} reverse 指示是否使用反向转换。
     * @returns {String} 此字符串将转换格式字符，如没有格式字符，则返回此字符串。
     */
    formatHTML: function(reverse) {
        var str = this.toString();
        if( reverse ) {
            str = str.replace(/<br[^>]*>/gm, '\n').replace(/&nbsp;/gm, ' ').replace(/&/gm, '&amp;');
        } else {
            str = str.replace(/&amp;/gm, '&').replace(/ /gm, '&nbsp;').replace(/\r\n/gm, '\n')
                    .replace(/\n/gm, '<br />');
        }
        return str;
    },
    /**
     * 返回字符串的长度，若指定 <tt>b</tt> ，则返回UTF-8编码的字符串长度。
     * @param {boolean} b 是否返回UTF-8编码的字符串长度。
     * @returns {Number} 返回字符串的长度。
     */
    len: function(b) {
        if( b ) {
            var s = this.toString();
            return s.replace(/[^\x00-\xFF]/g, '***').length;
        }
        return this.length;
    },
    /**
     * 将CSS样式的短线属性转换为Camel的命名样式。
     * <pre>
     * background-color  --&gt;  backgroundColor
     * border-top-color  --&gt;  borderTopColor
     * </pre>
     * @returns {String} 新的字符串，它移除原字符串的短线 <code>-</code>，并将短线后第一个字符转为大写。
     */
    toCamel: function() {
        var aParts = this.split('-'), iLen = aParts.length;
        if( iLen == 1 ) return aParts[0];
        
        var camelized = this.charAt(0) === '-' ? aParts[0].charAt(0).toUpperCase() + 
                aParts[0].substring(1) : aParts[0];
        for( var i = 1; i < iLen; i++ )
            camelized += aParts[i].charAt(0).toUpperCase() + aParts[i].substring(1);
        return camelized;
    },
    /**
     * 测试此字符串是否以指定的前缀开始。
     * @param {String} p 指定的前缀。
     * @returns {boolean} 如果该参数表示的字符序列是此字符串表示的字符序列的前缀，则为<code>true</code>，
     *   否则为<code>false</code>。还要注意，如果参数是空字符串，则返回<code>true</code>。
     */
    startsWith: function(p) {
        return p === '' ? true : (this.indexOf(p) === 0);
    },
    /**
     * 测试此字符串是否以指定的后缀结束。
     * @param {String} p 指定的后缀。
     * @returns {boolean} 如果该参数表示的字符序列是此字符串表示的字符序列的后缀，则为<code>true</code>，
     *   否则为<code>false</code>。还要注意，如果参数是空字符串，则返回<code>true</code>。
     */
    endsWith: function(p) {
        if( p === '' ) return true;
        var d = this.length - p.length;
        return d >= 0 && this.lastIndexOf(p) === d;
    },
    /**
     * 测试此字符串是否是一串空格组成的空字符串。
     * @returns {boolean} 如果该字符串是一串字可知组成的字符串，则为<code>true</code>，否则为<code>false</code>。
     */
    isBlank: function() { return this.length > 0 && /^\s*$/.test(this); },
    /**
     * 测试此字符串是否是一个正确格式的Email。
     * @returns {boolean} 如果该字符串是一个正确格式的Email，则为<code>true</code>，否则为<code>false</code>。
     */
    isEmail: function() { return (/^(?:\w+\.?)*\w+@(?:\w+\.?)*[a-zA-Z]{2,3}$/i).test(this.trim()); },
    /**
     * 测试此字符串是否是空字符串。
     * @returns {boolean} 如果该字符串是空字符串，则为<code>true</code>，否则为<code>false</code>。
     */
    isEmpty: function() { return this === String.Empty; },
    /**
     * 测试此字符串是否全部由数字组成。
     * @returns {boolean} 如果该字符串全部由数字组成，则为<code>true</code>，否则为<code>false</code>。
     */
    isNumber: function() { return /^\d+$/.test(this); },
    /**
     * 测试此字符串是否为合法的变量命名。
     * @returns {boolean} 如果该字符串为合法的变量命名格式，则为<code>true</code>，否则为<code>false</code>。
     */
    isVar: function() { return /^[a-zA-Z]\w+$/.test(this); },
    /**
     * 将此字符串转换成<code>JSON</code>格式。
     * @returns {String} 此字符串的<code>JSON</code>格式的副本。
     */
    toJSON: function() { return this.quote(); }
}, true);

/**
 * 创建一个新的StringBuilder实例。
 * @class
 * 一个类似于java.lang.StringBuffer的可变字符序列。
 * @example
 * var sb = new StringBuilder();
 * sb.append('&lt;div id="div1"&gt;\n');
 * sb.append('  &lt;h2&gt;this is a h2 title.&lt;/h2&gt;\n');
 * sb.append('&lt;/div&gt;\n');
 * var shtml = sb.toString();
 * // shtml为: &quot;&lt;div id="div1"&gt;\n  &lt;h2&gt;this is a h2 title.&lt;/h2&gt;\n&lt;/div&gt;&quot;
 * </pre>
 * @constructor
 * @name StringBuilder
 * @param {Object} o 要添加到序列首部的对象。
 * @returns {StringBuilder}的新实例。
 */
function StringBuilder(o) {
    this.__strings__ = [];
    if( o )
        this.append(o);
};

/**#@+
 * @memberOf StringBuilder
 * @method
 */
StringBuilder.prototype = {
    /**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
     * 追加<tt>Object</tt>参数的字符串表示形式。
     * <pre>参数将被转换成字符串，就好象使用了 o.toString() 方法一样。然后，将所得字符串中的字符追加到此序列。</pre>
     * @param {Object} o 一个Object
     * @returns 返回这个 <code>StringBuilder</code> 对象的一个引用。
     * @type StringBuilder
     */
    append: function(o) {
        if( !o )
            return this;
        if( Object.prototype.toString.call(o) === '[object Array]' )
            this.__strings__.push(o.join('').toString());
        else
            this.__strings__.push(o.toString());
        return this;
    },
    
    /**
     * 清空此字符序列。
     * @type void
     */
    clear: function() { this.__strings__ = []; },
    
    /**
     * 返回长度（字符数）。
     * <pre>该长度与给定的表示编码的参数有关。在UTF-8编码中，一个全角字符表示3个英文字符。
     * 不指定字符编码情况下，默认为正常的长度，即所有字符的长度为1。</pre>
     * @param {boolean} b 是否使用UTF-8字符编码解析序列长度。
     * @returns {Number} 返回给定字符编码的此序列的长度。
     */
    length: function(b) {
        if( arguments.length == 0 )
            b = false;
        var s = this.toString();
        if( b )
            return s.replace(/[^\x00-xFF]/g,'***').length;
        return s.length;
    },
    
    /**
     * 返回此序列中数据的字符串表示形式。
     * <pre>分配一个新的 String 对象，并将它初始化，以包含当前由此对象表示的字符串序列。然后返回此 String。
     * 对此序列的后续更改不影响该 String 的内容。</pre>
     * 
     * @return {String} 字符序列的字符串表示形式。
     */
    toString: function() {
        var __newString__ = this.__strings__.join('');
        return __newString__;
    }
};

/**
 * Web系统中统一的Ajax控制工具类。
 * @class Ajax控制工具类。
 * @constructor
 */
var GiantAjax = function() {};
window.GiantAjax = GiantAjax;

(function($) {

/**
 * @class Ajax请求的返回状态值信息。
 * <strong>该类的快捷引用是：AjaxStatus</strong>，如：AjaxStatus.success
 * @name giant.Status
 */
 GiantAjax.Status = {
    /**
     * 表示Ajax请求返回成功的标识。
     * @type Number
     */
    success: 1,
    /**
     * 表示Ajax请求返回失败的标识。
     * @type Number
     */
    failure: 0,
    /**
     * 表示Ajax请求发生错误的标识。
     * @type Number
     */
    error: -1
};
window.AjaxStatus = GiantAjax.Status;
	
/**
 * Ajax请求的默认载入控制器前缀。
 * @type String
 */
GiantAjax.LOAD = "ajaxLoad";
/**
 * Ajax请求的默认保存控制器前缀。
 * @type String
 */
GiantAjax.SAVE = "ajaxSave";
/**
 * Ajax请求的默认更新控制器前缀。
 * @type String
 */
GiantAjax.UPDATE = "ajaxUpdate";
/**
 * Ajax请求的默认上传控制器前缀。
 * @type String
 */
GiantAjax.UPLOAD = "ajaxUpload";
/**
 * Ajax请求的默认删除控制器前缀。
 * @type String
 */
GiantAjax.DELETE = "ajaxDelete";

/**
 * 用于执行响应返回Html的Ajax请求。
 * @example
 * <pre>
 * GiantAjax.responseHtml('#div1', {
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     error: function(xhr, status, error) {
 *         <span class="annotate">// Ajax请求错误时，将执行该函数</span>
 *         alert(status);
 *     },
 *     before: function() {
 *         <span class="annotate">// this 表示Ajax请求传递的 options 参数
 *         // return false; 若返回 false，则取消本次Ajax请求</span>
 *         return true;
 *     },
 *     success: function() {
 *         <span class="annotate"><strong>// div1内的Html被此请求返回的Html替换后，执行的回调函数</strong>
 *         // this 表示Ajax请求传递的 options 参数</span>
 *     }
 * });
 * </pre>
 * 
 * @param {String} container 装载返回的Html代码的Html容器Id。
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.async  --&gt;  是否异步发送Ajax请求 <strong>（可选）</strong><br>
 *         options.url    --&gt;  Ajax请求的URL地址   <br>
 *         options.params --&gt;  Ajax请求所传递的参数 <strong>（可选）</strong><br>
 *         options.before --&gt;  Ajax请求发送前执行的回调函数，若返回false，则中断请求。<strong>（可选）</strong><br>
 *         options.success--&gt;  Ajax请求完成，Html代码已装载完成后，执行的回调函数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.responseHtml = function(container, options) {
    var requestUrl = options.url;
//    if(!requestUrl.startsWith('http://'))
//        requestUrl = Path['domain'] + requestUrl;
    container = container.startsWith('#') ? container : '#' + container;
    options.params = options.params || {};
    options.params.format = 'html';
    var ajaxOptions = {
        type: 'GET',
        cache:options.cache||false,
        async: options.async || true,
        url: requestUrl,
        data: options.params,
        success: function(shtml) {
        	if(shtml.length==0){
                _login();
                return;
            }
            $(container).html(shtml);
            if(giant.isFunction(options.success))
                options.success.call(ajaxOptions);
        },
        dataType: options.params.format
    };
    if(giant.isFunction(options.error))
        ajaxOptions.error = options.error;
    if(giant.isFunction(options.before))
        ajaxOptions.beforeSend = options.before;
    $.ajax(ajaxOptions);
};

/**
 * 用于执行响应返回Html的Ajax请求。
 * @example
 * <pre>
 * GiantAjax.requestHtml({
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     error: function(xhr, status, error) {
 *         <span class="annotate">// Ajax请求错误时，将执行该函数</span>
 *         alert(status);
 *     },
 *     before: function() {
 *         <span class="annotate">// this 表示Ajax请求传递的 options 参数
 *         // return false; 若返回 false，则取消本次Ajax请求</span>
 *         return true;
 *     },
 *     success: function(html) {
 *         <span class="annotate"><strong>// 成功请求后，执行的回调函数</strong>
 *         // this 表示Ajax请求传递的 options 参数</span>
 *     }
 * });
 * </pre>
 * 
 * @param {String} container 装载返回的Html代码的Html容器Id。
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.async  --&gt;  是否异步发送Ajax请求 <strong>（可选）</strong><br>
 *         options.url    --&gt;  Ajax请求的URL地址   <br>
 *         options.params --&gt;  Ajax请求所传递的参数 <strong>（可选）</strong><br>
 *         options.before --&gt;  Ajax请求发送前执行的回调函数，若返回false，则中断请求。<strong>（可选）</strong><br>
 *         options.success--&gt;  Ajax请求完成，执行的回调函数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.requestHtml = function(options) {
	var requestUrl = options.url;
//    if(!requestUrl.startsWith('http://'))
//        requestUrl = Path['domain'] + requestUrl;
    options.params = options.params || {};
    options.params.format = 'html';

    var ajaxOptions = {
        type: 'GET',
        cache:options.cache||false,
        async: options.async || true,
        url: requestUrl,
        data: options.params,
        success: function(msg) {
//            if(msg.length==0){
//                _login();
//                return;
//            }
            if (giant.isFunction(options.success)) {
                options.success(msg);
            }
        },
        dataType: options.params.format
    };
    
    if(giant.isFunction(options.error))
        ajaxOptions.error = options.error;
    if(giant.isFunction(options.before))
        ajaxOptions.beforeSend = options.before;
    $.ajax(ajaxOptions);
};

/**
 * 用于执行响应返回JSON的Ajax请求。
 * @example
 * <pre>
 * GiantAjax.responseJson({
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     error: function(xhr, status, error) {
 *         <span class="annotate">// Ajax请求错误时，将执行该函数</span>
 *         alert(status);
 *     },
 *     before: function() {
 *         <span class="annotate">// this 表示Ajax请求传递的 options 参数
 *         // return false; 若返回 false，则取消本次Ajax请求
 *         <strong>// 该方法与<u>jQuery</u>的beforeSend相同</strong></span>
 *         return true;
 *     },
 *     success: function(jsonData) {
 *         <span class="annotate"><strong>// Ajax成功执行后的回调函数</strong></span>
 *     }
 * });
 * <span class="annotate"><strong>// 跨域Ajax请求</strong></span>
 * GiantAjax.responseJson({
 *     crossdomain: true,
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     success: function(jsonData) {
 *         <span class="annotate"><strong>// Ajax成功执行后的回调函数</strong></span>
 *     }
 * });
 * <span class="annotate">// 跨域Ajax请求返回的JSON
 * // jsonCallback是事先定义要执行的函数名(该函数名根据需要进行更改)</span>
 * jsonCallback(JSON数据)
 * </pre>
 * 
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.crossdomain --&gt; 是否进行跨域请求，若为true，请参看jQuery的getJSON方法的机制<br>
 *         options.async  --&gt;  是否异步发送Ajax请求 <strong>（可选）</strong><br>
 *         options.url    --&gt;  Ajax请求的URL地址   <br>
 *         options.params --&gt;  Ajax请求所传递的参数 <strong>（可选）</strong><br>
 *         options.before --&gt;  Ajax请求发送前执行的回调函数，若返回false，则中断请求。<strong>（可选）</strong><br>
 *         options.success--&gt;  Ajax请求完成，Html代码已装载完成后，执行的回调函数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.responseJson = function(options) {
    var requestUrl = options.url;
//    if(!requestUrl.startsWith('http://'))
//        requestUrl = Path['domain'] + requestUrl;
    var hasParams = requestUrl.indexOf('?') >= 0;
    options.async = giant.isBool(options.async) ? options.async : true;
    options.params = options.params || {};
    options.params.format = 'json';
    var ajaxOptions = {
            type: options.type || 'GET',
             cache:options.cache||false,
            async: options.async,
            url: requestUrl,
            data: options.params,
            success: options.success || function(jdata) {},
            dataType: options.params.format
        };
    if(options.crossdomain) {
    	requestUrl = hasParams ? requestUrl + '&jsoncallback=?' : 
                requestUrl + '?jsoncallback=?';
        ajaxOptions.url = requestUrl;
    }
    if(giant.isFunction(options.error))
        ajaxOptions.error = options.error;
    if(giant.isFunction(options.before))
        ajaxOptions.beforeSend = options.before;
    $.ajax(ajaxOptions);
};

/**
 * 用于执行FORM表单的Ajax方式提交。
 * @example
 * <pre>
 * <span class="annotate"><strong>// FORM表单的Ajax方式提交 </strong></span>
 * GiantAjax.formSubmit('#form_login', {
 *     <span class="annotate"><strong>// 此方法通常只做表单数据验证，和一些数据的前期处理</strong></span>
 *     beforeSubmit: function() {
 *         if(this.userAccount.value=='' || this.userPassword.value=='') {
 *             alert('请输入对应的账号和密码！');
 *             return false;
 *         }
 *         return true;
 *     },
 *     success: function(data) { alert(data.message); },
 *     dataType: 'json' 
 * });
 * </pre>
 * 
 * @param {String} formId 要执行Ajax提交的表单Id(前缀可包含#)。
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.dataType     --&gt; Ajax提交表单成功后，返回的数据类型(json,html,text...)。<strong>默认为JSON（可选）</strong><br>
 *         options.beforeSubmit --&gt; Ajax提交表单之前，执行的回调函数，<strong>通常用于验证表单数据（可选）</strong><br>
 *         options.success      --&gt; Ajax提交表单成功后，执行的回调函数。<br>
 *         options.data         --&gt; Ajax提交表单时，附加的额外的参数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.formSubmit = function(formId, options) {
	var jForm = formId.startsWith('#') ? $(formId) : $('#' + formId);
	options = Object.extend({
		beforeSubmit: function() { return true; },
		success: function(data) {}
	}, options);
	options.params = options.params || {};
    options.params.format = 'json';
	if(giant.isFunction(options.beforeSubmit))
	    if(options.beforeSubmit.call(jForm) === false)
	        return;
	var jFormOptions = {
		data: options.params,
		dataType: options.dataType || options.params.format,
		success: function(data) {
			options.success.call(jFormOptions, data);
		}
	};
	jForm.ajaxSubmit(jFormOptions);
};

})(jQuery);
