﻿
if ((typeof(window.CCN) == 'undefined') || (!window.CCN))
{
    window.CCN = {};
    window.CCN.RegisterObject = function(obj){
        if (typeof(this._Objects) == 'undefined')
        {
            this._Objects = [];
        }
        this._Objects.Add(obj);
    }
    window.CCN.RegisterElement = function(el){
        if (typeof(this._Elements) == 'undefined')
        {
            this._Elements = [];
        }
        this._Elements.Add(el);
    }
    window.CCN.RegisterExtension = function(el, funcName){
        if (typeof(el._extensions) == 'undefined')
        {
            el._extensions = [];
        }
        el._extensions.Add(funcName);
    }
    window.CCN.OnDispose = function(){
        window.CCN.Dispose();
    }
    window.CCN.Dispose = function() {
        if (typeof(this._Objects) != 'undefined')
        {
            if (this._Objects)
            {
                for (var i=0; i<this._Objects.length; i++)
                {
                    this._Objects[i].Dispose();
                    this._Objects[i] = null;
                }
                this._Objects.Clear();                
            }
        }
        if (typeof(this._Elements) != 'undefined')
        {
            if (this._Elements)
            {
                for (var i=0; i<this._Elements.length; i++)
                {
                    var el = this._Elements[i];
                    if (el._extensions)
                    {
                        for (var k=0; k<el._extensions.length; k++)
                        {
                            var funcName = el._extensions[k];
                            el[funcName] = null;
                            el._extensions[k] = null;                
                        }
                        el._extensions = null;
                    }
                    this._Elements[i] = null;
                }  
                this._Elements.Clear();              
            }
        }  
        // remove unload handler 
        if (window.removeEventListener) 
        {
            window.removeEventListener('unload', window.CCN.OnDispose, false);            
        }
        else if (window.detachEvent) 
        {
            window.detachEvent('onunload', window.CCN.OnDispose);            
        }         
    }
    if (window.addEventListener) 
    {
        window.addEventListener('unload', window.CCN.OnDispose, false);			
	} 
	else if (window.attachEvent) 
	{
	    window.attachEvent('onunload', window.CCN.OnDispose);
	} 
}

function Base()
{
    window.CCN.RegisterObject(this);
    this._Disposed = false;
    this._HandledElements = [];
    this._HTMLElements = [];
}

Base.prototype.Dispose = function(){
    if (this._Disposed) { return; }
    this._Disposed = true;
    for (var i=0; i<this._HandledElements.length; i++)    
    {
        var el = this._HandledElements[i];
        if (el._events)
        {
            for (var k=0; k<el._events.length; k++)
            {
                var ev = el._events[k];
                this.RemoveHandler(el, ev.eventName);
                el._events[k] = null;                
            }
            el._events = null;
        }        
        this._HandledElements[i] = null;
    }
    for (var i=0; i<this._HTMLElements.length; i++)    
    {
        var propertyName = this._HTMLElements[i];
        if (typeof(this[propertyName]) != 'undefined')
        {
            delete this[propertyName];
        }        
    }
}

Base.prototype.RegisterHTMLElement = function(propertyName) {
    this._HTMLElements.Add(propertyName);
}

Base.prototype.CreateDelegate = function(instance, method) 
{
    return function() {         
        return method.apply(instance, arguments); 
    }
}

Base.prototype.CreateCallback = function(func){
    var args = [];  
    args[0] = func;
    args[1] = this;
    args.LoadArgs(arguments, 1);     
    return this.CreateCallbackWithContext.apply(this, args);      
}

Base.prototype.CreateCallbackWithContext = function(func, context){    
    var newArgs = [];
    newArgs.LoadArgs(arguments, 2);
    
    return function() {
        var originalContext = this;        
        var args = [];
        args[0] = originalContext;
        args.AddRange(newArgs);
        args.LoadArgs(arguments);       
        func.apply(context, args);        
    }
}

Base.prototype.AddHandler = function(element, eventName, func){
    var args = [];    
    args[0] = element;
    args[1] = eventName;
    args[2] = func;
    args[3] = this;
    args.LoadArgs(arguments, 3);
    return this.AddHandlerWithContext.apply(this, args);    
}

