﻿
// 
// common.js
// 
// Copyright © 2007-2009 Comphonia Corporation. All rights reserved.
//
var Configuration = { Lib: "/lib", Data: "/data" };
Import("JQuery", "Format", "Setting", "Calendar", "Wikistyle");

var UA = {}, SearchQuery = {}, Cookie = {};
var D = document;
/*@cc_on eval('var document = D;'); @*/

function Import() {
    for (var i = 0; i < arguments.length; i++) {
        var a = arguments[i];
        document.write('\x3cscript type="text/javascript" src="' + (/\.js$/i.test(a) ? a : (Configuration.Lib + '/' + a.toLowerCase() + '.js')) + '" charset="utf-8"/\x3e\x3c/script\x3e');
    }
}
function E(id) { return D.getElementById(id); }
function H(id, v) { return arguments.length == 1 ? D.getElementById(id).innerHTML : (D.getElementById(id).innerHTML = v); }
function I(x) { return x.constructor == String ? x : (x.id ? x.id : (x.id = "Id__" + I.Count++ + "__")); }
I.Count = 0;
function L(x) { return x.constructor == String ? E(x) : x; }
function N(id, v) { return arguments.length == 1 ? (D.getElementById(id).value | 0) : (D.getElementById(id).value = (v | 0)); }
function P(n) { do { n = n.parentNode; } while (n.nodeType != 1); return n; }
function R(n, o) { UA.MSIE7 ? (o.parentElement.innerHTML = n.outerHTML) : (o.parentNode.replaceChild(n, o)); }
function T(id, v) { return arguments.length == 1 ? D.getElementById(id).innerHTML.replace(/<!--.*?-->/g, "").replace(/<.*?>/g, "").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&") : (D.getElementById(id).innerHTML = v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")); }
function V(id, v) { return arguments.length == 1 ? D.getElementById(id).value : (D.getElementById(id).value = v); }
function X(e) { e.title = e.innerHTML; e.innerHTML = ""; }
var ClassName = "class";
var Css = {
    AddRule: function(sel, prop) {
        var s = D.styleSheets;
        with (s[s.length - 1]) {
            if (addRule) addRule(sel, "{" + prop + "}");
            else if (insertRule) insertRule(sel + "{" + prop + "}", cssRules.length);
        }
    }
};
(function() {
    var u = ["Chrome", "FireFox", "MSIE", "Netscape", "Opera", "Safari"];
    with (navigator.userAgent) for (var i = 0; i < u.length; i++) UA[u[i]] = indexOf(u[i]) >= 0;
    UA.MSIE8 = UA.MSIE && D.documentMode >= 8;
    UA.MSIE7 = UA.MSIE && ! UA.MSIE8;
    
    var q = location.search.replace(/^\?/, "").split(/\x26/);
    for (var i = 0; i < q.length; i++)
        with (q[i].split(/\=/))
            SearchQuery[decodeURIComponent(shift())] = length ? decodeURIComponent(join("=")) : true;

    if (D.cookie) {
        var c = D.cookie.split(/;\s*/);
        for (var i = 0; i < c.length; i++) {
            var k = c[i].split(/\=/);
            Cookie[k[0]] = k.length == 1 ? "" : k[1];
        }
    }
    
    if (UA.MSIE && ! UA.MSIE8) {
        ClassName = "className";
        Css.GetStyle = function(e) { e.style.cssText; };
        Css.SetStyle = function(e, v) { e.style.cssText = v; };
    }
    else {
        Css.GetStyle = function(e) { e.getAttribute("style"); };
        Css.SetStyle = function(e, v) { e.setAttribute("style", v); };
    }
})();

