/******************************************************************************
 *                Copyright (c) 2005, Bazzisoft
 ******************************************************************************
 * Effects.js
 *
 * JavaScript class with effect functions.
 *
 *
 * $Id$
 *
 */

//*************************************************************************
//* Effects
//*
//*

function Effects()
{
}

//*************************************************************************
//* ShuffleArray()
//*
//* Randomizes an array.
//*
//*

Effects.ShuffleArray = function(o)
{
    for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x)
        ;
        
    return o;
}  

//*************************************************************************
//* Tween()
//*
//* Tweens the specified attribute of an element between the specified values.
//*
//* attr        - One of: 'opacity'
//* elem        - The id/element to tween
//* startval    - Initial value
//* endval      - End value
//* duration    - msec for effect
//* callback    - call when effect is complete
//* curval      - reserved. leave empty.
//*

Effects.Tween = function(attr, elem, startval, endval, duration, callback, curval)  
{
    elem = Utilities.GetElem(elem);
    
    var frames = duration / 67;
    var step = (endval - startval) / frames;

    if ( curval == undefined )
        curval = startval;
    else
    {
        curval = curval + step;
        if ( (startval <= endval && curval >= endval) || (startval > endval && curval <= endval) )
            curval = endval; 
    }        
    
    switch ( attr )
    {
        case 'opacity':
            Effects.SetOpacity(elem, curval);
            break;
    }
    
    if ( curval == endval && callback )
        callback();
    else
    {
        var fn = function() { Effects.Tween(attr, elem, startval, endval, duration, callback, curval); }
        setTimeout(fn, 67);
    }         
}

//*************************************************************************
//* SetOpacity()
//*
//* Sets the opacity of an element, 0-1.
//*

Effects.SetOpacity = function(elem, alpha) 
{
    var elem = Utilities.GetElem(elem);

    elem.style.opacity = alpha;
    elem.style.filter = 'alpha(opacity=' + alpha*100 + ')';
}

//*************************************************************************
//* RotateImage()
//*
//* Rotates the specified image, using the given fade time & list of
//* image URLs.
//*
//* img_id          - The ID of the img tag to rotate.
//* img_srcs        - Array of image URLs to preload & rotate
//* show_time_msec  - Time to show each image
//* fade_time_msec  - Time for fade effect when changing images
//* shuffle         - Whether to shuffle img array

Effects.RotateImageList = new Object();

Effects.RotateImage = function(img_id, img_srcs, show_time_msec, fade_time_msec, shuffle)
{
    if ( show_time_msec == undefined )
        show_time_msec = 5000;
        
    if ( fade_time_msec == undefined )
        fade_time_msec = 1000;
        
    if ( shuffle )
        Effects.ShuffleArray(img_srcs);
                
    Effects.RotateImageList[img_id] = { id:img_id, idx:0, srcs:img_srcs, show:show_time_msec, fade:fade_time_msec };
    
    var preload = new Preloader();
    for ( var i in img_srcs )
        preload.AddImage(img_srcs[i]);
        
    document.getElementById(img_id).src = img_srcs[0];
    
    var fn = function() { Effects.RotateImageFn(img_id, 'rotate'); }; 
    setTimeout(fn, show_time_msec);   
} 

Effects.RotateImageFn = function(id, operation)
{
    var entry = Effects.RotateImageList[id];
    
    if ( entry.fade <= 0 )
    {
        entry.idx = (entry.idx + 1) % entry.srcs.length;
        document.getElementById(id).src = entry.srcs[entry.idx];
        Effects.RotateImageList[id] = entry;
        
        var fn = function() { Effects.RotateImageFn(id, 'rotate'); }; 
        setTimeout(fn, entry.show);
        return;   
    }
    
    // Fade effect
    
    if ( operation == 'rotate' )
    {
        var fn = function() { Effects.RotateImageFn(id, 'fadein') };
        Effects.Tween('opacity', id, 1, 0, entry.fade / 2, fn);
    }
    else if ( operation == 'fadein' )
    {
        entry.idx = (entry.idx + 1) % entry.srcs.length;
        document.getElementById(id).src = entry.srcs[entry.idx];
        Effects.RotateImageList[id] = entry;
        
        var fn = function() { Effects.RotateImageFn(id, 'show'); }; 
        Effects.Tween('opacity', id, 0, 1, entry.fade / 2, fn);   
    }
    else if ( operation == 'show' )
    {
        var fn = function() { Effects.RotateImageFn(id, 'rotate'); }; 
        setTimeout(fn, entry.show);
    }
}

