﻿/*slideshow functionality
functionality
	In general, this set of functions is designed to rotate any number of pieces of content by swapping a piece's visibility
		with the next piece's visibility.  
		
	in the calling program there will be 3 sets of divs
		1. divs containing items currently displayed (aryThisSlideSet)
		2. divs contining itmems that will display next (i.e, the set the 'this' set will swap opacity with) (aryNextSlideSet)
		3. hidden divs containing all the content to be rotated through. Each piece is moved to the 'this' and 'next' arrays at
			various times where the rotaton acutally happens
		
implementation:
	startSlideInterval to set slides' initial states and to set the process in motion, pass
		inteveral = how long a view stays active (in milliseconds)
		transitionTime = how long the transition takes (in milliseconds)
		set of initialization arrays. They MUST be equal in length
		//var aryThisSlideSet;				//for example ['divThisContent','divThisTitle','divThisCaption']
		//var aryNextSlideSet;				//for example ['divNextContent','divNextTitle','divNextCaption']
		//var aryHiddenDivIdentifierSet;	//for example ['hdnContent_','hdnTitle_','hdnCaption_']
		
	if you have "next" and "last" buttons, hook them up to switchSlide
		directionToShow = 1 for next slide
		directionToShow = -1 for last slide
*/


var masterSlideIntervals = new Array();
function startSlideInterval(targetBase, aryThisSlideSet, aryNextSlideSet, aryHiddenDivIdentifierSet, interval, transitionTime) {
    //initialize opacities
	for (i=0; i<aryThisSlideSet.length; i++) {
	   changeOpac(100, aryThisSlideSet[i], 100, false);
	}
	for (i=0; i<aryNextSlideSet.length; i++) {
	   changeOpac(-100, aryNextSlideSet[i], 0, false);
	}
    masterSlideIntervals[masterSlideIntervals.length] = setInterval(function() {switchSlide(targetBase,aryThisSlideSet,aryNextSlideSet,aryHiddenDivIdentifierSet,transitionTime,null,null); }, interval); 
}


function switchSlide(targetBase, aryThisSlideSet, aryNextSlideSet, aryHiddenDivIdentifierSet, transition, indexToShow, directionToShow) {  
   //get the next slide ready
   //combine the 'this' and 'next' arrays
   var aryID = aryThisSlideSet.concat(aryNextSlideSet);
   //here, we define the arrays that will contain the opacity of each element at the start and at the end
   var aryShown = new Array();
   var aryHidden = new Array();
   var aryOpacStart = new Array();
   var aryOpacEnd = new Array();
   for (i=0; i<aryThisSlideSet.length; i++) {
		aryShown[i] = 100;
		aryHidden[i] = 0;
	}
   if (document.getElementById(aryNextSlideSet[0]).style.opacity<document.getElementById(aryThisSlideSet[0]).style.opacity) {    
   		//the 'this' elements start at 100 and the 'next' elements start at 0
		aryOpacStart = aryShown.concat(aryHidden);
		//the 'this' elements end at 0 and the 'next' elements end at 100
		aryOpacEnd = aryHidden.concat(aryShown);
        getNextSlide(targetBase, aryNextSlideSet, aryHiddenDivIdentifierSet, indexToShow, directionToShow); 
  } else {
	  	//the reverse case of above
		aryOpacStart = aryHidden.concat(aryShown);
		aryOpacEnd = aryShown.concat(aryHidden);
        getNextSlide(targetBase, aryThisSlideSet, aryHiddenDivIdentifierSet, indexToShow, directionToShow); 
  } 
  opacity_mult(aryID, aryOpacStart, aryOpacEnd, transition);
}