Base.prototype.AddHandlerWithContext = function(element, eventName, func, context){
    this._HandledElements.Add(element);
    
    var useCapture = false;
    if (typeof(this.UseCapture) != 'undefined')
    {
        if (this.UseCapture) { useCapture = true; }
    }
    
    var result = false;
    if (!element._events)
    {
        element._events = [];
    }
    var delegate = this.CreateDelegate(context, func);
    var handler;
    var args = [];    
    args[0] = null;
    args[1] = element;
    args.LoadArgs(arguments, 4);
    if (element.addEventListener)
    {
        handler = function(e) { args[0] = e; return delegate.apply(element, args); };
        element.addEventListener(eventName, handler, useCapture);
        result = true;
    }
    else
    {
        if (element.attachEvent)
        {
            handler = function(e) { 
                if (!e) 
                { 
                    try { e = window.event; }
                    catch (ex) { }                    
                }  
                args[0] = e;              
                return delegate.apply(element, args);
            };   
            element.attachEvent('on' + eventName,  handler); 
        }
    }
    element._events[element._events.length] = {eventName: eventName, delegate: delegate, handler: handler};  
    return delegate;
}

Base.prototype.RemoveHandler = function(element, eventName, delegate)
{    
    var handler = null;
    if ((typeof(element._events) !== 'object') || (element._events == null)) 
    {
        return false;
    }
    var result = false;
    var cache = [];
    for (var i=0; i<element._events.length; i++)
    {
        if (element._events[i].eventName == eventName)
        {
            cache[cache.length] = element._events[i];
            cache[cache.length-1].Index = i;
        }
    } 
    if (!(cache instanceof Array)) 
    {
        return false;
    }
    if (delegate)
    {
        var index = null;
        for (var i=0; i<cache.length; i++) 
        {
            if (cache[i].delegate === delegate) 
            {
                handler = cache[i].handler;
                index = cache[i].Index;
                break;
            }
        }
        if (typeof(handler) !== 'function') { return false; }
        if (element.removeEventListener) 
        {
            element.removeEventListener(eventName, handler, false);
            result = true;
        }
        else 
        {
            if (element.detachEvent) 
            {
                element.detachEvent('on' + eventName, handler);
                result = true;
            }
        }    
        element._events.splice(index, 1);
    }
    else
    {
        var i=0;
        var length = cache.length;
        while (i<length) 
        {
            if (cache[i].eventName == eventName)
            {
                handler = cache[i].handler;
                if (typeof(handler) == 'function') 
                { 
                    if (element.removeEventListener) 
                    {
                        element.removeEventListener(eventName, handler, false);
                        result = true;
                    }
                    else 
                    {
                        if (element.detachEvent) 
                        {
                            element.detachEvent('on' + eventName, handler);
                            result = true;
                        }
                    }    
                }
                element._events.splice(cache[i].Index, 1); 
                length -= 1;
            }
            else { i += 1; }
        }        
    }
    return result;
}

Base.prototype.KillEvent = function(eventObject) {
    if (eventObject)
    {
        if (eventObject.stopPropagation) eventObject.stopPropagation();
        if (eventObject.preventDefault) eventObject.preventDefault();
        eventObject.cancelBubble = true;
    }
    
    if (window.event)
    {        
        window.event.returnValue = false;
        window.event.cancelBubble = true;
    }
    var isFirefox3 = false;
    var isMozilla = window.netscape && !window.opera;    
    if (isMozilla)
    {
        if (window.showModalDialog) { isFirefox3 = true; }
    }
    
    if (!isFirefox3)
    {
        if(eventObject.preventCapture) eventObject.preventCapture();
        if(eventObject.preventBubble) eventObject.preventBubble();
    }
    return false;
}

Base.prototype.getElementById = function(id, propertyName){
    if (propertyName) { this.RegisterHTMLElement(propertyName); }
    return ContensisElement(document.getElementById(id));
}

Base.prototype.getElementsByTagName = function(tagName, element, propertyName){
    if (propertyName) { this.RegisterHTMLElement(propertyName); }
    var elements = document.getElementsByTagName(tagName);
    if (element)
    {
        if (element.getElementsByTagName)
        {
            elements = element.getElementsByTagName(tagName);
        }
    }
    var result = [];
    this.Each(elements, function(el, index){
        result[result.length] = ContensisElement(el);
    });
    return result;
}

Base.prototype.CreateElement = function(tagName, propertyName){
    if (propertyName) { this.RegisterHTMLElement(propertyName); }
    return ContensisElement(document.createElement(tagName));
}

Base.prototype.Each = function(obj, func){
    if (!obj) { return; }
    if (typeof(obj.length) != 'undefined')
    {
        for (var i=0; i<obj.length; i++)
        {            
            var result = func.call(this, obj[i], i);
            if (result) { break; }            
        }
    }
    else 
    {
        for (var prop in obj)
        {
            var result = func.call(this, obj[prop], prop);
            if (result) { break; }            
        }
    }    
}