//*************************************************************************
//* CenterElementOnScreen()
//*
//* Centers the given element on screen using absolute positioning styles.
//*
//* elem                - element object or id to get details for
//*

Effects.CenterElementOnScreen = function(elem)
{
    var elem = Utilities.GetElem(elem);
    
    var screenW = ( top.innerWidth ? top.innerWidth : top.document.documentElement.clientWidth );
    var screenH = ( top.innerHeight ? top.innerHeight : top.document.documentElement.clientHeight );
    var elemW = elem.offsetWidth;
    var elemH = elem.offsetHeight;
    
    elem.style.left = (Math.floor((screenW - elemW) / 2) + top.document.documentElement.scrollLeft) + 'px';
    elem.style.top = (Math.floor((screenH - elemH) / 2) + top.document.documentElement.scrollTop) + 'px';
}

//*************************************************************************
//* ShowDarkScreenOverlay()
//*
//* Darkens the screen by placing a big overlay with 70% opacity.
//*

Effects.ShowDarkScreenOverlay = function(show)
{
    var id = 'jsEffects_DarkScreenOverlay';
    var div = top.document.getElementById(id);
    
    if ( !div )
    {
        var div = top.document.createElement('DIV');
        div.id = id;
        div.style.display = 'none';
        div.style.position = 'absolute';
        div.style.top = '0px';
        div.style.left = '0px';
        div.style.backgroundColor = 'black';
        Effects.SetOpacity(div, 0.65);
        top.document.body.insertBefore(div, top.document.body.firstChild);
    }
    
    var screenW = ( top.innerWidth ? top.innerWidth : top.document.documentElement.clientWidth );
    var screenH = ( top.innerHeight ? top.innerHeight : top.document.documentElement.clientHeight );
    
    div.style.width = Math.max(top.document.body.scrollWidth, screenW) + 'px';
    div.style.height = Math.max(top.document.body.scrollHeight, screenH) + 'px';
    div.style.display = ( show ? '' : 'none' );
}      

//*************************************************************************
//* ShowDivPopup()
//*
//* Shows the specified DIV center screen as a popup, darkening the
//* screen in the background.
//*
//* show should be 'true' or 'false' to show/hide the popup.
//* select_ids should be a string or array of select box ids which need to
//* be hidden beneath the popup (IE6 bug). Otherwise leave out. 
//*

Effects.ShowDivPopup = function(div_id, show, select_ids) 
{
    if ( show && select_ids )
        Effects.HideElements(select_ids);
    else if ( !show )
        Effects.RestoreElements();

    var div = Utilities.GetElem(div_id);
    
    div.style.position = 'absolute';
    div.style.left = '0px';
    div.style.top = '0px';

    if ( show )
    {    
        Effects.ShowDarkScreenOverlay(true);
        div.style.display = 'block';
        Effects.CenterElementOnScreen(div);
    }
    else
    {
        div.style.display = 'none';
        Effects.ShowDarkScreenOverlay(false);
    }
}

//*************************************************************************
//* ShowIFramePopup()
//*
//* Shows the specified URL center screen in a popup IFrame.
//* If URL is undefined/false, removes the popup.
//*
//* options is an object with the following optional attributes:
//*     width:<pixels>
//*     height:<pixels>
//*     border:<true|false>
//*     bgcolor:<#xxxxxx>
//*     title:<heading>
//*     close:<true|false> 
//*
//* select_ids should be a string or array of select box ids which need to
//* be hidden beneath the popup (IE6 bug). Otherwise leave out. 
//*