var curControl = new Array();            //there will be multiple controls calling this function. "curControl" keeps track of which one is calling
var slideIndex = new Array();               //slideIndex keeps track of where we are in the slide rotation for the given control
function getNextSlide(target, refArrayNextSlides, aryHiddenDivIdentifierSet, indexToShow, directionToShow ) {
   if ((indexToShow==null) && (directionToShow==null)) directionToShow = 1;    //if nothing defined, move forward one.
    
   var boolAddNewControl = true;
   var curControl_index;        
    	
    //see if the target control is defined in the curControl array.  
    curControl_index = indexOfID(curControl, target);
     //control doesn't exist, add a new one
     if (curControl_index == curControl.length) {
        curControl[curControl_index]=target;
        slideIndex[curControl_index]=0;
     }
     
     //we've defined the control and slide index OR determined the existing control and slide index
   var nextSlide=null;
   var iNextSlideIndex;      //this will be the index of the next slide to show
   var iTmp=100; 			 //we'll assume no more than 100 elements we're scrolling through.
   do { 
       if (indexToShow==null) {
            iNextSlideIndex = slideIndex[curControl_index]+directionToShow;
       } else {
             iNextSlideIndex = indexToShow;
       }  
	   
	   nextSlide = document.getElementById(aryHiddenDivIdentifierSet[0] + iNextSlideIndex);
       if (nextSlide==null) {
	   //if there's nothing at this slideIndex, we're iterated through all the content.  Now we search until we find content again.
            if (directionToShow==-1) {
                //Start with 100 and work back until you find a control
                nextSlide= document.getElementById(aryHiddenDivIdentifierSet[0] + iTmp);
                iNextSlideIndex=iTmp; 
                iTmp--; 
           } else {  
                nextSlide= document.getElementById(aryHiddenDivIdentifierSet[0] + '0');
                iNextSlideIndex=0; 
           }
       }
   } while (nextSlide==null);
   slideIndex[curControl_index]=iNextSlideIndex;   
  
  //now that we've found the next content, fill the appropriate array
//   for (itm in aryHiddenDivIdentifierSet) {
   for (i=0; i<aryHiddenDivIdentifierSet.length; i++) {
       var content = document.getElementById(aryHiddenDivIdentifierSet[i]+ iNextSlideIndex).innerHTML;
	   document.getElementById(refArrayNextSlides[i]).innerHTML = content;
   }
    
  return (curControl_index);     //return the index for the arrays - with each slideshow control on the page having its own index
}

function KillAllAutoSlides() {
    for (i=0; i< masterSlideIntervals.length; i++) {
            clearInterval(masterSlideIntervals[i]);
        }
}



//--- fade functions --//
var opacID = new Array();                                   //opacID keeps track of the ID of the controls that are fading
var opacIntervalID = new Array();                      //opacIntervalID keeps track of the IntervalID of fades associated with the controls that are fading
// opacity serves to set the parameters with which to fade the control that is passed. It then saves the ID and interval ID in lookup arrays
function opacity(id, opacStart, opacEnd, millisec) { 
    //speed for each frame 
    var speed = Math.round((millisec*5) / (opacStart-opacEnd)); 
    if (speed<0) speed=speed*-1; 

    //determine the direction for the blending, if start and end are the same nothing happens 
    var intervalID; 
    if(opacStart > opacEnd) { 
            intervalID = setInterval("changeOpac(-5,'" + id + "'," + opacEnd + ", true)",speed); 
    } else if(opacStart < opacEnd) { 
            intervalID = setInterval("changeOpac(5,'" + id + "'," + opacEnd + ", true)",speed); 
    } 
  
   //now track the intervalID associated with the controlID
   var  i = indexOfID(opacID, id); 
    if ((opacIntervalID[i]!=null)&&(opacIntervalID[i]>0))  clearInterval(opacIntervalID[i]);   //if the old transition is still active, clear it.
    opacIntervalID[i] = intervalID;
    opacID[i] = id;  
} 

