/**
    @title:  OMEGA Application Framework for Javascript
    @author: Eugen Andrasescu
    @mailto: only4seasons@gmail.com
*/
var omega = {
    __name:"omega",
    __version:1.0,
    __description:"Application Framework for Javascript",
    __state:0,
    __require:{},
    __depend:{},
    
    ready:false,
    modules:{},
    
    __init:function() {
        if (document.addEventListener) {
            document.addEventListener("DOMContentLoaded", function(){omega.ready=true;omega.start()}, false );
        }
        else if (document.onreadystatechange === null) {
            document.write("<scr" + "ipt id=__ie_init defer=true " + 
            "src=//:><\/script>");
            var script = $id("__ie_init");
            script.onreadystatechange = function() {
                if ( this.readyState != "complete" ) return;
                this.parentNode.removeChild( this );
                omega.ready=true;
                omega.start();
            };
            script = null;
        }
        else {
            window.onload = function(){omega.ready=true;omega.start()};
        }
        
        window.onbeforeunload = function() {
            //alert(__flash_setupUnloadHandler);
            //alert(window.onunload);
            //alert(__flash_unloadHandler + "\n" + __flash_savedUnloadHandler);
            __flash_unloadHandler = function(){};
		    __flash_savedUnloadHandler = function(){};
            //window.blur();
            //window.minimize();
            //window.focus();
        }
        /*
        window.onunload = function() {
            if (window.opera || !document.all) {}
            /*
            var k = document.getElementsByTagName("OBJECT");
		    for (i=0;i<k.length;i++) {
			    k[i].style.display = "none";
			    for (var x in k[i]) {
				    if (typeof k[i][x] == "function") {
					    k[i][x] = function(){};
				    }
			    }
                k[i].parentNode.removeChild(k[i]);
		    }
            omega.stop();
        }*/
        return true;
    },
    __start:function() {
        for (var i in omega.modules) {
            if (omega.modules[i].__state == 1) {
                omega.modules[i].start();
            }
        }
        
        window.onunload = function(){omega.ready=false;omega.stop();};
        return true;
    },
    __stop:function() {
        for (var i in omega.modules) {
            if (omega.modules[i].__state == 2) {
                omega.modules[i].stop();
            }
        }
        document.body.innerHTML = "";
        //alert("omega.stopped");
        return true;
    },
    __destroy:function() {
    },
    
    init:function() {
        $dbg("init: "+this.__name);
        if (this.__require && this.__require.length>0) {
            for (var i=0;i<this.__require.length;i++) {
                var r = this.__require[i];
                if (!omega.modules[r]) {
                    omega.load("js/omega."+r+".js");
                }
            }
        }
        this.__state = this.__init() ? 1:0;
        $dbg("__init: "+this.__name+" "+this.__state);
        if (omega.ready)
            this.start();
    },
    start:function() {
        $dbg("start: "+this.__name);
        if (this.__state == 1) {
            var tr = true;
            for (var i in this.__require) {
                var m = omega.modules[i];
                if (m.__state==1) {
                    m.start();
                }
                if (m.__state != 2) {
                    tr = false;
                }
            }
            if(!tr) return;
            
            if (this.__state == 1) {
                this.__state = this.__start() ? 2:1;
                $dbg("__start: "+this.__name+" "+this.__state);
            }
            if (this.__state == 2) {
                for (var i in this.__depend) {
                    if (i == "omega")
                        var m = omega;
                    else
                        var m = omega.modules[i];
                    
                    m.start();
                }
            }
        }
    },
    stop:function() {
        $dbg("stop: "+this.__name);
        if (this.__state == 2) {
            this.__state = this.__stop() ? 1:2;
            $dbg("__stop: "+this.__name+" "+this.__state);
            for (i=0;i<this.__depend.length;i++) {
                omega.modules[this.__depend[i]].stop();
            }
        }
    },
    destroy:function() {
        $dbg("destroy: "+this.__name);
    },
    
    require:function(mod) {
        if (!this.__require[mod]) {
            if (!omega.modules[mod]) {
                omega.modules[mod]  = {};
                omega.modules[mod].__depend = {};
                omega.load("js/omega."+mod+".js");
            }
            this.__require[mod] = true;
            omega.modules[mod].__depend[this.__name] = true;
        }
    },
    
    dispose:function(mod) {
        if (this.__require[mod]) {
            delete this.__require[mod];
            delete omega.modules[mod].__depend[this.__name];
            if (omega.modules[mod].__depend.length == 0) {
                omega.modules[mod].stop();
                omega.modules[mod].destroy();
            }
        }
    },
    
    __listeners:{},
    
    listen:function(src, code) {
        if (!omega.__listeners[src]) omega.__listeners[src] = {};
        if (!omega.__listeners[src][code]) omega.__listeners[src][code] = {};
        omega.__listeners[src][code][this.__name] = true;//this.callback;
    },
    
    broadcast:function(code, msg) {
        var ev  = {};
        if (omega.__listeners[this.__name]) {
            if (omega.__listeners[this.__name][code]) {
                $extend(ev, omega.__listeners[this.__name][code]);
            }
            if (omega.__listeners[this.__name]["*"]) {
                $extend(ev, omega.__listeners[this.__name]["*"]);
            }
        }
        if (omega.__listeners["*"]) {
            if (omega.__listeners["*"][code]) {
                $extend(ev, omega.__listeners["*"][code]);
            }
            if (omega.__listeners["*"]["*"]) {
                $extend(ev, omega.__listeners["*"]["*"]);
            }
        }
        var src = this.__name;
        
        for (i in ev) {
            omega.modules[i].callback(src,code,msg);
        }
    },
    
    module:function(mod) {
        if (omega.modules[mod.__name] != null) {
            mod.__depend = omega.modules[mod.__name].__depend;
        }
        
        if (!mod.__init) mod.__init = omega.__true;
        if (!mod.__start) mod.__start = omega.__true;
        if (!mod.__stop) mod.__stop = omega.__true;
        if (!mod.__destroy) mod.__destroy = omega.__true;
        if (!mod.__depend) mod.__depend = {};
        
        
        omega.modules[mod.__name] = mod;
        
        mod.__require = {};
        mod.__state = 0;
        $extend(mod, omega, ["init","start","stop", "destroy","require","dispose","listen","broadcast"]);
        
        var path = mod.__name.split(".");
        if (path.length == 1) {
            omega[mod.__name] = mod;
        }
        else {
            if (omega[path[0]] == null) {
                omega[path[0]] = {};
            }
            omega[path[0]][path[1]] = mod;
        }
        
        mod.init();
    },
    
    load:function(src) {
        //try {
        //    document.write(String.fromCharCode(60)+"script type=\"text/javascript\" src=\""+src+"\">"+String.fromCharCode(60)+"/script>");
        //} catch (e) {
            var script = document.createElement("script");
            script.src = src;
            script.type = "text/javascript";
            $tag("head")[0].appendChild(script);
        //}
    },
    
    __call:function(arr) {
        for (i=0;i<arr.length;i++) {
            arr[i]();
        }
    },
    
    __true:function() {
        return true;
    },
    __false:function() {
        return false;
    }
}