Effects.ShowIFramePopup = function(url, options, select_ids) 
{
    if ( show && select_ids )
        Effects.HideElements(select_ids);
    else if ( !show )
        Effects.RestoreElements();


    // Show black screen overlay
    
    Effects.ShowDarkScreenOverlay(url);

    // Default options
    
    options = ( options ? options : {} );
    options.width = ( options.width ? options.width : 550 );
    options.height = ( options.height ? options.height : 600 );
    options.border = ( options.border ? options.border : true );
    options.bgcolor = ( options.bgcolor ? options.bgcolor : 'white' );
    options.title = ( options.title ? options.title : '' );
    options.close = ( options.close ? options.close : true );
    
    var iddiv = 'jsEffects_IFramePopupDiv';
    var idtitlediv = 'jsEffects_IFramePopupTitleDiv'; 
    var idframe = 'jsEffects_IFramePopupFrame';
    var div = top.document.getElementById(iddiv);
    var titlediv = top.document.getElementById(idtitlediv);
    var frame = top.document.getElementById(idframe);

    // Create the popup?
    
    if ( !div )
    {
        div = top.document.createElement('DIV');
        div.id = iddiv;
        div.style.display = 'none';
        div.style.position = 'absolute';
        div.style.top = '0px';
        div.style.left = '0px';        
        top.document.body.appendChild(div);

        titlediv = top.document.createElement('DIV');
        titlediv.id = idtitlediv;
        titlediv.style.fontSize = '0px';
        div.appendChild(titlediv);
        
        frame = top.document.createElement('IFRAME');
        frame.id = idframe;
        frame.frameBorder = 0;
        div.appendChild(frame);
    }

    // Close the popup?
    
    if ( !url )
    {
        div.style.display = 'none';
        frame.src = '';
        return;
    }    
    
    // Implement options

    div.style.backgroundColor = options.bgcolor;
    
    if ( options.border )
        div.style.border = '2px solid #808080';
        
    if ( options.title || options.close )
    {
        var html = '';
        html += '<div style="background-color:#D4D0D0; border-bottom:1px solid #808080; margin-bottom:12px; padding:4px 8px; text-align:left; color:#606060; font-family:verdana; font-size:9pt; font-weight:bold;">';
        
        if ( options.close )
            html += '<a style="float:right; color:#606060; text-decoration:none; font-family:verdana; font-size:9pt; font-weight:normal;" href="#" onmouseover="this.style.textDecoration=\'underline\';" onmouseout="this.style.textDecoration=\'none\';" onclick="Effects.ShowIFramePopup(false); return false;">close</a>';
        
        html += ( options.title ? options.title : '&nbsp;' );
        html += '</div>';
        
        titlediv.innerHTML = html;
    }
    else
        titlediv.innerHTML = '';
    
    frame.width = options.width;
    div.style.width = options.width + 'px';
    frame.height = options.height;
    
    frame.src = url;   
    div.style.display = '';
    Effects.CenterElementOnScreen(div);
}

//*************************************************************************
//* HideElements()
//*
//* Sets the specified elements to invisible, and saves their IDs
//* for restore elements later.
//*
//* ids - String or Array of string element IDs
//*

Effects.HideElementsSavedIds = null;

Effects.HideElements = function(ids) 
{
    var i;
    
    if ( !(ids instanceof Array) )
        ids = new Array(ids);
        
    Effects.HideElementsSavedIds = ids;
    
    for ( i = 0; i < ids.length; i++ )
    {
        document.getElementById(ids[i]).style.visibility = 'hidden';
    }    
}

//*************************************************************************
//* RestoreElements()
//*
//* Restores the saved hidden elements.
//*

Effects.RestoreElements = function()
{
    var i;
    
    if ( !Effects.HideElementsSavedIds )
        return;
    
    for ( i = 0; i < Effects.HideElementsSavedIds.length; i++ )
        document.getElementById(Effects.HideElementsSavedIds[i]).style.visibility = '';
            
    Effects.HideElementsSavedIds = null;
} 


