//Daniel Krawisz
//This file contains functions to run a menu whose subheaders fade in and out
//with a delay. 

      //From http://www.howtocreate.co.uk/tutorials/javascript/combinedpage#domstructure*/
      // This function takes an id from a div and a reference to a document.	//
      // and finds the correct reference depending on which browser you got.	//
      function getRefToDiv(divID, oDoc) {
        if( document.getElementById ) {
          return document.getElementById(divID); }
        if( document.all ) {
          return document.all[divID]; }
        if( !oDoc ) { oDoc = document; }
        if( document.layers ) {
          if( oDoc.layers[divID] ) { return oDoc.layers[divID]; } else {
            //repeatedly run through all child layers
            for( var x = 0, y; !y && x < oDoc.layers.length; x++ ) {
              //on success, return that layer, else return nothing
              y = getRefToDiv(divID,oDoc.layers[x].document); }
          return y; } }
        return false;
      }

//modified from http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/
//This function takes a link to a DOM element and a string with a CSS style
//sheet parameter and finds the default style for that parameter for that element.      
function getStyle(oElm, strCssRule){
	if(document.defaultView && document.defaultView.getComputedStyle){
		return document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	}
	else if(oElm.currentStyle){
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
			return p1.toUpperCase();
		});
		return oElm.currentStyle[strCssRule];
	}
}

//The amount of time it takes an element to fade.
var TimeToFade = 300.0;
//The delay before an element fades out after the mouse moves off of it.
var FadeOutDelay = 500.0;
var DefaultZIndex = 10;

//Checks whether an element has a fade state set and sets one if it is not. 
function checkFadeState(element) {
  if(!element.FadeState) {
    if(!element.style.display) {
      element.style.display = getStyle(element, 'display');
      //alert('display set to ' + element.style.display);
    }
    if(!element.style.opacity) {
      element.style.opacity = getStyle(element, 'opacity');
      //alert('opacity set to ' + element.style.opacity);
    }
    if(element.style.display === 'none') {
      element.style.opacity = 0;
      element.style.filter = 'alpha(opacity = 0)';
      element.FadeState = -2;
    } else if (element.style.opacity == 0 || element.style.opacity == '0') {
      element.style.display = 'none';
      element.style.filter = 'alpha(opacity = 0)';
      element.FadeState = -2;
    } else {
      element.style.display = 'block';
      element.style.opacity = 1;
      element.style.filter = 'alpha(opacity = 100)';
      element.FadeState = 2;
    }
  }
}

//function recursiveCheckFadeState

//The next five functions are modified from
//http://www.switchonthecode.com/tutorials/javascript-tutorial-simple-fade-animation
//This takes a string that gives the id of an element and begins to fade it in
//or out. 
function showHideDivFade(eid)
{
  var element = document.getElementById(eid);
  if(element == null)
    return;
   
  checkFadeState(element);
  if(element.FadeTimeLeft == null) element.FadeTimeLeft = 0;
    
  if(element.FadeState == 1 || element.FadeState == -1) {
    element.FadeState = element.FadeState == 1 ? -1 : 1;
    element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft;
  } else {
    element.FadeState = element.FadeState == 2 ? -1 : 1;
    element.FadeTimeLeft = TimeToFade;
    setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);
  }  
}

//Takes the id of an element as a string and fades in that element.
function showDivFade(eid) {
  var element = document.getElementById(eid);
  if(element == null)
    return;

  //alert("fade in called for eid: "+ eid);
  checkFadeState(element);   
  if(element.FadeTimeLeft == null) element.FadeTimeLeft = 0;
  element.style.display = 'block';
  element.DelayedFadeOut = 0;
  element.style.zIndex = ++DefaultZIndex;

  if(element.FadeState == -1) {
    element.FadeState = 1;
    element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft;
    // alert("fade state of " + eid + "changed to -1.\tFade time left changed to " + element.FadeTimeLeft);
  } else if(element.FadeState == -2) { 
    //alert("starting animation");
    element.FadeState = 1;
    element.FadeTimeLeft = TimeToFade; 
    setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);
  } 
}

