/******************************************************************************
 *                Copyright (c) 2005, Bazzisoft
 ******************************************************************************
 * RolloverSetMulti.js
 *
 * JavaScript class to support multiple rollovers (images, color style, and
 * backgroundColor style). It allows you to modify the rollover for
 * mouse up, down, over, out and "selected" events.
 * 
 * Also supports a "selected" item, eg making the "home" image a different
 * color when you're on the home page.
 *
 *
 * $Id: RolloverSetMulti.js 109 2006-11-30 09:27:18Z barak $
 *
 */


//*************************************************************************
//* RolloverSetMulti()
//*
//* Constructor. Initialises a new rollover set. Use one set per
//* menu or similar grouping.
//*

function RolloverSetMulti()
{
    this.m_rollovers = new Array();
    this.m_selected = null;
    this.m_timer_id = null;
}

//*************************************************************************
//* AddItem()
//*
//* This method adds a rollover item (eg menu item) to the set.
//* Call this once per image, link or whatever to add it to the set,
//* and once for each event that image should support.
//*
//* item - An object of the RolloverItem* classes. Use the correct one
//*        based on the type of rollover you want.
//* evt  - The event to associate that rollover state with. One of:
//*        "mouseover", "mouseout", "mouseup", "mousedown", "selected"
//*

RolloverSetMulti.prototype.AddItem = function(evt, item)
{
    var oldfn;
    var first = false;
    
    // Save this item in the set
    
    item.m_parent = this;
    
    if ( !this.m_rollovers[item.m_id] )
    {
        first = true;
        this.m_rollovers[item.m_id] = new Array();
    }
    
    this.m_rollovers[item.m_id][evt] = item;
    
    // Initialise the item in this state if it is the first state given
    
    if ( first )
        item.Set();
    
    // Register appropriate rollover function
    
    switch ( evt )
    {
        case 'mouseover':   
            oldfn = item.m_obj.onmouseover;
            item.m_obj.onmouseover = function() { if ( oldfn ) oldfn(); RolloverSetMulti.Exec(item, 'mouseover'); };  
            break;
            
        case 'mouseout':    
            oldfn = item.m_obj.onmouseout;
            item.m_obj.onmouseout = function() { if ( oldfn ) oldfn(); RolloverSetMulti.Exec(item, 'mouseout'); };    
            break;
            
        case 'mousedown':   
            oldfn = item.m_obj.onmousedown;
            item.m_obj.onmousedown = function() { if ( oldfn ) oldfn(); RolloverSetMulti.Exec(item, 'mousedown'); };  
            break;
            
        case 'mouseup':     
            oldfn = item.m_obj.onmouseup;
            item.m_obj.onmouseup = function() { if ( oldfn ) oldfn(); RolloverSetMulti.Exec(item, 'mouseup'); };      
            break;
    }
}

//*************************************************************************
//* AddItemRollover()
//*
//* This helper method creates a mouseover/mouseout rollover given
//* items for mouseout/mouseover and optionally selected events.
//*
//* Call this once per rollover.
//*
//* item_out  - An object of the RolloverItem* classes, for the 'off' state.
//* item_over - An object of the RolloverItem* classes, for the 'on' state.
//* item_sel  - (optional) An object of the RolloverItem* classes, for 
//*             the 'selected' state.
//*

RolloverSetMulti.prototype.AddItemRollover = function(item_out, item_over, item_sel)
{
    this.AddItem('mouseout', item_out);
    this.AddItem('mouseover', item_over);
    
    if ( item_sel )
        this.AddItem('selected', item_sel);
}

//*************************************************************************
//* AddItemButton()
//*
//* This helper method creates a mouseup/mousedown button given
//* items for up/down and optionally selected events.
//*
//* Call this once per button.
//*
//* item_up   - An object of the RolloverItem* classes, for the 'up' state.
//* item_down - An object of the RolloverItem* classes, for the 'pressed' state.
//* item_sel  - (optional) An object of the RolloverItem* classes, for 
//*             the 'selected' state.
//*

RolloverSetMulti.prototype.AddItemButton = function(item_up, item_down, item_sel)
{
    this.AddItem('mouseup', item_up);
    this.AddItem('mouseout', item_up);
    this.AddItem('mousedown', item_down);
    
    if ( item_sel )
        this.AddItem('selected', item_sel);
}

