/*!
*  Script 架构
* @author luliang
* @version v 1.0 2011-7-20
----------------------------------------------------------
/********************************************************
*/
var Hst = Hst || {};

; (function (object) {
    //private的成员中 _this是绑定当前对象,public的成员 this和_this绑定当前对象    
    var _this = object || window;
    var version = "1.0";
    var topNamespace = _this; //topNamespace是顶级命名空间,所以的命名空间都在他下面。
    var DEBUG = { OFF: 0, ERROR: 1, WARN: 2, INFO: 3, DEBUG: 4, ALL: 5 };
    var console = window.console;
    var options = {
        debug: _this.debug || DEBUG.OFF//管理debug的模式
    };
    //初始化
    function _init() {
        //关闭调试模式,禁用js错误
        if (options.debug == DEBUG.OFF)
            window.onerror = new Function("return true");
    }
    /**
    * 创建一个命名空间，创建的命名空间将会在 顶级 根命名空间下。
    * $namespace('Hst.App'); // returns Hst.App
    * $namespace('App.Shop'); // returns Hst.App.Shop
    * $namespace('TB.App.Shop', true); // returns TB.app.Shop
    */
    function $namespace() {
        var args = arguments, l = args.length,
                o = null, i, j, p,
                global = (args[l - 1] === true && l--);
        for (i = 0; i < l; ++i) {
            p = (args[i]).split('.');
            o = global ? window : topNamespace;
            for (j = (window[p[0]] === o) ? 1 : 0; j < p.length; ++j) {
                o = o[p[j]] = o[p[j]] || {};
            }
        }
        return o;
    }
    /**
    * 创建一个类
    */
    function $class() {
        var length = arguments.length;
        var context = arguments[length - 1];
        var hasSuperClass = (length === 2);
        //创建空类
        function klass() {
            this.init && this.init.apply(this, arguments);
        }
        // 如果参数中有要继承的父类，先让klass继承父类
        if (hasSuperClass) {

            var superClass = arguments[0];

            var tempClass = function () { };
            tempClass.prototype = superClass.prototype;

            // 加一个对父类原型引用的静态属性
            klass.superClass = superClass.prototype;

            // 指定原型
            klass.prototype = new tempClass();

            // 重新指定构造函数
            klass.prototype.constructor = klass;
        }
        if (typeof context === "function") {
            //使用函数构造类成员
            context.call(klass.prototype, klass); //function
            context.init = klass.prototype.init || function () { };
        } else if (typeof context === "object") {
            //使用对象构造类成员
            extend(klass.prototype, context);
        }
        if (hasSuperClass) {
            // 重载init方法，插入对父类init的调用
            klass.prototype.init = function () {
                // 调用父类的构造函数
                klass.superClass.init && klass.superClass.init.apply(this, arguments);
                // 调用此类自身的构造函数                
                context.init && context.init.apply(this, arguments);
            };
        }
        return klass; //返回类
    }
    /**
    * 注册对象
    * eg.
    * $package("Hst.App.Comment",function(top){
    * 	//这时上下文对象this指向顶级命名空间的Hst.App.Comment对象,top指向顶级命名空间
    * 	alert("Hello world! _this is " + this);
    * };
    *
    *$package(function(top){ 
    *   //这时上下文对象this指向顶级命名空间的RS对象,top指向顶级命名空间
    *});
    *
    * @param {String},{Object} name 要创建的包的名字空间
    * @param {Function} func 要创建的包的包体
    */
    function $package() {
        var name = arguments[0];
        var func = arguments[arguments.length - 1];
        var ns = topNamespace;
        if (typeof func === "function") {
            if (typeof name === "string") {
                ns = $namespace(name);
            } else if (typeof name === "object") {
                ns = name;
            }
            func.call(ns, topNamespace);
        } else {
            throw new Error("Function required");
        }
    }
    //简单继承
    function extend(destination, source) {
        for (property in source) {
            destination[property] = source[property];
        }
        return destination;
    }
    //记录异常信息
    function error(ex, space) {
        var msg = "";
        var _s = space || "\n";
        if (!!(window.attachEvent && !window.opera)) {
            msg = ex + _s + "错误类型:" + ex.name + _s + "错误信息:" + ex.message;
        }
        else {
            msg = ex + _s + "错误类型:" + ex.name + _s + "错误信息:" + ex.message + _s + "错误堆栈信息:" + ex.stack;
        }
        out(msg, 1);
        return msg;
    }
    function out(msg, type) {
        type = type || 4;
        if (type <= options.debug) {
            if (!!console) {
                //firebug
                switch (type) {
                    case 5: console.log(msg); break;
                    case 4: console.debug(msg); break;
                    case 3: console.info(msg); break;
                    case 2: console.warn(msg); break;
                    case 1: console.error(msg); break;
                }
            } else {
                alert("消息类型[" + type + "]\n" + msg);
            }
        }
        //可以在此处通过Ajax向服务器端记录到log
        return msg;
    }
    _init();
    _this.$namespace = $namespace; //注册命名空间
    _this.$package = $package; //注册包
    _this.$class = $class; //注册类
    _this.extend = extend;
    _this.version = version; //版本
    _this.error = error; //显示异常信息
    _this.out = out; //日志
    return _this;
} (Hst));
/*
缓存
无塞阻
文件加载后立即缓存，不会第二次加载同一个文件
缓存非常厉害,缓存生命周期在当前浏览器关闭之后
Hst.load(['base.css', 'app01.css','base.js','app01.js']);//同步加载,阻塞
Hst.load(['base.css', 'app01.css','base.js','app01.js'],function() { });//异步加载,无阻塞
Hst.loadVersion(['base.js','base.css', 'app02.js', 'app02.css']);//预加载脚本库文件列表的版本,不实际加载文件
Hst.loadResVersion();//自动预加载页面使用script标签引入的脚本文件列表的版本,不实际加载文件
*/
; (function (object) {
    var _this = object || window;
    var files = {}; //文件列表 file = {src : "",type : "js" , status :"init"|"loading"|"loaded",queue:[]文件加载之前的函数队列 };
    var queues = {}; //load队列
    var excute = false;
    //初始化Loader对象
    function _init() {
        // 很好，很强大，因为getTime()结果不一样，所以用这种方法可以准确的定位到某一个类有没有执行		
        var root = document.documentElement;
        var script = document.createElement("script");
        id = "script" + (new Date).getTime();
        script.type = "text/javascript";
        try {
            script.appendChild(document.createTextNode("window." + id + "=1;"));
        } catch (e) { }
        root.insertBefore(script, root.firstChild);
        if (window[id]) {
            excute = true;
            delete window[id];
        }
        root.removeChild(script);
    }
    function loadResVersion() {
        var alPath = [];
        var is_msie = (navigator.userAgent.indexOf("MSIE") != -1 && !window.opera);
        var scripts = document.getElementsByTagName('script');
        for (var i = scripts.length - 1; i >= 0; i--) {
            var src = is_msie ? scripts[i].src : scripts[i].getAttribute('src');
            if (!!src) {
                alPath.push(src);
            }
        }
        var links = document.getElementsByTagName('link');
        for (var i = links.length - 1; i >= 0; i--) {
            var rel = links[i].rel;
            var href = is_msie ? links[i].href : links[i].getAttribute('href');
            if (!!rel && !!href && rel.toLowerCase() == "stylesheet") {
                alPath.push(href); ;
            }
        }
        loadVersion(alPath);
    }
    function loadVersion(paths) {
        paths = paths.constructor === Array ? paths : [paths]; //设置文件列表
        for (var i = 0; i < paths.length; i++) {
            _mark(paths[i], "loaded");
        }
    }
    function writeScript(paths) {
        paths = paths.constructor === Array ? paths : [paths]; //设置文件列表            
        for (var i = 0; i < paths.length; i++) {
            document.writeln("<script type=\"text/javascript\" src=" + paths[i] + "><\/script>");
        }
    }
    /**
    * @name 载入资源文件
    * @summary 
    * @param <String|Array> path 资源文件路径
    * @param <Function> callback 回调方法
    * @param <Boolean> [isEval] 可选 是否调用系统的Eval方法把JavaScript加载到Dom中,一般都选false,一些动态加载过来有问题的js就写true
    */
    function load(paths, callback, isEval) {
        //加载参数
        var options = {
            name: "queue" + (new Date).getTime(),
            asyn: false //是否异步加载
        };
        paths = paths.constructor === Array ? paths : [paths]; //设置文件列表                
        if (!!callback) {
            options.asyn = true;
            queues[options.name] = { name: options.name, src: paths, done: false, callback: callback }; //设置load队列
        }
        //加载文件
        for (var i = 0; i < paths.length; i++) {
            //标记文件,把文件放到files中
            var src = paths[i];
            var file = _mark(src, "init");
            //文件已经加载成功
            if ("loaded" == file.status) {
                continue;
            }
            if ("loading" == file.status && options.asyn) {
                //文件已经正在加载中
                file.queue.push(queues[options.name]); //装载该文件的callback队列
            }
            else if ("init" == file.status) {
                //文件没有加载  
                file.status = "loading";
                if (file.type == "css") {
                    //加载css
                    loadStyle(file.src);
                    file.status = "loaded";
                }
                else if (file.type == "js") {
                    //同步,无callback,同步加载js(有塞阻)
                    if (!callback && !options.asyn) {
                        loadScript(file.src);
                        file.status = "loaded";
                    }
                    //异步,或者有callback,异步加载js(无塞阻)
                    else {
                        if (!!callback) {
                            file.queue.push(queues[options.name]); //装载该文件的callback队列
                        }
                        loadFile(file.src, function (tsrc) {
                            var tfile = _getFile(tsrc);
                            tfile.status = "loaded";
                            _callqueue(tfile);
                            tfile.queue.length = 0;
                        }, (!!isEval));
                    }
                }
            }
        }
        if (!!queues[options.name] && _eachqueue(queues[options.name].src)) {
            queues[options.name].callback();
            delete queues[options.name];
        }
    }
    //异步加载文件
    function loadFile(src, callback, isEval) {
        var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (4 == xhr.readyState) {
                isEval ? eval("{" + xhr.responseText + "}") : _globalEval(xhr.responseText);
                callback(src);
            }
        };
        xhr.open("GET", src, true);
        xhr.send("");
    }
    // 直接加载脚本
    function loadScript(src, context) {
        context = context || document;
        var head = context.getElementsByTagName("head")[0] || context.documentElement;
        var script = context.createElement("script");
        script.type = "text/javascript";
        script.src = src;
        head.appendChild(script);
        return script;
    }
    //加载css
    function loadStyle(src, context) {
        context = context || document;
        var head = context.getElementsByTagName("head")[0] || context.documentElement;
        var _link = context.createElement("link");
        var links = context.getElementsByTagName("link", context);
        _link.type = "text/css";
        _link.rel = "stylesheet";
        _link.href = src;
        if (0 < links.length) {
            var _last = links[links.length - 1];
            _last.parentNode.insertBefore(_link, _last.nextSibling);
        } else {
            head.appendChild(_link);
        }
        return _link;
    }
    //判断文件是否加载成功
    function hasLoad(src) {
        var file = _getFile(src);
        if ("undefined" != typeof file && "loaded" == file.status) {
            return true;
        }
        return false;
    }
    //获得标记的文件
    function _getFile(src) {
        return files[encodeURIComponent(src.toLowerCase())];
    }
    //标记文件
    function _mark(src, status) {
        src = src.toLowerCase();
        var file = _getFile(src);
        if ("undefined" == typeof (file)) {
            file = {}
            file.src = src;
            file.status = !!status ? status : "init"; //文件的加载状态
            file.type = ""; //文件的类型
            file.queue = []; //文件加载前的callback队列
            if (/\.js(\?|$)/.test(src))
                file.type = "js";
            else if (/\.css(\?|$)/.test(src))
                file.type = "css";
            files[encodeURIComponent(src)] = file
        }
        return file;
    }
    // 将把异步加载的脚本内容插入当前页面来执行
    function _globalEval(data, context) {
        if (data && /\S/.test(data)) {
            context = context || document;
            var head = context.getElementsByTagName("head")[0] || context.documentElement;
            var script = context.createElement("script");
            script.type = "text/javascript";
            if (excute) {
                script.appendChild(context.createTextNode(data));
            } else {
                script.text = data;
            }
            head.insertBefore(script, head.firstChild);
            head.removeChild(script);
            return true;
        }
        return false;
    }
    // 执行文件回调方法数组。一个文件有可能请求多次，绑定了多个的回调方法。
    function _callqueue(file) {
        for (var i = 0; i < file.queue.length; i++) {
            var item = file.queue[i];
            if (_eachqueue(item.src)) {
                item.callback();
                delete queues[item.name];
            }
        }
    }
    //检验队列中的文件是否全部加载完成
    function _eachqueue(src) {
        var flag = true;
        for (var i = 0; i < src.length; i++) {
            if (!hasLoad(src[i])) {
                flag = false;
                break;
            }
        }
        return flag;
    }
    _init();
    _this.load = load;
    _this.loadVersion = loadVersion;
    _this.writeScript = writeScript;
    //把页面上手动嵌入的脚本加入脚本版本库
    _this.loadResVersion = loadResVersion;
} (Hst));

