/*==========================================================================
  This code is evil.  Don't try this at home, kids.  Go to www.webcoder.com and read
  Nick Heinle's works about layer positioning and animation.  I took a great bulk of this
  code from his examples, especially the timeLineController functions and the animation
  code.  
  
  This is *ADVANCED* JavaScript programming.  You *MUST* know what you are doing
  to use this code - you will only frustrate yourself silly unless you do.  You *cannot*
  simply cut and paste this code.  You have to understand what it does and why.
  If you can write a rollOver script, then you can probably learn this stuff easily enough.
  A good place to start is www.webcoder.com or www.dhtmlzone.com.
  
  Good luck.
  
  Caveat:  If you use a timer, you *MUST* TURN IT OFF.  Otherwise, the timer keeps
  eating up ram as it counts higher and higher.
  ==========================================================================*/

var layerObj="null", layerStyleObj="null",styleObj="null", totalTime="null", currTime="null";
var layerObj="null", layerStyleObj="null",styleObj="null", totalTime="null", currTime="null";
var animationTime, animationTimeline, animatedObjects;
var bon, boff;
var positionState = 0;
// Netscape uses document.layers.  
var isNS = (document.layers);

// document.layers for NS, document.all for IE.  If either is present, we have a 4+ browser.
var isDHTML = (document.layers || document.all);

var NS4 = (navigator.appName == "Netscape" && parseInt(navigator.appVersion) >= 4);

	var layerObj = (NS4) ? 'document' : 'document.all';
	var styleObj = (NS4) ? '' : '.style';




// showLayer and hideLayer require the eval() statements to pick the correct
// layer and style names (document.layers versus document.all, and null versus .style)
// These two basically flip the "visibility" flag set in the STYLE attribute of the DIV tags.

function showLayer(layerName) {
  eval(layerObj+'["'+layerName+'"]'+styleObj+'.visibility="visible"');
}

function hideLayer(layerName) {
  eval(layerObj+'["'+layerName+'"]'+styleObj+'.visibility="hidden"');
}

// Modified show/hideLayer functions.  They operate the onMouseOver defintion
// appearances.  I wrote them this way (with the setting of layerDefName inside the
// function itself) because I'm lazy.

function flipDefTextSwitchOff(layerName) {
  if(positionState == 1) {
    var layerOnName = layerName + "On";
    var layerDefName = layerName + "Def";
    eval(layerObj+'["'+layerDefName+'"]'+styleObj+'.visibility="hidden"');
    eval(layerObj+'["'+layerOnName+'"]'+styleObj+'.visibility="hidden"');
  }
}

function flipDefTextSwitchOn(layerName) {
  if(positionState == 1) {
    var layerOnName = layerName + "On";
    var layerDefName = layerName + "Def";
    eval(layerObj+'["'+layerDefName+'"]'+styleObj+'.visibility="visible"');
    eval(layerObj+'["'+layerOnName+'"]'+styleObj+'.visibility="visible"'); 
  }
}




function flipTextSwitchOff(layerName) {
  if(positionState == 1) {
    var layerOnName = layerName + "On";
    eval(layerObj+'["'+layerOnName+'"]'+styleObj+'.visibility="hidden"');
  }
}

function flipTextSwitchOn(layerName) {
  if(positionState == 1) {
    var layerOnName = layerName + "On";
    eval(layerObj+'["'+layerOnName+'"]'+styleObj+'.visibility="visible"');
  }
}


function showMainNavBar() {
  showLayer('homeOff');
  showLayer('abyssOff');
  showLayer('heroinOff');
  showLayer('voidOff');
  showLayer('consultingOff');
  showLayer('xOff');
  showLayer('evilPeopleOff');
  showLayer('commentsOff');
  showLayer('bharrisAtOff');
}




// This is evil incarnate.  Create an object.  Pass it several attributes.  Assign
// a couple methods to it.  Just cut and paste this.