//*************************************************************************
//* SetSelected()
//*
//* This function sets the selected item for the page. This is the item
//* that is either always on or displays a third color/image when no
//* rollovers are activated, indicating the current page.
//*
//* tag_id - the id of the element which is to be selected, as supplied
//*          to the appropriate RolloverItem* object.
//*

RolloverSetMulti.prototype.SetSelected = function(tag_id)
{
    var i;
    
    if ( !this.m_rollovers[tag_id] )
        return;
    
    this.m_selected = tag_id;
    this.m_rollovers[tag_id]['selected'].Set();
}

//*************************************************************************
//* Exec()
//*
//* Static function that is called by event handlers. Calls the 
//* appropriate RolloverSetMulti object's Execute function.
//*

RolloverSetMulti.Exec = function(item, event_type)
{
    // Find item's parent RolloverSetMulti object, and call
    // its Execute function.

    item.m_parent.Execute(item, event_type);
}

//*************************************************************************
//* Execute()
//*
//* This is the rollover event handler. It switches the rollover
//* images/colors appropriately.
//*

RolloverSetMulti.prototype.Execute = function(item, event_type)
{
    switch ( event_type )
    {
        case 'mouseout':
        case 'mouseup':
        
            // If the item is not the selected item, switch it back to off

            if ( item.m_id != this.m_selected )
                item.Set();
                
            // If there is a selected item, set it back to 'selected' state
            // but only after a 100ms timeout to avoid flickering
            // Timeout can be cancelled by another mouseover event.
            
            if ( this.m_selected )
            {
                sel_item = this.m_rollovers[this.m_selected]['selected'];
                this.m_timer_id = setTimeout('sel_item.Set()', 100);
            }
            break;
         
        case 'mouseover':
        case 'mousedown':
        
            // Clear any selected setting timeout, as we need to reset it now
            
            clearTimeout(this.m_timer_id);

            // Turn off the selected item, unless it's this one
            
            if ( this.m_selected && item.m_id != this.m_selected )
                this.m_rollovers[this.m_selected]['mouseout'].Set();
            
            // Turn on the item that triggered the mouseover
        
            item.Set();
            
            break;
            
        default:
            item.Set();
            break;
    }
}



//***********************************************************************//



//*************************************************************************
//* RolloverItemImage()
//*
//* Wrapper class for Image rollover items. Create a class for every
//* menu item, (and every state), with "new". Then, pass it to the 
//* RolloverSetMulti.AddItem() method.
//*
//* tag_id       - id of the <img> element
//* imgsrc       - the SRC of the rollover state image
//*

function RolloverItemImage(tag_id, imgsrc)
{
    // Initialise class variables
    
    this.m_parent = null;
    this.m_id = tag_id;
    this.m_obj = document.getElementById(tag_id);
    this.m_src = imgsrc;
           
    // Preload image
    
    this.m_img_preload = new Image();
    this.m_img_preload.src = imgsrc;
}

//*************************************************************************
//* Set()
//*
//* Private function called by RolloverSetMulti to change the state of the
//* element during rollover events.
//*

RolloverItemImage.prototype.Set = function()
{
    var src1 = Utilities.SplitURL(this.m_obj.src);
    var src2 = Utilities.SplitURL(this.m_src);
    
    if ( src1[2] != src2[2] )
        this.m_obj.src = this.m_src;
}




//***********************************************************************//




//*************************************************************************
//* RolloverItemImageSeries()
//*
//* Rollover item that enables on image rollover to trigger multiple
//* images. 
//* Create a class for every rollover set, add an image items to it.
//* Then, pass it to the RolloverSetMulti.AddItem() method.
//*
//*

function RolloverItemImageSeries()
{
    this.m_parent = null;
    this.m_id = null;
    this.m_obj = null;   
    this.m_images = new Array();    
}


//*************************************************************************
//* AddImage()
//*
//* Adds a new image to the rollover set. The first image added is the
//* trigger item.
//*
//* tag_id       - id of the <img> element
//* imgsrc       - the SRC of the rollover state image
//*

RolloverItemImageSeries.prototype.AddImage = function(tag_id, imgsrc)
{
    // Create a new RolloverItemImage object to store and preload the image
    
    var img = new RolloverItemImage(tag_id, imgsrc);
    
    // If this is the first item, it is our trigger
    
    if ( this.m_images.length == 0 )
    {
        this.m_id = img.m_id;
        this.m_obj = img.m_obj;
    }
    
    // Add to array of images
    
    this.m_images[this.m_images.length] = img;
}

