/**
 * @author poppy
 */
/*-=< System Class >=-*/
(function(){
    Function.prototype.Extends = function(SuperClass, ClassName){
        var i, p, op = this.prototype, a = function(){
        };
        a.prototype = SuperClass.prototype;
        p = this.prototype = new a();
        if (ClassName) 
            p._className = ClassName;
        for (i in op) 
            p[i] = op[i];
        this.prototype.constructor = op.constructor;
        op = null;
        return p;
    };
    function toHashCode(e){
        if (typeof(e.hashCode) != "undefined") 
            return e.hashCode;
        return (e.hashCode = System.getUniqueId());
    };
    
    //System
    if (typeof(System) != "function") {
        window.System = function(){
            instances[(this.hashCode = System.getUniqueId())] = this;
        };
        var counter = 0;
        System.getUniqueId = function(){
            return "mz_" + (counter++).toString(36);
        };
        System.extend = function(d, s){
            for (var i in s) 
                d[i] = s[i];
            return d;
        };
        System.ie = navigator.userAgent.indexOf("MSIE") > 0 && !window.opera;
    };
    var instances = System._instances || {};
    window.Instance = function(hashCode){
        return instances[hashCode];
    };
    
    //System.Event
    System.Event = function(type){
        this.type = type;
    };
    var t = System.Event.Extends(Object, "System.Event");
    t.target = t.currentTarget = t.srcElement = null;
    t.returnValue = true;
    
    //System.prototype
    var t = System.Extends(Object);
    System.Object = System;
    t.addEventListener = function(type, handle){
        if (typeof(handle) != "function") 
            throw new Error(this + " addEventListener: " + handle + " is not a function");
        if (!this._listeners) 
            this._listeners = {};
        var id = toHashCode(handle), t = this._listeners;
        if (typeof(t[type]) != "object") 
            t[type] = {};
        t[type][id] = handle;
    };
    t.removeEventListener = function(type, handle){
        if (!this._listeners) 
            this._listeners = {};
        var t = this._listeners;
        if (!t[type]) 
            return;
        var id = toHashCode(handle);
        if (t[type][id]) 
            delete t[type][id];
        if (t[type]) 
            delete t[type];
    };
    t.dispatchEvent = function(e){
        if (!this._listeners) 
            this._listeners = {};
        var i, t = this._listeners, p = e.type;
        e.target = e.srcElement = e.target || e.srcElement || this;
        e.currentTarget = this;
        if (this[p]) 
            this[p](e);
        if (typeof(t[p]) == "object") 
            for (i in t[p]) 
                t[p][i].call(null, e);
        return e.returnValue;
    };
    t.dispose = function(){
        if (this.hashCode) 
            delete instances[this.hashCode];
        for (var i in this) 
            if (typeof(this[i]) != "function") 
                delete this[i];
    };
    t.getHashCode = function(){
        if (!this.hashCode) 
            instances[(this.hashCode = System.getUniqueId())] = this;
        return this.hashCode;
    };
    t.decontrol = function(){
        delete instances[this.hashCode]
    };
    t.toString = function(){
        return "[object " + (this._className || "Object") + "]"
    };
    
    //Object
    Object.extend = System.extend;
    Object.create = function(json){
        var e = new System.Object();
        if (!(json && json._controlled)) 
            e.decontrol();
        if (json && typeof(json) == "object") 
            System.extend(e, json);
        return e;
    };
})();