/*
var eval2 = eval;
var eval = function(arg) {
    //alert(arg);
    return eval2(arg);
};




/**
 * Helper Functions
 */

/* $invoke */
if (typeof $invoke == "undefined") {
    $invoke = function(func) {
        window.setTimeout(func, 0);
    };
}
/* $id - getElementById */
if (typeof $id == "undefined") {
    $id = function(id) {
        return document.getElementById(id);
    }
}
/* $tag - getElementsByTagName */
if (typeof $tag == "undefined") {
    $tag = function(tag) {
        return document.getElementsByTagName(tag);
    }
}
/* $class - getElementsByClassName */
if (typeof $class == "undefined") {
    $class = function(oElm, strTagName, oClassNames) {
        var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
        var arrReturnElements = new Array();
        var arrRegExpClassNames = new Array();
        if(typeof oClassNames == "object"){
            for(var i=0; i<oClassNames.length; i++){
                arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"));
            }
        }
        else{
            arrRegExpClassNames.push(new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"));
        }
        var oElement;
        var bMatchesAll;
        for(var j=0; j<arrElements.length; j++){
            oElement = arrElements[j];
            bMatchesAll = true;
            for(var k=0; k<arrRegExpClassNames.length; k++){
                if(!arrRegExpClassNames[k].test(oElement.className)) {
                    bMatchesAll = false;
                    break;                      
                }
            }
            if(bMatchesAll){
                arrReturnElements.push(oElement);
            }
        }
        return (arrReturnElements);
    }
}
/* $chr - fromCharCode */
if (typeof $chr == "undefined") {
    $chr = function(chr) {
        return String.fromCharCode(chr);
    }
}
/* $uid - Unique ID */
if (typeof $uid == "undefined") {
    $uid = function() {
        return "UID_" + $uid.key + (++$uid.id);
    }
    $uid.id = 1000;
    $uid.key = $chr(65+25*Math.random())+$chr(65+25*Math.random())+$chr(65+25*Math.random())+$chr(65+25*Math.random());
}
/* $extend - Extend Object */
if (typeof $extend == "undefined") {
    $extend = function(dest, src, func) {
        if (func == null) {
            for (i in src)
                dest[i] = src[i];
        }
        else {
            for (i=0;i<func.length;i++) {
                dest[func[i]] = src[func[i]];
            }
        }
    }
}

/* $dbg - Debug */
if (typeof $dbg == "undefined") {
    $dbg = function(msg) {
        if (msg == null) {
            return $dbg.msg;
        }
        $dbg.msg += msg + "<br />";
    }
    $dbg.msg = "";
}

/* $xo - Explore Object */
if (typeof $xo == "undefined") {
    function $xo(obj, pad) {
        var _pad = "   ";
        if (pad == null) pad = "";
        
        var t = "";
        switch (typeof obj) {
            case "object":
                if (obj.constructor == Object) {
                    t += "{\n";
                    for (var i in obj) {
                        t += pad+_pad + i + ": " + $xo(obj[i], pad+_pad) + "\n";
                    }
                    t += pad + "}";
                    return t;
                }
            case "array":
                t += "[\n";
                for (var i=0;i<obj.length;i++) {
                    t += pad+_pad + i + ": " + $xo(obj[i], pad+_pad) + "\n";
                }
                t += pad + "]";
                return t;
            case "function":
                return "function(){}";
            case "string":
                return "\"" + obj.toString() + "\"";
            default:
                return obj.toString();
        }
        return t;
    }
}
    
omega.init();