var Path = {
    CurrentDirectory: location.pathname == '/' ? '/' : location.pathname.replace(/\/.*?$/, ''),
    Combine: function(p, q) { return (p + '/' + q).replace(/\/+/g, '/'); },
    GetDirectoryName: function(p) { return p.replace(/\/.*?$/, ''); },
    GetFileName: function(p) { return p.replace(/^.*\//, ''); },
    GetFullPath: function(p) {
        with (Path) if (! IsPathRooted(p)) p = Combine(CurrentDirectory, p);
        var a = p.split(/\/+/), r = [''];
        for (var i = 0; i < a.length; i++) {
            switch (a[i]) {
                case '': case '.': break;
                case '..': r.pop(); break;
                default: r.push(a[i]);
            }
        }
        if (p.charAt(p.length - 1) == '/') r.push('');
        return r.join('/');
    },
    IsPathRooted: function(p) { return p.charAt(0) == '/' || /^\w+:/.test(p); }
};

String.prototype.Invoke = function(e, next) {
    var f = function() { with (arguments.callee) { Event.call(Source); if (Next) Next(Source); } };
    f.Event = new Function(this);
    f.Source = e;
    f.Next = next;
    setTimeout(f, 0);
};
String.prototype.Evaluate = function(o) { return (new Function(o ? "with(arguments[0]){" + this + "}" : this))(o); };
String.prototype.ToInt = function() { return this.replace(/[\s,]/g, "").replace(/^\D*([+-]?\d+).*$/, "$1") | 0; };

var Ajax = {
    GetHttpRequest: function() {
        if (Ajax.HttpRequest)
            return Ajax.HttpRequest;
        else if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else if (window.ActiveXObject) {
            try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
            try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
        }
        return null;
    },
    HttpRequest: null,
    GetResponseText: function(uri) {
        with (Ajax.GetHttpRequest()) {
            open("GET", uri, false); send(null);
            return status == 200 ? responseText : null;
        }
    },
    SendRequest: function(uri, func) {
        var r = Ajax.GetHttpRequest();
        var f = function() { if (arguments.callee.HttpRequest.readyState == 4) func(arguments.callee.HttpRequest); };
        f.HttpRequest = r;
        with (r) {
            open("GET", uri, true);
            onreadystatechange = f;
            send(null);
            return r;
        }
    },
    Import: function(element, uri) {
        var f = function(r) {
            if (r.status == 200) {
                var t = r.responseText.replace(/\\/g, "\\\\").replace(/\r?\n|\r/g, "\\n").replace(/<!--.*?-->/g, "");
                var onLoad = Ajax.PickUpRE.OnLoad.test(t) ? RegExp.$1 : null;
                var e = L(arguments.callee.Element);
                e.innerHTML = (Ajax.PickUpRE.Body.test(t) ? RegExp.$1 : t).replace(/\\n/g, "\n").replace(/\\\\/g, "\\").ReplaceMacro();
                var ra = Ajax.ReferenceAttributes, all = e.getElementsByTagName('*');
                if (! /\w+:/.test(arguments.callee.Uri)) with (Path) {
                    for (var i = 0; i < all.length; i++) {
                        var ai = all.item(i), n = ai.tagName.toLowerCase();
                        if (n in ra) {
                            var h = e.getAttribute(ra[n]);
                            if (h && ! IsPathRooted(h) && h.charAt(0) != '#')
                                ai.setAttribute(ra[n], GetFullPath(Combine(GetDirectoryName(arguments.callee.Uri), h)));
                        }
                        var s = Css.GetStyle(ai);
                        if (s && s.indexOf("url(") > 0) {
                            var a = s.split(/;/);
                            for (var j = 0; j < a.length; j++)
                                if (/^(.*?:.*\burl\()(.*?)(\).*)$/.test(a[j]))
                                    a[j] = RegExp.$1 + GetFullPath(Combine(GetDirectoryName(arguments.callee.Uri), RegExp.$2)) + RegExp.$3;
                            Css.SetStyle(ai, a.join(";"));
                        }
                    }
                }
                if (onLoad)
                    onLoad.Invoke(e, ProcessJSTitle);
                else
                    ProcessJSTitle(e);
                Ajax.ImportedPages[arguments.callee.Uri] = true;
            }
            else
                return null;
        };
        f.Element = element;
        f.Uri = uri;
        Ajax.ImportedPages[uri] = false;
        Ajax.SendRequest(uri, f);
    },
    Evaluate: function(uri) { return Ajax.GetResponseText(uri).Evaluate(); },
    CheckImported: function() {
        for (var i = 0; i < Ajax.ImportedPages.length; i++) if (! Ajax.ImportedPages[i]) return false;
        return true;
    },
    ImportedPages: {},
    PickUpRE: { Body: /<body.*?>(.*?)<\/body.*?>/, OnLoad: /<body.*?onload="(.*?)".*?>/ },
    ReferenceAttributes: { a: 'href', iframe: 'src', form: 'action', img: 'src', link: 'href', script: 'src', object: 'data' }
};

var Xml = {
    NodeType: { Element: 1, Attribute: 2, Text: 3, CdataSection: 4, EntityReference: 5, Entity: 6, ProcessingInstruction: 7, Comment: 8, Document: 9, DocumentType: 10, DocumentFragment: 11, Notation: 12 }
};

String.prototype.ToMacroValue = function(o) {
    var a = this.split(/\./);
    if (o == null)
        o = Setting;
    for (var i = 0; i < a.length; i++) { if (a[i] in o) o = o[a[i]]; else return "?"; }
    if (typeof o == "object") { if ("$" in o) o = o.$; else return "?"; }
    return o + "";
};

var ImportedData = {};
String.prototype.ReplaceMacro = function() {
    var s = this.replace(/"#?%7B(.*?)%7D/ig, '"{$1}').replace(/#?(\{(?:[\w\.\/]*::)?[\w\.]+(?:,-?\d+)?(?:\:[A-Za-z]\d*)?\}|#?\{(?:[\w\.\/]*::)?[=@].*?[=@](?:\:[A-Za-z]\d*)?\}|\{\{|\}\})/g, "{}$1{}").split(/\{\}/);
    for (var i = 0; i < s.length; i++) {
        var si = s[i];
        if (/^\{(?:([\w\.\/]+)::)?([\w\.]+)(?:,-?\d+)?(?:\:[A-Za-z]+\d*)?\}$/.test(si)) {
            var ext = RegExp.$1;
            if (ext && ! (ext in ImportedData))
                ImportedData[ext] = Ajax.Evaluate(Configuration.Data + "/" + ext.toLowerCase() + ".txt");
            var v = RegExp.$2.ToMacroValue(ext ? ImportedData[ext] : Setting);
            s[i] = Format(si.replace(/\{(?:[\w\.\/]+::)?[\w\.]+/, "{0"), v);
        }
        else if (/^\{(?:([\w\.\/]*)::)?([=@])(.*)\2(?:,-?\d+)?(?:\:[A-Za-z]+\d*)?\}$/.test(si)) {
            var ext = RegExp.$1;
            if (ext && ! (ext in ImportedData))
                ImportedData[ext] = Ajax.Evaluate(Configuration.Data + "/" + ext.toLowerCase() + ".txt");
            var v = (RegExp.$2 == "=" ? "return " + RegExp.$3 + ";" : RegExp.$3).Evaluate(ext ? ImportedData[ext] : {});
            s[i] = Format(si.replace(/^\{(?:[\w\.\/]*::)?[=@].*[=@]([:,}])/, "{0$1"), v);
        }
        else if (si == "{{")
            s[i] = "{";
        else if (si == "}}")
            s[i] = "}";
    }
    return s.join("");
};

String.prototype.Trim = function() { return this.replace(/^\s+|\s+$/g, ""); };
String.prototype.TrimEnd = function() { return this.replace(/\s+$/, ""); };
String.prototype.TrimStart = function() { return this.replace(/^\s+/, ""); };

function ProcessJSTitle(e) {
    var all = e.getElementsByTagName('*');
    for (var i = 0; i < all.length; i++) {
        var t = all.item(i);
        if (/\bwiki\b/.test(t.getAttribute(ClassName))) Wikistyle.Format(t);
        if (t.title && /^(\w+):(.+)$/.test(t.title)) {
            switch (RegExp.$1) {
                case "javascript": t.title = ""; RegExp.$2.Invoke(t); break;
                case "source": t.title = ""; Ajax.Import(t, RegExp.$2);
            }
        }
    }
}

onload = function() {
    D.body.innerHTML = D.body.innerHTML.ReplaceMacro();
    ProcessJSTitle(D);
    setTimeout(Premain, 0);
};

function Premain() {
    try {
        with (D.getElementsByTagName("h1")[0].ReplaceMacro())
            (indexOf("|") < 0) && (D.title = Setting.Title + " | " + innerHTML);
    }
    catch (e) { }
    
    if (typeof Main == "function")
        Main();
    
    setTimeout(AfterMain, 100);
}

function AfterMain() {
    if (Ajax.CheckImported())
        FitHeight("menu", "main");
    else
        setTimeout(AfterMain, 250);
}

function FitChildHeight(e) {
    var j = [], h = 0, i = 0;
    for (var c = L(e).firstChild; c; c = c.nextSibling)
        if (c.nodeType == Xml.NodeType.Element)
            h = Math.max(h, (j[i++] = $(c)).height());
    while (i)
        j[--i].height(h);
}

function FitHeight() {
    var j = [], h = 0, i = 0;
    while (i < arguments.length) {
        j[i] = $(L(arguments[i]));
        h = Math.max(h, j[i++].height());
    }
    while (i)
        j[--i].height(h);
}

function NewWindow(e, name) {
    var href = e.getAttribute("href");
    if (name == null)
        name = (/^\w+:\/\/(.+)(?:\/|$)/.test(href) ? RegExp.$1 : href.replace(/^.*\//, "")).replace(/\W/g, "_");
    if (name == "")
        name = "_blank";
    window.open(href, name);
    return false;
}
