//args..
function print(args..)
{
    var msg = "";
    for (var i = 0; i < args.length; i++) 
    {
        msg += (i == 0 ? "" : "\n") + obj2str(args[i]);
    }
    stdout.println(msg);
}

//args.. strFormat("name:%0,age:%1","tom",25)
function strFormat(args..)
{
    var str = args[0];
    var param = args.slice(1, args.length);
    param = param || [];
    for (var i = 0; i < param.length; i++) 
    {
        var reg = "%" + i;
        str = str.replace(new RegExp(reg, "g"), param[i].toString());
    }
    return str;
}

function copyText(text)
{
	view.clipboard(#put, text);
}

function loadCSS(key, url)
{
    var styleTag = self.select("#" + key);
    if (styleTag) 
        styleTag.src = url;
    else 
        styleTag = self.$("head").$append("<style id='" + key + "' src='" + url + "' />");
    styleTag.activate();
}

function loadJS(path)
{
	//compile("c:\file_in.js", "c:\file_out.js");
	var s = Stream.openFile(path);
	loadbc(s);
}

function toUnicode(str)
{
    var arr = [];
    for (var i = 0, len = str.length; i < len; i++) 
        arr[i] = ("00" + str.charCodeAt(i).toString(16)).slice(-4);
    return "\\u" + arr.join("\\u");
}

function setTimeout(callback, time)
{
    self.timer(time, function()
    {
        if (typeof(callback) == "function") 
            callback();
        if (typeof(callback) == "string") 
            eval(callback);
        return false;
    });
}

function extend(obj1, obj2)
{
    for (var key in obj2) 
        obj1[key] = obj2[key];
    return obj1;
}

function htmlChars(html)
{
    html = html.replace(/\</g, "&lt;");
    html = html.replace(/\>/g, "&gt;");
    return html;
}

function preLoadImage(imgs)
{
    var preImg = self.$("div#preImg");
    preImg && preImg.remove();
    
    var html = "<div id='preImg' style='display:none'>";
    for (var i = 0; i < imgs.length; i++) 
        html += "<img src='" + imgs[i] + "' />";
    html += "</div>";
    
    self.$("body").append(html);
}

function obj2str(o)
{
    var r = [];
    if (typeof o == "string" || o == null) 
    {
        return o;
    }
    if (typeof o == "object" || typeof o == "array") 
    {
        if (!o.sort) 
        {
            r[0] = "{";
            for (var i in o) 
            {
                r[r.length] = "\"" + i + "\"";
                r[r.length] = ":";
                r[r.length] = typeof(o[i]) == "string" ? "\"" + obj2str(o[i]) + "\"" : obj2str(o[i]);
                r[r.length] = ",";
            }
            r[r.length - 1] = "}";
        }
        else 
        {
            r[0] = "[";
            for (var i = 0; i < o.length; i++) 
            {
                r[r.length] = typeof(o[i]) == "string" ? "\"" + obj2str(o[i]) + "\"" : obj2str(o[i]);
                r[r.length] = ",";
            }
            r[r.length - 1] = "]";
        }
        return r.join("");
    }
    return o.toString();
}

function hasClass(elem, className)
{
    if (elem.attributes.exists("class") && new RegExp("(\\s|^)" + className + "(\\s|$)").test(elem.attributes["class"])) 
        return true;
    else 
        return false;
}

function getByteLen(str)
{
	var byteLen = 0;
	for (var i = 0, len = str.length; i < len; i++) 
	{
		if (str.charCodeAt(i) > 127) 
			byteLen += 2;
		else 
			byteLen++;
	}
	return byteLen;
}

function strByteSub(str, size)
{
    var subLastIndex = 0;
    var byteLen = 0;
    for (var i = 0, len = str.length; i < len; i++) 
    {
        if (str.charCodeAt(i) > 127) 
            byteLen += 2;
        else 
            byteLen++;
        if (byteLen > size) 
            break;
        subLastIndex++;
    }
    return str.substr(0, subLastIndex);
}

function byteSubstr(str, size)
{
	str = str || "";
    var ellipsis = "";
    var subLastIndex = 0;
    var byteLen = 0;
    
    for (var i = 0, len = str.length; i < len; i++) 
    {
        if (str.charCodeAt(i) > 127) 
            byteLen += 2;
        else 
            byteLen++;
        
        if (byteLen > size) 
        {
            ellipsis = "...";
            break;
        }
        
        subLastIndex++;
    }
    
    var o = {};
    o.text = str.substr(0, subLastIndex) + ellipsis;
    o.len = subLastIndex;
    return o;
}

//{"error":{"type":"404","message":"Page not found"}}
function checkError(data)
{
    if (data["error"]) 
    {
        print("--------------------------------------------------");
        print("error type:" + data["error"]["type"]);
        print("error message:" + data["error"]["message"]);
        print("--------------------------------------------------");
        return true;
    }
    else 
    {
        return false;
    }
}

function changeSkin(styleConstObj)
{
    //The first style block must be css const,one line one const.
    var style = self.$("style");
    var styleText = style.text;
    for (var attr in styleConstObj) 
    {
        if (!styleConstObj[attr]) 
            continue;
        
        //var reg = new RegExp("\s*@const\s+" + attr + "\s*:\s*.+\s*;\s*");
        var reg = new RegExp("@const\\s+" + attr + "\\s*:.*;");
        var result = reg.exec(styleText);
        if (result.length) 
            styleText = styleText.replace(reg, "@const " + attr + ":" + styleConstObj[attr] + ";");
    }
    style.text = styleText;
    
    var styleLinks = self.$$("head > link, head > style");
    for (var i = 0; i < styleLinks.length; i++) 
        styleLinks[i].activate();
}

//Just like <a> or <button> has ClickEvent
self.onControlEvent = function(evt)
{
    if (evt.type == Event.HYPERLINK_CLICK || evt.type == Event.BUTTON_CLICK) 
    {
        var aOnClick = evt.target.attributes["onclick"];
        return aOnClick && evt.target.eval(aOnClick);
    }
};

var gameListPanel = 
{
    getHTML: function(listData, id, width)
    {
        //listData = listData.sort(function(a, b){ return a["name"] > b["name"] ? 1 : -1; });
		var styleWidth = width > 0 ? " style='width:" + width + "px'" : "";
        var html = "<select class='sel gameListSelect' id='" + id + "'" + styleWidth + ">";
        html += "<div class='gameListBox'>";
        html += "<h5><a href='#' class='current' onclick='gameListPanel.switchList(this,true)'>" + lang["hotGame"] + "</a><a href='#' onclick='gameListPanel.switchList(this,false)'>" + lang["otherGame"] + "</a></h5>";
        var htmlHot = "";
        var htmlOther = "";
        for (var i = 0; i < listData.length; i++) 
        {
            var obj = listData[i];
            if (obj["create"] != 0) 
            {
                var selected = obj["id"] == "0" ? " selected='true' " : "";
				var style = obj["style"] ? " style='" + obj["style"] + "' " : "";
				selected += style;
                if (obj["hot"] == 1) 
                    htmlHot += "<option value='" + obj["id"] + "' title='" + obj["name"] + "'" + selected + ">" + obj["name"] + "</option>";
                else 
                    htmlOther += "<option value='" + obj["id"] + "' title='" + obj["name"] + "'" + selected + ">" + obj["name"] + "</option>";
            }
        }
        html += "<div class='hotGame'>" + htmlHot + "</div>";
        html += "<div class='otherGame' style='display:none'>" + htmlOther + "</div>";
        //html += "<div class='space' />";
        html += "</div>";
        html += "</select>";
        return html;
    },
    switchList: function(linkObj, showHot)
    {
        var listBox = linkObj.parent.parent;
        var btns = listBox.$$("h5 > a");
        var hotGame = listBox.$("div.hotGame");
        var otherGame = listBox.$("div.otherGame");
        if (showHot) 
        {
            btns[0].attributes.addClass("current");
            btns[1].attributes.removeClass("current");
            hotGame.style["display"] = "block";
            otherGame.style["display"] = "none";
        }
        else 
        {
            btns[0].attributes.removeClass("current");
            btns[1].attributes.addClass("current");
            hotGame.style["display"] = "none";
            otherGame.style["display"] = "block";
        }
    }
};

//Not change use -1
function resizeWin(width, height, absolute)
{
    if (absolute) 
    {
        view.resizeWindow(width, height);
    }
    else 
    {
        var elemBody = $("body");
        var currentW = elemBody.scroll(#width), currentH = elemBody.scroll(#height);
        var newW = width == -1 ? -1 : width + currentW;
        var newH = height == -1 ? -1 : height + currentH;
        view.resizeWindow(newW, newH);
    }
}

//Remove \r \n char
function removeRN(str)
{
    var strArray = [];
    for (var i = 0, len = str.length; i < len; i++) 
    {
        var charCode = str.charCodeAt(i);
        if (charCode != 10 && charCode != 13) 
            strArray.push(str.charAt(i));
    }
    return strArray.join("");
}

function forceWrap(text, len)
{
    var str = "";
    for (var i = 0; i < text.length; i++) 
    {
        str += text.substr(i, 1);
        if ((i + 1) % len == 0) 
            str += "<br/>";
    }
    return str;
}

function centerDiv(divId)
{
    var elemDiv = $("#" + divId);
	if (!elemDiv)
		return;
	var elemBody = $("body");
    
    var left = view.box(#width)/2 - elemDiv.box(#width)/2 + elemBody.scroll(#left);
    var top = view.box(#height)/2 - elemDiv.box(#height)/2 + elemBody.scroll(#top);
    
    elemDiv.style.set(
    {
        "position": "absolute",
        "left": left,
        "top": top
    });
	
	setTimeout("centerDiv(\"" + divId + "\")", 100);
}

function callGameBox(params)
{
    var p = "";
    if (typeof(params) == "object") 
    {
        var arr = [];
        for (var key in params) 
            arr.push(key + "=" + params[key].toString().toUrlString());
        p = arr.join("&");
    }
    else if (typeof(params) == "string") 
    {
        p = params;
    }
    view.callGameBox(p);
}

function resetViewHeight(selector, otherHeight = 0)
{
    var elem = self.select(selector);
    if (elem) 
    {
        var topObj = getCssBox(elem, 0);
        var bottomObj = getCssBox(elem, 2);
        var newHeight = elem.intrinsicHeight(elem.box(#width));
        newHeight += topObj.padding + topObj.border + topObj.margin + bottomObj.padding + bottomObj.border + bottomObj.margin;
        newHeight += otherHeight;
        view.resizeWnd(-1, newHeight);
    }
}

function getCssBox(selector, pIndex)
{
    var pData = ["top", "right", "bottom", "left"];
    var elem = typeof(selector) == "Element" ? selector : self.select(selector);
    if (elem) 
    {
        var o = {};
        var elemWidth = elem.style["width"];
        var elemHeight = elem.style["height"];
        var elemPadding = elem.style["padding-" + pData[pIndex]];
        var elemBorder = elem.style["border-" + pData[pIndex] + "-width"];
        var elemMargin = elem.style["margin-" + pData[pIndex]];
        o.width = (elemWidth || 0).toInteger();
        o.height = (elemHeight || 0).toInteger();
        o.padding = (elemPadding || 0).toInteger();
        o.border = (elemBorder || 0).toInteger();
        o.margin = (elemMargin || 0).toInteger();
        return o;
    }
}

class DataLoader
{
    var url = "";
    var instanceName = "";
    var elem = null;
    var method = "";
    var lang = 
    {
        loading: "Loading, please wait...",
        error: "Loading failed. Please try again.",
        reload: "Try Again."
    };
    
    function this(url, instanceName, boxSelector, method = "get")
    {
        this.url = url;
        this.instanceName = instanceName;
        this.elem = self.select(boxSelector);
        this.method = method;
    }
    
    function load()
    {
        var beforeFunName = this.instanceName + ".beforeLoad";
        var completeFunName = this.instanceName + ".complete";
        var errorFunName = this.instanceName + ".error";
        view.httpRequest(this.method, this.url, beforeFunName, completeFunName, errorFunName);
    }
    
    function reload()
    {
        this.load();
    }
    
    function beforeLoad()
    {
        print("beforeLoad");
        this.elem.html = this.getTipsHtml(1);
    }
    
    function complete(data)
    {
        print("complete, data:" + data);
        this.elem.html = data;
    }
    
    function error(code, message)
    {
        print("error, code:" + code + ", message:" + message);
        this.elem.html = this.getTipsHtml(0);
    }
    
    function getTipsHtml(htype)
    {
        var html = "<div style='width:*; height:*; text-align:center; vertical-align:middle; font-size:12px; line-height:20px'>";
        if (htype === 1) 
            html += "<span style='color:#000'>" + this.lang.loading + "</span>";
        else if (htype === 0) 
            html += "<span style='color:#F00'>" + this.lang.error + "</span>";
        html += "<br /><a onclick='" + this.instanceName + ".reload()' href='#' style='text-decoration:none'>" + this.lang.reload + "</a></div>";
		return html;
    }
}

function obj2url(obj)
{
    var arr = [];
    for (var key in obj) 
        arr.push(key + "=" + (obj[key] + "").toUrlString());
    return arr.join("&");
}

function numberFormat(number)
{
    number = number.toInteger().toString();
    var arr = [];
    var flag = 0;
    for (var i = number.length - 1; i >= 0; i--) 
    {
        arr.push(number.charAt(i));
        flag++;
        if (flag == 3 && i != 0) 
        {
            arr.push(",");
            flag = 0;
        }
    }
    return arr.reverse().join("");
    //Sciter split("") & RegExp bug
    //return number.toString().split("").reverse().join("").replace(/(\d{3})(?=\d)/g, "$1,").split("").reverse().join("");
}

function isElemShowing(selector)
{
    var elem = typeof(selector) == "Element" ? selector : self.select(selector);
    if (elem) 
    {
        if (elem.style["display"] == "none" || elem.style["visibility"] == "hidden") 
            return false;
        else 
            return true;
    }
    return undefined;
}

//args list or one object param,new list will be add in default css const list.
function getSkinData(args..)
{
    var defaultCssConst = 
    {
        "default_color": "#333333",
        "tips_color": "#666666",
        "link_color": "#10469E",
        "link_hover_color": "#10469E",
        "link_disabled_color": "#999999",
        "border_color": "#A2BEEC",
        "border_light_color": "#CBD5E5",
        "bg_color": "#F4F7FC",
        "bg_gradient_color1": "#FFFFFF",
        "bg_gradient_color2": "#E5EFFF",
        "bg_node_hover": "#eff5ff",
        "bg_node_selected": "#e5efff",
        "btn_bg": "#EEF3F5",
        "btn_glow": "#66B6EE",
        "btn_border": "#98B8DD",
        "btn_border_hover": "#66B6EE",
        "btn_border_active": "#AAC1E3"
    };
    
    var argsSize = args.length;
    if (argsSize == 1 && typeof(args[0]) == "object") 
    {
        var obj = args[0];
        for (var key in obj) 
        {
            if (!defaultCssConst[key]) 
                defaultCssConst[key] = obj[key];
        }
    }
    else 
    {
        for (var i = 0; i < argsSize; i++) 
        {
            var arg = args[i] + "";
            if (arg.indexOf("|") != -1) 
            {
                var arr = arg.split("|");
                if (!defaultCssConst[arr[0]]) 
                    defaultCssConst[arr[0]] = arr[1];
            }
        }
    }
    
    return view.getSkinColor(defaultCssConst);
}

function trace()
{
    var traceData = __TRACE__;
    print("");
    print("-------------------- trace start --------------------");
    for (var i = 1; i < traceData.length; i++) 
        print("FILE:" + traceData[i][2] + "  LINE:" + traceData[i][0] + "  FUNCTION:" + traceData[i][1]);
    print("--------------------- trace end ---------------------");
}

function templateReplace(templateStr, data)
{
    templateStr += "";
    for (var key in data) 
      templateStr = templateStr.replace("{" + key + "}", data[key] + "");
    return templateStr;
}