// TODO:  Events keep getting added on top of each other.  Maybe keep references to elements where it has already been applied with each rule?
//
// Use a copy of EventCache?

try
{
var MyBehaviour =
{
    rules : new Array

    // Used to remove existing events before a refresh so we don't have duplicate events.
    ,doneRules : new Array

    ,addRules : function( newRules )
    {
        MyBehaviour.rules.push( newRules );
    }

    ,init : function()
    {
        addLoadEvent( function() { MyBehaviour.refresh(); } );
    }

    ,refresh : function()
    {
        var i, rule;

        // alert( "ANONYMOUS MyBehaviour.doneRules.length:  " + MyBehaviour.doneRules.length );

        // Remove existing events before a refresh so we don't have duplicate events.
        for ( i = 0; i < MyBehaviour.doneRules.length; i++ )
        {
            rule = MyBehaviour.doneRules[ i ];

            // myAlert( "ANONYMOUS getProperties(MyBehaviour.doneRules[i], i, 'el type action'):  " + getProperties(MyBehaviour.doneRules[i], i, 'el type action') );
            // myAlert( "ANONYMOUS rule.type:  " + rule.type );

            removeEvent( rule.el, rule.type, rule.action );
        }


        MyBehaviour.doneRules = new Array;

        for ( var i = 0; i < MyBehaviour.rules.length; i++ )
        {
            if ( exists( MyBehaviour.rules[ i ] ) )
            {
                MyBehaviour.processRules( MyBehaviour.rules[ i ] );
            }
        }
    }

    ,addRemovableEvent : function( element, type, action )
    {
        addEvent( element, type, action );

        // To eventually remove the event in case of a refresh
        var processedRule = new Object;

        processedRule.el     = element;
        processedRule.type   = type;
        processedRule.action = action;

        /*
        if ( type == 'change' )
        {
            alert( "ANONYMOUS 'hello':  " + 'hello' );
            alert( "ANONYMOUS processedRule.action == action:  " + ( processedRule.action == action ) );
        }
         */

        MyBehaviour.doneRules.push( processedRule );
    }

    ,processRules : function( rules )
    {
        try
        {
        // myAlert( "processRules rules.each:  " + rules.each );
        // myAlert( "processRules rules:  " + rules );
        // myAlert( "processRules rules.length:  " + rules.length );

        for ( var rule in rules )
        {
            // myAlert( "processRules rule:  " + rule );
            // myAlert( "processRules rules[ rule ]:  " + rules[ rule ] );

            var selectors = rule.split( / *, */ );

            // myAlert( "processRules selectors:  " + selectors );

            selectors.each( function( selector )
                            {
                                // myAlert( "ANONYMOUS selector:  " + selector );
                                // myAlert( "ANONYMOUS rules[ rule ]:  " + rules[ rule ] );

                                var parts = selector.split( / *: */ );

                                // myAlert( "ANONYMOUS parts.length:  " + parts.length );

                                if ( parts.length > 0 )
                                {
                                    // myAlert( "ANONYMOUS parts[ 0 ]:  " + parts[ 0 ] );

                                    var elements = cssQuery( parts[ 0 ] );

                                    // myAlert( "ANONYMOUS elements.length:  " + elements.length );

                                    elements.each( function( element )
                                                   {
                                                       if ( parts.length == 1 )
                                                       {
                                                           rules[ rule ]( element );
                                                       }
                                                       else
                                                       {
                                                           var ruleFunction = rules[ rule ];
                                                           // myAlert( "ANONYMOUS parts[ 1 ]:  " + parts[ 1 ] );
                                                           // myAlert( "Here! element.nodeName:  " + element.nodeName );
                                                           var func = function( event )
                                                           {
                                                               ruleFunction( getEventTarget( event ), event );
                                                           };

                                                           // myAlert( "func parts[1]:  " + parts[1] );
                                                           MyBehaviour.addRemovableEvent( element, parts[ 1 ], func );
                                                       }
                                                   }
                                                 );
                                }
                            }
                          );
        }
        }
        catch ( err )
        {
            showProperties( err );
        }
    }
};

MyBehaviour.init();
}
catch ( e )
{
    alert( "ANONYMOUS getProperties(e):  " + getProperties(e) );
}


// Variation of addEvent that can take a selector rather than a specific element.
function addGenericEvent( selector, eventType, handler )
{
    if ( typeof selector == 'string' )
    {
        var elements = cssQuery( selector );

        for ( var i = 0; i < elements.length; i++ )
        {
            addGenericEvent( eventType, elements[ i ], handler );
        }
    }
    else
    {
        MyBehaviour.addRemovableEvent( selector, eventType, handler );
    }
}

// Accepts either a selector or an element and a handler function.  If none is provided, adds the class 'mouseover' to the elements.
function addMouseOver( selector, handler )
{
    addGenericEvent( selector, 'mouseover', exists( handler ) ? handler : function() { addClassName( this, 'mouseover' ); } );
}

// Accepts either a selector or an element and a handler function.  If none is provided, removes the class 'mouseover' from the elements.
function addMouseOut( selector, handler )
{
    addGenericEvent( selector, 'mouseout', exists( handler ) ? handler : function() { removeClassName( this, 'mouseover' ); } );
}

// Shortcut for adding a mouseover and a mouseout.  Provide neither handler if simply adding and removing the class 'mouseover' is desired.
function addHover( selector, handler1, handler2 )
{
    addMouseOver( selector, handler1 );
    addMouseOut( selector, handler2 );
}

// The addFocus, addBlur and addFocusBlur behave the exact same way as the addMouseOver, addMouseOut and addHover series of functions, except for the focus and
// blur events.
function addFocus( selector, handler )
{
    addGenericEvent( selector, 'focus', exists( handler ) ? handler : function() { addClassName( this, 'focus' ); } );
}

function addBlur( selector, handler )
{
    addGenericEvent( selector, 'blur', exists( handler ) ? handler : function() { removeClassName( this, 'focus' ); } );
}

function addFocusBlur( selector, handler1, handler2 )
{
    addFocus( selector, handler1 );
    addBlur( selector, handler2 );
}