//Takes the id of an element as a string and sets it to fade out after a delay.
function hideDivFade(eid) {
  var element = document.getElementById(eid);
  if(element == null)
    return;

  checkFadeState(element);
  //alert("the fade state of " + eid + " is " + element.FadeState);
  if(element.FadeState < 0) return;    
  element.DelayedFadeOut = 1;

  //console.log("Delayed fade out set for " + eid + " with id " + element.FadeOutCount);
  //clearTimeout(element.timeout);
  element.timeout = setTimeout("fadeOutDelayed('" + eid + "')", FadeOutDelay); 
}

//Takes the id of an element as a string and fades it out if it has been set
//to be faded out earlier. 
function fadeOutDelayed(eid) {
  var element = document.getElementById(eid);
  if(element == null)
    return;

  if(element.DelayedFadeOut != 1) return;
  //if(element.FadeOutCount != count) return;
  //console.log("delayed fade out called for " + eid + " with id " + element.FadeOutCount);
   
  checkFadeState(element);
  if(element.FadeTimeLeft == null) element.FadeTimeLeft = 0;
  element.DelayedFadeOut = 0;

  if(element.FadeState == 1) {
    element.FadeState = -1;
    element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft;
    //alert("fade state of " + eid + "changed to -1.\tFade time left changed to " + element.FadeTimeLeft);
  } else if(element.FadeState == 2) {
    element.FadeState = -1;
    element.FadeTimeLeft = TimeToFade; 
    setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);
  } 
}