//opacity_mult does the same thing as the "opacity" function, but does it for multiple controls at a time. 
//  the function even works for different opacity spans, BUT ONLY IF ALL THE SPANS ARE EQIDISTANT.
function opacity_mult(aryID, aryOpacStart, aryOpacEnd, millisec) {
    var speed = Math.round((millisec*5) / (aryOpacStart[0] - aryOpacEnd[0]));
     if (speed<0) speed=speed*-1; 
     
     var iID;
     var aryTransition = new Array();
     for (iID=0; iID<aryID.length; iID++) {
        aryTransition[iID] = 5;
        if (aryOpacStart[iID] > aryOpacEnd[iID]) aryTransition[iID] = -5;
     }
     intervalID = setInterval("changeOpac_mult('" + aryTransition.join() + "','" + aryID.join() + "'," + aryOpacEnd[0] + ")", speed);
     
    var i = indexOfID(opacID, 'aryPointer'+aryID[0]);
    if ((opacIntervalID[i]!=null)&&(opacIntervalID[i]>0))  clearInterval(opacIntervalID[i]);
    opacIntervalID[i] = intervalID;
    opacID[i] = 'aryPointer'+aryID[0];
}

//change the opacity for different browsers 
function changeOpac(opacChange, id, endOpacity, boolCheckClearInterval) { 
    var object = document.getElementById(id).style; 
    var curOpacity = object.opacity;
    if (curOpacity==null) curOpacity=1;  
    var newOpacity = (curOpacity*100) + parseInt(opacChange); 
    if (newOpacity>100) newOpacity=100;
    if (newOpacity < 0) newOpacity= 0;
      
    object.opacity = (newOpacity / 100); 
    object.MozOpacity = (newOpacity / 100); 
    object.KhtmlOpacity = (newOpacity / 100); 
    object.filter = "alpha(opacity=" + newOpacity + ")"; 
    //object.filter  = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')';
    
   //now handle special cases - newOpacity is 0 (hide the element), or at the end  of the transition (clear the interval)
   if (newOpacity==0) {
        object.display='none';
        if (boolCheckClearInterval) clearIntervalForId(id); 
   } else {
       object.display='block';
       if (boolCheckClearInterval) {
            if (((opacChange>1) && (newOpacity>= endOpacity)) || ((opacChange<1) && (newOpacity<=endOpacity))) {
                clearIntervalForId(id);
            }  
        }     
    }
   return (newOpacity); 
} 

//changeOpac_mult does the same thing as changeOpac, but does it for multiple controls at a time
function changeOpac_mult(sOpacChange, sID, endOpacity) {
    var iID;
    var newOpacity=-1; 
    var aryOpacChange = sOpacChange.split(",");
    var aryID = sID.split(",");  
    // we just want the newOpacity returned for the first element. That's the one we'll use for the test. 
    for (iID=0; iID<aryID.length; iID++) {
        if (newOpacity==-1) { 
            newOpacity = changeOpac(aryOpacChange[iID], aryID[iID], endOpacity, false);
        } else {
            changeOpac(aryOpacChange[iID], aryID[iID], endOpacity, false);
       } 
   }    
   
    if (((aryOpacChange[0]>1) && (newOpacity>= endOpacity)) || ((aryOpacChange[0]<1) && (newOpacity<=endOpacity))) {
        clearIntervalForId( 'aryPointer'+aryID[0]);
    }  
}


function clearIntervalForId(myId) {
    for (i=0; i< opacIntervalID.length; i++) {
        if (opacID[i]==myId) { 
            clearInterval(opacIntervalID[i]);
            opacIntervalID[i]=0;
            break;
        }
    } 
}


//this function is used when there are two arrays, one containing an ID, the other containing a value associated with that ID.  
//  meaning that the two arrays must stay in sync.  This function looks at the ID array to determine if the ID passed is already
// contained in that array. If so, it returns the ID. If not, it returns the length of the array (presumably the next function will use this
// to add the new ID to the end of the array)
function indexOfID(ary, id) {
    var newIndex = ary.length
    for (i=0; i<newIndex; i++) {
        if (ary[i]==id) {
            return (i);
        }
     }
    return (newIndex);
}

//****************************End fade functions *************************