/**
* 公用 
* @module common 
* @static
*/

//描述：String原型扩展,去除开头某个字符
String.prototype.trimStart = function (trimString) {
    var re = new RegExp("^" + trimString + "*", "g");
    return this.replace(re, "");
}

//描述：String原型扩展,去除末尾某个字符
String.prototype.trimEnd = function (trimString) {
    var re = new RegExp(trimString + "*$", "g");
    return this.replace(re, "");
}



//格式字符串 alert("http://{0}/{1}/{2}".format("www.meizz.com", "web", "abc.htm"));
String.prototype.format = function () {
    if (arguments.length == 0) return this;
    for (var s = this, i = 0; i < arguments.length; i++)
        s = s.replace(new RegExp("\\{" + i + "\\}", "g"), arguments[i]);
    return s;
}
//staic String.format("{name}的年龄{age}");
String.format = function () {
    if (arguments.length == 0)
        return null;

    var str = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
        str = str.replace(re, arguments[i]);
    }
    return str;
}

; (function ($) {
    var ajax = $.ajax;
    $.ajax = function (obj) {
        var complete=obj.complete;
        var success = obj.success;   
        if(typeof success=="function"){
            obj.success = function (data, textStatus) {
                if(!data.success && data.success==0)
                {
                    $.dialog.alert(data.msg);
                }else {         
                     success(data, textStatus);
                }     
            }
        }
        if(typeof complete=="function"){
            obj.complete = function (data, textStatus) {
               try  {
                    var result=eval('('+data.responseText+')');
                     }
               catch(exception) {
                     result=null;
                     }
                if(result!=null && !result.success && result.success==0)
                {
                    $.dialog.alert(result.msg);
                }else {         
                        complete(data, textStatus);
                }     
            }
        }
      ajax(obj);
   }

   $.fn.reload=function (url,data ,callback) {
        $(this).block();
        $(this).load(url,data ,callback);
   }


} )(jQuery);


//返回json对象
(function ($, undefined) {
    $.fn.serializeObject = function () {
    var obj = {};

    $.each(this.serializeArray(), function (i, o) {
        var n = o.name,
        v = o.value;
        obj[n] = obj[n] === undefined ? v
        : $.isArray(obj[n]) ? obj[n].concat(v)
        : [obj[n], v];
    });

    return obj;
};
})(jQuery);
