// Multi-browser and general utility functions
function Is() {
	var agent = navigator.userAgent.toLowerCase();
	this.major = parseInt(navigator.appVersion);
	this.minor = parseFloat(navigator.appVersion);
	this.ns  = ((agent.indexOf('mozilla')!=-1) && ((agent.indexOf('spoofer')==-1) && (agent.indexOf('compatible') == -1)));
	this.ns2 = (this.ns && (this.major == 3));
	this.ns3 = (this.ns && (this.major == 3));
	this.ns4 = (this.ns && (this.major >= 4));
	this.ie   = (agent.indexOf("msie") != -1);
	this.ie3  = (this.ie && (this.major == 2));
	this.ie4  = (this.ie && (this.major >= 4));
	this.op3 = (agent.indexOf("opera") != -1);
}

var is = new Is();

var doc, sty, htm;
if(is.ns4) {
	doc = "document";
	sty = "";
	htm = ".document";
} else if(is.ie4) {
	doc = "document.all";
	sty = ".style";
	htm = "";
}

function dumpObject(anObject) {
  var msgStr = "";
  for (prop in anObject) {
    if (prop == "font") {
      alert("Skipping property " + prop + "!");
      continue;
    }
    //alert("For property " + prop + "...");
    if (anObject[prop]) {
      //alert("Object " + anObject + "'s " + prop + " has value:" + anObject[prop]);
      msgStr += prop + ':' + anObject[prop] + '\n';
    }
    else {
      //alert("Object " + anObject + "'s " + prop + " has no value");
      msgStr += prop + ':novalue\n';
    }
  }
  alert(msgStr);
}

function stringToSubLayerObj(parentLayerObj, subLayerStr) {
	if (is.ns4) {return(parentLayerObj.document[subLayerStr]);}
	else {
	  return(eval("document.all."+ subLayerStr +".style"));
	}
}

// End multi-browser and utility functions

// Choose color limits, number of gradations, any other program constants
//var outColor = "cfbb8d";
//var overColor = "ffebcd";
var outColor = "cfbb8d";
var overColor = "efdbbd";
var numFadeLevels = 45;
var numMenuItems = 6;
var rollingMenuReady = false;
var rolling = false;

// Define menu items array for tracking rolling colors, set up 
function menuItems(index) {
	this.fadeIndex = 0;
	this.currentTop = null;
	this.layer = stringToSubLayerObj(baseMenuLyr,"button"+index+"MenuLayer");
	this.imageLayer = stringToSubLayerObj(imageMenuLyr, "button"+index+"ImageLayer");
}
function menuItemsSetup() {
	//alert("Entering menuItemsSetup");
	menuArray = new Array(numMenuItems)
	for (var i=0; i<numMenuItems; i++) {
		menuArray[i] = new menuItems(i);
	}
}

// Create array of color fades
function setupColorFadeList(low,high,length) {
	//alert("Entering colorfadelistsetup");
	colorScale = new Array(length);

	var redLow = (low&0xff0000)>>16; redHigh = (high&0xff0000)>>16; redRange = redHigh-redLow;
	var greenLow = (low&0x00ff00)>>8; greenHigh = (high&0x00ff00)>>8; greenRange = greenHigh-greenLow;
	var blueLow = low&0x0000ff; blueHigh = high&0x0000ff; blueRange = blueHigh-blueLow;

	for (var i=0; i<numFadeLevels-1; i++) {
		var redComp =   redLow +   Math.round(redRange/numFadeLevels) * i;
		var greenComp = greenLow + Math.round(greenRange/numFadeLevels) * i;
		var blueComp =  blueLow +  Math.round(blueRange/numFadeLevels) * i;
		var hexString = ((redComp<<16) + (greenComp<<8) + blueComp).toString(16);
		for (var j=hexString.length; j<6; j++) {
			hexString = "0" + hexString;
		}
		colorScale[i] = hexString;
	}
	colorScale[numFadeLevels-1] = high.substr(2);
}

// Set the coords of all layers
// THIS is the function called upon load of the page, starting a chain that runs the program
var buttonDepth = 39;
var baseMenuLyr, imageMenuLyr;

var windowOutsideWidth, windowOutsideHeight;