//*************************************************************************
//* Set()
//*
//* Private function called by RolloverSetMulti to change the state of the
//* element during rollover events.
//*

RolloverItemImageSeries.prototype.Set = function()
{
    var i;
    
    for ( i = 0; i < this.m_images.length; i++ )
        this.m_images[i].Set();
}



//***********************************************************************//



//*************************************************************************
//* RolloverItemColor()
//*
//* Wrapper class for style color rollover items. Create a class for every
//* menu item and state, with "new". Then, pass it to the RolloverSetMulti.AddItem()
//* method.
//*
//* tag_id         - id of the element
//* color          - CSS color for this state
//*

function RolloverItemColor(tag_id, color)
{
    // Initialise class variables
    
    this.m_parent = null;
    this.m_id = tag_id;
    this.m_obj = document.getElementById(tag_id);
    this.m_color = color;
}

//*************************************************************************
//* Set()
//*
//* Private function called by RolloverSetMulti to change the state of the
//* element during rollover events.
//*

RolloverItemColor.prototype.Set = function()
{
    if ( this.m_obj.style.color != this.m_color )
        this.m_obj.style.color = this.m_color;
}



//***********************************************************************//



//*************************************************************************
//* RolloverItemBackgroundColor()
//*
//* Wrapper class for style background-color rollover items. Create a class for every
//* menu item and state, with "new". Then, pass it to the RolloverSetMulti.AddItem()
//* method.
//*
//* tag_id         - id of the element
//* color          - CSS color for this state
//*

function RolloverItemBackgroundColor(tag_id, color)
{
    this.m_parent = null;
    this.m_id = tag_id;
    this.m_obj = document.getElementById(tag_id);
    this.m_color = color;
}

//*************************************************************************
//* Set()
//*
//* Private function called by RolloverSetMulti to change the state of the
//* element during rollover events.
//*

RolloverItemBackgroundColor.prototype.Set = function(state)
{
    if ( this.m_obj.style.backgroundColor != this.m_color )
        this.m_obj.style.backgroundColor = this.m_color;
}



//***********************************************************************//



//*************************************************************************
//* RolloverItemBackgroundImage()
//*
//* Wrapper class for style background-imagee rollover items. 
//* Create a class for every menu item, (and every state), with "new". 
//* Then, pass it to the RolloverSetMulti.AddItem() method.
//*
//* tag_id       - id of the element
//* imgsrc       - the SRC of the rollover state image to use as background-image
//*

function RolloverItemBackgroundImage(tag_id, imgsrc)
{
    // Initialise class variables
    
    this.m_parent = null;
    this.m_id = tag_id;
    this.m_obj = document.getElementById(tag_id);
    this.m_src = imgsrc;
           
    // Preload image
    
    this.m_img_preload = new Image();
    this.m_img_preload.src = imgsrc;
}

//*************************************************************************
//* Set()
//*
//* Private function called by RolloverSetMulti to change the state of the
//* element during rollover events.
//*

RolloverItemBackgroundImage.prototype.Set = function()
{
    var new_url = 'url(' + this.m_src + ')';
    
    if ( this.m_obj.style.backgroundImage != new_url )
        this.m_obj.style.backgroundImage = new_url;
}



//***********************************************************************//



//*************************************************************************
//* RolloverItemCSSClass()
//*
//* Wrapper class for CSS 'class' replacement rollover items. 
//* Create a class for every menu item, (and every state), with "new". 
//* Then, pass it to the RolloverSetMulti.AddItem() method.
//*
//* tag_id       - id of the element
//* css_class    - the CSS class to use for the rollover
//*

function RolloverItemCSSClass(tag_id, css_class)
{
    // Initialise class variables
    
    this.m_parent = null;
    this.m_id = tag_id;
    this.m_obj = document.getElementById(tag_id);
    this.m_css = css_class;
}

//*************************************************************************
//* Set()
//*
//* Private function called by RolloverSetMulti to change the state of the
//* element during rollover events.
//*

RolloverItemCSSClass.prototype.Set = function()
{
    if ( this.m_obj.className != this.m_css )
        this.m_obj.className = this.m_css;
}

