Function.EnsureNamespace('Inrix');
if(!Inrix.Dom)throw new Error("Required Resource Inrix.Dom failed to load. Are you missing a script reference or file?");

Inrix.Dom.EventManager=function(){
    var _defaultKey='defaultKey';
    var _evts={};

    this.dispose=dispose;

    this.add=addEvent;
    this.clear=clearEvents;
    this.remove=removeEvent;

    function dispose(){
        clearEvents();
        _evts=null;
    }

    function addEvent(evt,key){
        if(!evt||evt.constructor!=Inrix.Event)throw new Error("Inrix.Dom.EventManager.add: 'evt' must be an object of type 'Inrix.Event'.");
        if(!key)key=_defaultKey;
        if(!_evts[key])_evts[key]=[];
        _evts[key].push(evt);
        attach(evt);
        evt=null;
    }
    function removeEvent(evt){
        if(!evt||evt.constructor!=Inrix.Event)throw new Error("Inrix.Dom.EventManager.remove: 'evt' must be an object of type 'Inrix.Event'.");
        for(var x in _evts){
            for(var i=0;i<_evts[x].length;i++){
                if(!Object.Equals(evt,_evts[x][i]))continue;
                _evts[x].splice(i--,1);
                detach(evt);
            }
        }
        evt=null;
    }
    
    function clearEvents(key){
        if(key)return removeKey(key);
        for(var x in _evts)removeKey(x);
    }
    
    function attach(evt){
        if(evt.Target.addEventListener)return evt.Target.addEventListener(evt.Type.replace(/^on/i,''),evt.Handler,evt.Intercept);
        if(evt.Target.attachEvent)return evt.Target.attachEvent(evt.Type,evt.Handler);
        evt.Target[evt.Type]=evt.Handler;
    }
    
    function detach(evt){
        if(evt.Target.removeEventListener)return evt.Target.removeEventListener(evt.Type.replace(/^on/i,''),evt.Handler,evt.Intercept);
        if(evt.Target.detachEvent)return evt.Target.detachEvent(evt.Type,evt.Handler);
        evt.Target[evt.Type]=null;
    }
    
    function removeKey(key){
        if(!_evts[key])return;
        for(var i=0;i<_evts[key].length;i++){
            detach(_evts[key][i]);
            for(var x in _evts[key][i])_evts[key][i][x]=null;
            _evts[key][i]=null;
        }
        delete _evts[key];
    }
}

Inrix.Events={
    CancelBubble:function(e){
        Inrix.Event.cancelBubble(e);
    },
    Void:function(e){
        return Inrix.Event.killEvent(e);
    }
}

Inrix.Event=function(target,type,handler,intercept){
    if(!target)throw new Error("Inrix.Event.ctor: 'target' can not be null.");
    if(!type)throw new Error("Inrix.Event.ctor: 'type' can not be null.");
    if(typeof(handler)!='function')throw new Error("Inrix.Event.ctor: 'handler' must be a valid function pointer.");
    this.Target=target;
    this.Type=type+'';
    this.Handler=handler;
    this.Intercept=!!intercept;
    target=type=handler=intercept=null;
}

//Static Event Methods
Inrix.Event.killEvent=function(domEvent){
    Inrix.Event.cancelBubble(domEvent);
    return Inrix.Event.cancelEvent(domEvent);
}
Inrix.Event.cancelEvent=function(domEvent){
    if(domEvent){
        if(domEvent.preventDefault)domEvent.preventDefault();
        else domEvent.returnValue=false;
    }
    return false;
}
Inrix.Event.cancelBubble=function(domEvent){
    if(!domEvent)return;
    if(domEvent.stopPropagation)domEvent.stopPropagation();
    else domEvent.cancelBubble=true;
}