function animatedObject(elementName,loop,speed,steps,endRoutines,route){
  this.elementName = elementName;
  this.loop = loop;
  this.speed = speed;
  this.steps = steps;
  this.frameIndex = 0;
  this.endRoutines = endRoutines;
  this.route = route.split(',');
  this.animate = animateObject;
  this.move = moveObject;
  this.show = showObject;
  this.hide = hideObject;
  animatedObjects[elementName] = this;
}

// ALWAYS remember to stop your running timelines.  Give yourself some time (perhaps
// a number of a hundred after the final usage) but DO stop them.  Crashes might ensue
// without it.

function stopTimeline(timelineNumber){
  animationTime[timelineNumber] = animationTimeline[timelineNumber].length;
}


// We can create several timelines, if we want to keep track of several things at once.
// Pass it a number.  That creates it.  We define the information about it later.
function startTimeline(timelineNumber) {
  animationTime[timelineNumber] = 0;
  timelineController(timelineNumber);
}

// This steps through the timeLine array that we define and execs the commands at 
// that array level.
function timelineController(timelineNumber) {
           if (animationTime[timelineNumber] <= animationTimeline[timelineNumber].length - 1) {
	     animationTime[timelineNumber]++;
	     if (animationTimeline[timelineNumber][animationTime[timelineNumber]] != null){
	       eval(animationTimeline[timelineNumber][animationTime[timelineNumber]]);
	     }
	     setTimeout('timelineController(' + timelineNumber + ')', 100);
	   }
}


// Basically, show/hideLayer but built for methods.
function showObject(){
  eval(layerObj + '["' + this.elementName + '"]' + styleObj + '.visibility = "visible"');
}

function hideObject(){
  eval(layerObj + '["' + this.elementName + '"]' + styleObj + '.visibility = "hidden"');
}


// This is brilliant in it's simplicity.
function moveObject(left, top){
  eval(layerObj + '["' + this.elementName + '"]' + styleObj + '.top = top');
  eval(layerObj + '["' + this.elementName + '"]' + styleObj + '.left = left');
}


// Here there be Dragons.

// This is the code to understand.  All the values you pass to an animatedObject get used
// here, like the speed and route (defined as a list of x,y co-ordinates.)
// NOTE:  var frameModRate is set in init().  It is differing speeds for the animation
// depending on the browser.  (NS gets 2, IE gets 4)
function animateObject(){
  if (this.route.length > 4 && this.frameIndex < this.route.length)  {
    this.move(this.route[this.frameIndex], this.route[this.frameIndex + 1]);
    this.frameIndex += frameModRate;
    setTimeout('animatedObjects["' + this.elementName + '"].animate()', this.speed);
  }
  else if (this.route.length == 4 && this.frameIndex <= this.steps) {
    // This is important, the way it parses the route definition.  You have to follow the
    // syntax it uses.
    this.move(parseInt(this.route[0]) + (this.frameIndex * ((parseInt(this.route[2]) - parseInt(this.route[0])) / this.steps)), parseInt(this.route[1]) + (this.frameIndex * ((parseInt(this.route[3]) - parseInt(this.route[1])) / this.steps)));
    this.frameIndex++;
    setTimeout('animatedObjects["' + this.elementName + '"].animate()', this.speed);         
  } else {
    eval(this.endRoutines + "");
    this.frameIndex = 0;
    if (this.loop == "yes"){
      this.animate();
    }
  }
}

// Startup function.  Season to taste, and use it in an onLoad="" attribut of the BODY tag.
function init() {
  // Are we NS or IE?  set it up accordingly.  (This will probably have to be modifed
  // in case there are ever any other CSS compliant browsers that show up.  (Not that
  // NS 4.x is compliant.)
  if (document.layers) {
    layerStyleObj="layer.";
    layerObj="document.layers";
    styleObj="";
    frameModRate = 2;
  }else{
    layerStyleObj="layer.style.";
    layerObj="document.all";
    styleObj=".style";
    // WARNING:  Changing this can have dire effects.
    frameModRate = 2;
  }
  window.self.defaultStatus='Novus Ordo Templis Digitalis.';
}


