﻿
/// <summary>
/// A class factory.
/// This class is used to give scripted classes an object oriented flavour.
/// </summary>
Class = 
{
    register: function()
    {
        return function() 
               {
                    this.construct.apply(this, arguments);
               };
    }
};

EventArgs = Class.register();

/// <summary>
/// Represents generic event information.
/// </summary>
EventArgs.prototype =
{
    construct: function(source, e)
    {
        var m_e = e;
        var m_source = source;
        var m_cancel = false;
        
        this.cancel = function() 
        { 
            m_cancel = true;
            
            if (m_e != null)
            {
                m_e.returnValue  = false;
                m_e.cancelBubble = true;
            }
        };
        
        this.get_htmlEvent = function() { return m_e; };
        
        this.get_source = function() { return m_source; };
        
        this.isCancelled = function() { return m_cancel; };
    }
};

EventListener = Class.register();

/// <summary>
/// Represents a listener for custom raised events.
/// </summary>
EventListener.prototype = 
{
    construct: function(target, handler)
    {
        var m_target  = target;
        var m_handler = handler;

        this.getHandler = function() { return m_handler; };
        this.getTarget  = function() { return m_target; };
        
        this.dispose = function()
        {
            m_target  = null;
            m_handler = null;
        };
        
        this.equals = function(listener)
        {
            var result = false;
            
            if (this.getTarget() === listener.getTarget() &&  this.getHandler() === listener.getHandler())
                result = true;
                    
            return result;
        };
    }
};

EventObject = Class.register();

/// <summary>
/// Represents a custom event.
/// </summary>
EventObject.prototype =
{
    construct: function()
    {
        var m_listeners = new Array();                                      

        this.addHandler = function(target, handler)
        {
            m_listeners.push(new EventListener(target, handler));
        };

        this.dispose = function()
        {
            m_clear();
            m_listeners = null;
        };

        this.raise = function(sender, e)
        {
            for (var i = 0; i < m_listeners.length; i++)
            {
                var target  = m_listeners[i].getTarget();
                var handler = m_listeners[i].getHandler();
                
                handler.call(target, sender, e);
            }
        };

        this.removeHandler = function(target, handler)
        {
            var i = 0;
            var listener = new EventListener(target, handler);
            
            for (var i = 0; i < m_listeners.length; i++)
            {
                if (m_listeners[i].equals(listener))
                {
                    m_listeners[i].dispose();
                    m_listeners.splice(i--, 1);
                }
            }
            
            listener.dispose();
        };
        
        function _clear()
        {
            var ubound = m_listeners.length - 1;
            
            for (var i = ubound; i >= 0; i--)
            {
                m_listeners[i].dispose();
                m_listeners.pop();
            }
        }
    }
};
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();