function layerSetup() {

	windowOutsideWidth = window.outerWidth;
	windowOutsideHeight = window.outerHeight;

    specialsLyrStr = doc + '["specialsLayer"]' + sty;
	specialsLyr = eval(specialsLyrStr);
	

	// baseMenuLyr = eval(doc + "['baseMenuLayer']" + sty);
	baseMenuLyrStr = doc + '["baseMenuLayer"]' + sty;
	baseMenuLyr = eval(baseMenuLyrStr);
	
	imageMenuLyr = eval(doc + "['imageMenuLayer']" + sty);
	menuItemsSetup();

	var topMark = 0;
	var leftMark = 0;
	var buttonLyr;
    
	margin = window.document.firstChild.offsetWidth > 670?
		 (window.document.firstChild.offsetWidth - 670) / 2 : 0;
        specialsLyr.left = margin + 12;
	specialsLyr.top =  320;
	specialsLyr.posLeft = margin + 12;
	specialsLyr.posTop =  320;
	
	imageMenuLyr.left = margin + 11;
	// imageMenuLyr.top =  320 + 225 + 12;
	imageMenuLyr.top =  539;  // I don't know WHY this is 22 pixels too low, but ...
	imageMenuLyr.posLeft = margin + 11;
	//imageMenuLyr.posTop =  320 + 225 + 12;
	imageMenuLyr.posTop =  539;

	var layerName="";
	for (var i=0; i<numMenuItems; i++) {
		menuArray[i].imageLayer.left = leftMark;
		menuArray[i].imageLayer.top = topMark + buttonDepth*i;
		menuArray[i].imageLayer.posLeft = leftMark;
		menuArray[i].imageLayer.posTop = topMark + buttonDepth*i;
		//alert("menuArray imageLayer " + i + " should now have left, top, posLeft, posTop");
		//dumpObject(menuArray[i].imageLayer);
	}
	imageVisibilitySetup();
}

function imageVisibilitySetup() {

	for (var i=0; i<numMenuItems; i++) {
		menuArray[i].imageLayer.visibility = "visible";
		menuArray[i].imageLayer.zIndex = 4;
	}
	imageMenuLyr.visibility = "visible";

	baseLayersSetup();
}

function baseLayersSetup() {

	//alert("Entering baseLayersSetup");
	var topMark = 0;
	var leftMark = 0;
	var buttonLyr;

	// window.document.firstChild.offsetWidth is the width of enclosing window; 764 is tablewidth+menuswidth
	//dumpObject(window.document.firstChild.firstChild);
	margin = window.document.firstChild.offsetWidth > 670?
		 (window.document.firstChild.offsetWidth - 670) / 2 : 0;
	baseMenuLyr.left = margin + 12;
	baseMenuLyr.top =  320 + 225 + 12;
	baseMenuLyr.posLeft = margin + 12;
	baseMenuLyr.posTop =  320 + 225 + 12;

	for (var i=0; i<numMenuItems; i++) {
		menuArray[i].layer.left = leftMark;
		menuArray[i].layer.top = topMark + buttonDepth*i;
		menuArray[i].layer.posLeft = leftMark;
		menuArray[i].layer.posTop = topMark + buttonDepth*i;
		//alert("menuArray layer " + i + " now should have left, top, posLeft, posTop");
		//dumpObject(menuArray[i].layer);
	}
	baseVisibilitySetup();
}

function baseVisibilitySetup() {

	//alert("Entering baseVisibilitySetup");
	for (var i=0; i<numMenuItems; i++) {
		menuArray[i].layer.visibility = "visible";
		menuArray[i].layer.zIndex = 2;
	}
	baseMenuLyr.visibility = "visible";
	specialsLyr.visibility = "visible";

	// NOW the base menu WILL display and respond to mouse-over/outs and clicks.
	// Start preparing the rolling menu; when it is ready, mouse-out's for sufficient time
	//		will switch and display the roller
	setupColorFadeList("0x"+outColor, "0x"+overColor, numFadeLevels);
	rollingMenuReady = true;
	if (selected == null) {
		startOutTimer();
	}
	else {
	  //alert("selected has value:" + selected);
	}
}

// THIS is to be called if the base Menu's "mouseout timer" expires AND rollingMenuReady
// (Base Menu's mouseOut must set selected to null, and Rolling Menu's mouseover's will set it

var rollingMenuTimeOutId=null;

function rollMenu() {
	//alert("Entering rollMenu");
	if (selected == null) {
		paintRollingMenu();
		rollingMenuTimeOutId = setTimeout("rollMenu()", 32);
	}
	else {
		switchToBaseMenu();
	}
}

function switchToBaseMenu() {
	//alert("Entering switchToBaseMenu");
	if (rollingMenuTimeOutId != null) {
		clearTimeout(rollingMenuTimeOutId);
		rollingMenuTimeOutId = null;
	}
	rolling = false;
	initializeRollingMenu();
}

function initializeRollingMenu() {
	//alert("Entering initializeRollingMenu");
	var i, j;

	for (i=0; i<numMenuItems; i++) {
		menuArray[i].fadeIndex = 0;
	}
}

function paintRollingMenu() {
	//alert("Entering paintRollingMenu");
	if (!rolling) {
		rolling = true;
		going = lastSelected;
		nextComingGoing();
	}
	doRoll();
}