//Animates the next step in a fade in or out. 
function animateFade(lastTick, eid) {  
  var curTick = new Date().getTime();
  var elapsedTicks = curTick - lastTick;
  
  var element = document.getElementById(eid);
 
  if(element.FadeTimeLeft <= elapsedTicks) {
    element.style.opacity = element.FadeState == 1 ? '1' : '0';
    element.style.display = element.FadeState == 1 ? 'block' : 'none';
    element.style.filter = 'alpha(opacity = ' 
        + (element.FadeState == 1 ? '100' : '0') + ')';
    element.FadeState = element.FadeState == 1 ? 2 : -2;
    return;
  }
 
  element.FadeTimeLeft -= elapsedTicks;
  var newOpVal = element.FadeTimeLeft/TimeToFade;
  if(element.FadeState == 1) {
    newOpVal = 1 - newOpVal;
  } 

  element.style.opacity = newOpVal;
  element.style.filter = 'alpha(opacity = ' + (newOpVal*100) + ')';
  
  setTimeout("animateFade(" + curTick + ",'" + eid + "')", 33);
}
      
      // This will take a div id and set it visible.				//
      function showDivVisibility(divID_as_a_string) {
        //get a reference as above ...
        myReference = getRefToDiv(divID_as_a_string);
        //now we have a reference to it
        //DOM & proprietary DOM
        myReference.style.visibility = 'visible';
      }
      
      // This will take a div id and set it invisible.			//
      function hideDivVisibility(divID_as_a_string) {
        //get a reference as above ...
        myReference = getRefToDiv(divID_as_a_string);
        //now we have a reference to it
        //DOM & proprietary DOM
        myReference.style.visibility = 'hidden';
      }
      
      // This will take a div id and alter its visibility.			//
      function showhideDivVisibility(divID_as_a_string) {
        //get a reference as above ...
        myReference = getRefToDiv(divID_as_a_string);
        //now we have a reference to it
        //DOM & proprietary DOM
        if(myReference.style.visibility == 'visible')
        {myReference.style.visibility = 'hidden';return false;}
        else {myReference.style.visibility = 'visible';return true;}
      }

      // This will take a div id and set it visible.				//
      function showDivDisplay(divID_as_a_string) {
        //get a reference as above ...
        myReference = getRefToDiv(divID_as_a_string);
        //now we have a reference to it
        //DOM & proprietary DOM
        myReference.style.display = 'block';
      }
      
      // This will take a div id and set it invisible.			//
      function hideDivDisplay(divID_as_a_string) {
        //get a reference as above ...
        myReference = getRefToDiv(divID_as_a_string);
        //DOM & proprietary DOM
        myReference.style.display = 'none';
        myReference.style.opacity = 0;
        myReference.style.filter = 'alpha(opacity = 0)';
        myReference.FadeState = -2;
      }
      
      // This will take a div id and alter its visibility.			//
      function showhideDivDisplay(divID_as_a_string) {
        //get a reference as above ...
        myReference = getRefToDiv(divID_as_a_string);
        //now we have a reference to it
        //DOM & proprietary DOM
        if(myReference.style.display == 'block')
        {myReference.style.display = 'none';return false;}
        else {myReference.style.display = 'block';return true;}
      }
      
      // This will turn all menus and forms off other then the ones you want.	//
      function switchMenuClick(divID)
      {
      	function recursiveMenuCheck(anArray)
      	{
      		//if (anArray[0] == fatherID) {
      		//  menuNode = anArray;
      		//}
      		var toReturn = false;
      		//alert("checking " + anArray[0]);
      		for (x in anArray[2])	{
      			toReturn = recursiveMenuCheck(anArray[2][x])||toReturn;
      		}
      		if (anArray[0] == divID){
      			if(showhideDivDisplay(anArray[0])) {
      			  menuNode = anArray;
      			}
      			return true;
      		}
      		if(toReturn) {
      			showDivDisplayDisplay(anArray[0]);
      			return true;
      		}
      		else {
      			hideDivDisplayDisplay(anArray[0]);
      			return false;
      		}
      	}
      
        //alert('in switchMenu; switching menu '+ divID);
        resetMenuNode(divID);
        //alert('in switchMenu; menu node reset');
      	recursiveMenuCheck(menuTree);	
      }

      // This will turn all menus and forms off other then the ones you want.	//
      function switchMenuHover(divID)
      {
      	function recursiveMenuCheckFade(anArray)
      	{
      		//if (anArray[0] == fatherID) {
      		//  menuNode = anArray;
      		//}
      		var toReturn = false;
      		//alert("checking " + anArray[0]);
      		for (x in anArray[2])	{
      			toReturn = recursiveMenuCheckFade(anArray[2][x])||toReturn;
      		}
      		if (anArray[0] == divID){
      			showDivFade(anArray[0]);
      			menuNode = anArray;
      			return true;
      		}
      		if(toReturn) {
      			showDivFade(anArray[0]);
      			return true;
      		} else {
      			hideDivFade(anArray[0]);
      			return false;
      		}
      	}

      	function recursiveMenuCheck(anArray)
      	{
      		//if (anArray[0] == fatherID) {
      		//  menuNode = anArray;
      		//}
      		var toReturn = false;
      		//alert("checking " + anArray[0]);
      		if (anArray[0] == divID){
      			showDivFade(anArray[0]);
      			menuNode = anArray;
      			for (x in anArray[2])	{
              toReturn = recursiveMenuCheckFade(anArray[2][x])||toReturn;
            }
      			return true;
      		} else {
      			for (x in anArray[2])	{
              toReturn = recursiveMenuCheck(anArray[2][x])||toReturn;
            }
          }
      		if(toReturn) {
      			showDivFade(anArray[0]);
      			return true;
      		} else {
      			hideDivDisplay(anArray[0]); 
      			return false;
      		}
      	}
      
        //console.log('Switching menu '+ divID);
        resetMenuNode(divID);
        //alert('in switchMenu; menu node reset');
        //console.log("entering recursiveMenuCheck for divID = " + divID);
      	recursiveMenuCheck(menuTree);	
      }

      //Resets menuNode to point to the location in menuTree corresponding
      // to the divID. 
      function resetMenuNode(divID) {
        function recursiveMenuCheck(anArray) {
      		if (anArray[0] == divID) {
      		  menuNode = anArray;
      		  //alert("menuNode set to "+anArray[0]+". ");
      		}
      		else {
      		  for(x in anArray[2]) {
      		    recursiveMenuCheck(anArray[2][x]);
      		  }
      		}
        }

        var ref = getRefToDiv(menuNode[1]);
        recursiveMenuCheck(menuTree);
        ref = getRefToDiv(menuNode[1]);
      }