function nextComingGoing() {

	//alert("Entering nextComingGoing");
	if (going == numMenuItems-1 && goingDown) {
		goingDown = false;
	}
	if (going == 0 && !goingDown) {
		goingDown = true;
	}
	coming = goingDown? going+1 : going-1;

	// Set an item one beyond "coming," to start getting light as coming approaches full
	comingPlus = goingDown? coming+1 : coming-1;
	if (comingPlus<0 || comingPlus==numMenuItems) {comingPlus = coming;}

	menuArray[going].fadeIndex = numFadeLevels - 1;  // Set to highest(brightest) color
}

function doRoll() {

	//alert("Entering doRoll");
	// check current fadeIndex values, inc/dec if appropriate, or change coming/going
	if (menuArray[going].fadeIndex == 0 && 
	    menuArray[coming].fadeIndex == numFadeLevels-1) {
		going = coming;
		nextComingGoing();
	}
	else {
	// Set current fields of coming/going layers, and appropriate visibility indices
		if (menuArray[going].fadeIndex > 0) {
			menuArray[going].fadeIndex--;
		}
		if (menuArray[coming].fadeIndex < numFadeLevels-1) {
			menuArray[coming].fadeIndex++;
		}
		if ((menuArray[coming].fadeIndex == numFadeLevels-1) && (coming != comingPlus)) {
			menuArray[comingPlus].fadeIndex++;
		}
	}
	//alert("doRoll before setting come menu " + coming + " bgColor");
	//dumpObject(menuArray[coming].layer);
	menuArray[coming].layer.bgColor = colorScale[menuArray[coming].fadeIndex];
	menuArray[coming].layer.backgroundColor = colorScale[menuArray[coming].fadeIndex];
	//alert("doRoll after setting come menu");
	//dumpObject(menuArray[coming].layer);

	//alert("doRoll before setting go menu " + going + " bgColor");
	//dumpObject(menuArray[going].layer);
	menuArray[going].layer.bgColor = colorScale[menuArray[going].fadeIndex];
	menuArray[going].layer.backgroundColor = colorScale[menuArray[going].fadeIndex];
	//alert("doRoll after setting go menu");
	//dumpObject(menuArray[going].layer);

	//alert("doRoll before setting comeplus menu " + comingPlus + " bgColor");
	//dumpObject(menuArray[comingPlus].layer);
	menuArray[comingPlus].layer.bgColor = colorScale[menuArray[comingPlus].fadeIndex];
	menuArray[comingPlus].layer.backgroundColor = colorScale[menuArray[comingPlus].fadeIndex];
	//alert("doRoll after setting comeplus menu");
	//dumpObject(menuArray[comingPlus].layer);

	if (windowOutsideWidth != window.outerWidth ||
	    windowOutsideHeight != window.outerHeight) {
	    //alert("User resized..reloading..");
		window.location.reload();
	}
}

var selected = null;
var lastSelected = 0;
var goingDown = true;

function imagemouseover(index) {
	if (rolling) {
		rollingmouseover(index);
	}
	else {
		basemouseover(index);
	}
}

function imagemouseout(index) {
	if (!rolling) {
		basemouseout(index);
	}
}

function basemouseover(index) {

	if (timeOutId != null) {
		clearTimeout(timeOutId);
		timeOutId = null;
	}

	if(selected != index) {
		selected = index;
		menuArray[index].layer.bgColor = colorScale[numFadeLevels-1];
		menuArray[index].layer.backgroundColor = colorScale[numFadeLevels-1];

		// If we ever missed another mouseout, catch it now:
		for (var i=0; i<numMenuItems; i++) {
			if (i != index) {
				menuArray[i].layer.bgColor = colorScale[0];
				menuArray[i].layer.backgroundColor = colorScale[0];
			}
		}
	}
}

function basemouseout(index) {

	menuArray[index].layer.bgColor = colorScale[0];
	menuArray[index].layer.backgroundColor = colorScale[0];
	lastSelected = index;
	selected = null;

	startOutTimer();
}

var timeOutId=null;
function startOutTimer() {
	// rollMenu will do NOTHING if selected is set to something non-null before this times out
	//alert("Entering startOutTimer");
	timeOutId = window.setTimeout("rollMenu()", 1000);
}
	
function rollingmouseover(index) {
	switchToBaseMenu();
	basemouseover(index);
}

// Not used yet, have to RESTORE .top on mouseout...
/*
function mousedown(index) {
	if(selected != index) {
		eval(menuArray[index].layer).top += 1;
		htmlArray[index].current = htmlArray[index].out;
		htmlArray[index].changed = true;
	}
}
*/
