// menuBase.js - Generic abstract menu objects (View and Node)

/**************************************/

/* version control comments:
   2001.09.27 - Chazz Mevoli - created initial file
   2003.01.28 - Chazz Mevoli - modified for Project Next Flyouts
   */

/**************************************/

var menu_next_div_id = 0;
var menu_popup_toplevel;
var menu_orig_onload = window.onload;
var menu_last_popup_id = Array();
var menu_last_sel_id = Array();
var menu_parent_did = Array();
var node_padding = 0;
var menu_timeout_id;
var menu_mouseover_count = 0;
var menu_timeout_value = 2000;

window.onload = function() {
	if (menu_orig_onload) menu_orig_onload();
	menu_popup_toplevel.cbeInit();
	}

/**************************************/

/* include global functions

  core/global_funcs.js
  core/cbe_core.js
  core/cbe_event.js

*/

/**************************************/

// menuView: inherit this object to implement menu views

function menuView_setTarget (target) {
	this.target = target;
	}

/**************************************/

function menuView_setLAF (laf) {
	this.laf = laf;
	this.wall = laf.get ("menu", "wall");
	this.bg_color = laf.get ("menu", "bg_color");
	this.text_color = laf.get ("menu", "text_color");
	this.sel_wall = laf.get ("menu", "sel_wall");
	this.sel_bg_color = laf.get ("menu", "sel_bg_color");
	this.sel_text_color = laf.get ("menu", "sel_text_color");
	this.sep_color = laf.get ("menu", "sep_color");
	this.sep_size = laf.get ("menu", "sep_size");
	this.border_color = laf.get ("menu", "border_color");
	this.border_size = laf.get ("menu", "border_size");
	this.border_padding = laf.get ("menu", "border_padding");
	this.animate = laf.get ("menu", "animate");
	this.animate_speed = laf.get ("menu", "animate_speed");
	}

/**************************************/

function menuView_addNode (n) {
	if (this.nodes.length==0) this.nodes = new Array();
	n.level = this.level + 1;
	apush (this.nodes, n);
	return n;
	}

/**************************************/

function menuView_display (docptr) {
	var i;
	var orient = this.orientation.charAt(0);
	var doc = docptr || document;
	this.write ('<div id="mdPopup' + this.id +
		'" style="visibility:hidden; position:absolute; ' +
    'background-color:transparent; layer-background-color:transparent;' +
    'color:' + this.text_color + '">\n' +
    '<table border=' + this.border_size +
		' cellspacing=0 cellpadding=' + this.border_padding +
		' bgcolor=' + this.bg_color +
		(this.wall ? (' background=' + this.wall) : "") +
		'><tr><td>\n' +
		(orient=="h" ? '<table border=0 cellspacing=0 cellpadding=0><tr>' : "")
		);
	for (i=0;i<this.nodes.length;i++) {
		if (orient=="h") this.write ('<td>');
		this.nodes[i].display (this);
		if (orient=="h") this.write ('</td>');
    menu_parent_did[this.nodes[i].id] = 'mdPopup' + this.id;
		}
	this.write (
		(orient=="h" ? '</tr></table>' : "") +
		'</td></tr></table>\n</div>\n'
		);
	for (i=0;i<this.nodes.length;i++) {
		if (this.nodes[i].isPopup) this.nodes[i].displayPopup (this);
		}
	//alert ("<xmp>" + this.docbuf + "</xmp>");
	this.writeBuffer (doc);
	}

/**************************************/

function menuView_build (docptr) {
	var i;
	var doc = docptr || document;
	tmp = new docBuffer();
	tmp.write (
		'<style type="text/css"><!--\n' +
		'td.' + menu_popup_toplevel.style_class + ' {\n' +
    '  background-color:' + this.border_color + '; }\n' +
    'a.'  + menu_popup_toplevel.style_class + ':link {\n' +
    '  text-decoration:none;\n' +
    '  font-size: 12pt;\n' +
    '  color:' + this.text_color + ';\n' +
    '  }\n' +
    'a.'  + menu_popup_toplevel.style_class + ':visited {\n' +
    '  text-decoration:none;\n' +
    '  font-size: 12pt;\n' +
    '  color:' + this.text_color + ';\n' +
    '  }\n' +
    'a.'  + menu_popup_toplevel.style_class + ':active {\n' +
    '  text-decoration:none;\n' +
    '  font-size: 12pt;\n' +
    '  color:' + this.text_color + ';\n' +
    '  }\n' +
    'a.'  + menu_popup_toplevel.style_class + ':hover {\n' +
    '  text-decoration:none;' +
    '  font-size: 12pt;\n' +
    '  color:' + this.sel_text_color + '; }\n' +
		'#mdPopup' + this.id + ' {\n' +
		'  visibility:hidden;\n'
		);
	/* calculate layer height, not just 600 */
	//if (is.opera) tmp.write ('  height:600;\n');
	if ((this.left+this.top) > 0) tmp.write (
		'  position:absolute;\n' +
		'  left:' + this.left + ';\n' +
		'  top:' + this.top + ';\n'
		);
	else if (is.nav4) tmp.write ('position:relative;\n');
	tmp.write (
		'  color:' + this.text_color + ';\n' +
		'  background-color:transparent;\n' +
		'  layer-background-color:transparent;\n' +
		'  }\n'
		);
	for (i=0;i<this.nodes.length;i++) this.nodes[i].build (tmp);
	tmp.write ('--></style>\n');
	//alert (tmp.docbuf);
	tmp.writeBuffer (doc);
	}

/**************************************/

function menuView_closeAll() {
 	var e;
	var e_before;
	for (i=menu_last_popup_id.length;i>1;i--) {
		e = document.getElementById(menu_last_popup_id[i-1]);
		e_before = document.getElementById(menu_last_sel_id[i-1]);
		e_before.cbe.background (menu_popup_toplevel.bg_color);
		e.cbe.hide();
		}
	}

/**************************************/

function menuView_mouseHandler(ev) {
	cbeEvent.init(ev);
	menuView_closeAll();
	}

/**************************************/

function menuView_show() {
	e = document.getElementById('mdPopup' + this.id);
	e.cbe.show();
  }

/**************************************/

function menuView_hide() {
	e = document.getElementById('mdPopup' + this.id);
	e.cbe.hide();
  }

/**************************************/

function menuView_cbeInit() {
	var e;
	var et;
	var x, y, y2;
	var x2 = 0;
	var x_first = 0;

	e = document.getElementById('mdPopup' + this.id);
	if ((this.left+this.top) > 0) e.cbe.moveTo (this.left,this.top);
  this.left = e.cbe.offsetLeft();
	this.top = e.cbe.offsetTop();
	e.cbe.show();

	/*
	x = this.left;
	y = this.top;
	if (this.orientation.charAt(0)=='h') {
		x += (this.border_size + this.border_padding);
		y += (this.border_size + this.border_padding);
		y2 = y;
		}
  for (var i=0;i<this.nodes.length;i++) {
		if (this.orientation.charAt(0)=='h') {
			et = document.getElementById('mdItem' + this.nodes[i].id);
			x += x2;
			x2 = parseInt(et.cbe.width());
			y = y2 + parseInt(et.cbe.height());
			}
		this.nodes[i].cbeInit (x,y);
		}
	*/
  document.addEventListener("click", menuView_mouseHandler, true);
	}

//--------------------------------

/* x can be set to orient if coords are not absolute */
/* EX: menuView (orient) */
function menuView (x, y, orient) { /* object constructor */
	// vars
	this.id = menu_next_div_id++;
	this.target = "";
	this.nodes = new Array();
	if (isFinite(x)) {
		this.left = x || 0;
		this.top = y || 0;
		this.orientation = orient || "v";
		}
	else {
		this.left = 0;
		this.top = 0;
		this.orientation = x || "v";
		}
	this.level = 0;
	menu_popup_toplevel = this;
	this.laf = null;
	this.wall = "";
	this.bg_color = '#444444';
	this.text_color = '#ffffff';
	this.sel_wall = "";
	this.sel_bg_color = '#228822';
	this.sel_text_color = '#ffffff';
	this.sep_color = '#ffffff';
	this.sep_size = 2;
	this.border_color = '#888888';
	this.border_size = 1;
	this.border_padding = 4;
	this.animate = 0;
	this.animate_speed = 30;
	this.node_padding = 3;
	this.arrow_image = "";
	this.node_wall = "";
	this.node_wall_end = "";
	this.node_wall_bottom = "";
	this.node_border = 0;
	this.style_class = 'menunode';
  this.trans_gif = "";
	// methods
	this.setTarget = menuView_setTarget;
	this.setLAF = menuView_setLAF;
	this.addNode = menuView_addNode;
	this.display = menuView_display;
	this.build = menuView_build;
	this.closeAll = menuView_closeAll;
	this.cbeInit = menuView_cbeInit;
	this.show = menuView_show;
	this.hide = menuView_hide;
	}

menuView.prototype = new docBuffer;

/**************************************/

// menuNode: generic node object to hold data and abstract methods

function menuNode_mouseover (did, level, img_over) {
	// NOTE: this function is not in the scope of the menuNode object.
	//       therefore, no 'this' pointer exists
  var i;
	var cbet;
	var x, y;
  clearTimeout (menu_timeout_id);
  menu_mouseover_count++;
	var e = document.getElementById(did);
	var cbe_before = document.getElementById(menu_last_sel_id[level]);
	if (cbe_before) {
    cbe_before.cbe.background (menu_popup_toplevel.bg_color);
    cbe_before.cbe.color ('#ff0000');
    }
	if (img_over) eval ('document.' + did + 'i.src = ' + img_over + ';');
	else {
    e.cbe.background (menu_popup_toplevel.sel_bg_color);
    e.cbe.color ('#000000');
    }
	menu_last_sel_id[level] = did;
	for (i=menu_last_popup_id.length;i>level;i--) {
		cbet = document.getElementById(menu_last_popup_id[i-1]).cbe;
		cbe_before = document.getElementById(menu_last_sel_id[i]);
		if (cbe_before) {
      cbe_before.cbe.background (menu_popup_toplevel.bg_color);
      cbe_before.cbe.color ('#ff0000');
      }
		cbet.hide();
		}
	}

/**************************************/

function menuNode_timeoutCallback() {
  if (menu_mouseover_count==0) menuView_closeAll();
  }

/**************************************/
function menuNode_mouseout (did, level, img_out) {
	if (img_out) eval ('document.' + did + 'i.src = ' + img_out + ';');
  menu_mouseover_count--;
  if (menu_mouseover_count==0) {
    menu_timeout_id = setTimeout ('menuNode_timeoutCallback()', menu_timeout_value);
    }
  else clearTimeout (menu_timeout_id);
	}

/**************************************/

function menuNode_build (docptr) {
	var doc = docptr || document;
	doc.write (
    '#mdItem' + this.id + ' {\n' +
		'  color:' + menu_popup_toplevel.text_color + ';\n' +
		'  background-color:' + menu_popup_toplevel.bg_color + ';\n' +
		'  layer-background-color:' + menu_popup_toplevel.bg_color + ';\n' +
		'  }\n'
		);
	}

/**************************************/

function menuNode_display (docptr) {
	var doc = docptr || document;
	var did = "mdItem" + this.id;
	this.write (
		'<div id="' + did + '" style="color:' + menu_popup_toplevel.text_color +
    '; background-color:' + menu_popup_toplevel.bg_color +
    '; layer-background-color:' + menu_popup_toplevel.bg_color + ';">' +
    '<a href="' + this.url +
		'" onmouseover="menu' + (this.isPopup ? "Popup" : "Node") +
		'_mouseover(\'' + did + '\',' + this.level +
		(this.img_over ? (',\'' + did + 'iover.src\'') : "") + ')" ' +
		'" onmouseout="menu' + (this.isPopup ? "Popup" : "Node") +
		'_mouseout(\'' + did + '\',' + this.level +
		(this.img_out ? (',\'' + did + 'iout.src\'') : "") + ')">'
		);
	if (this.img_out) {
		this.write (
			'<img src="' + this.img_out + '" border=0 ' +
			'name="' + did + 'i">'
			);
		eval (
			did + 'iover = new Image();' +
			did + 'iover.src = "' + this.img_over + '";' +
			did + 'iout = new Image();' +
			did + 'iout.src = "' + this.img_out + '";'
			);
		}
	else {
    this.write (
      '<table border=' + menu_popup_toplevel.node_border +
      ' cellspacing=0 cellpadding=0 width="100%"' +
      ' background="' + menu_popup_toplevel.node_wall + '">' +
      '<tr><td>' +
      '<table border=0 cellspacing=0 cellpadding=' + menu_popup_toplevel.node_padding +
      ' width="100%"><tr><td>' +
      '<a class="' + menu_popup_toplevel.style_class + '" href="' + this.url + '">' +
      this.label +
      '</a></td>' +
      '<td align="right">'
      );
    if (this.nodes.length>0) {
      this.write ('<img src="' + menu_popup_toplevel.arrow_image + '" border=0>');
      }
    else this.write ('&nbsp;');
    this.write (
      '</td></tr></table>' +
      '</td></tr></table>'
      );
    }
	this.write (
    '</a>' +
    '</div>\n'
    );
	this.writeBuffer (doc);
	}

/**************************************/

function menuNode_cbeInit() {
	var e;
	//e = document.getElementById('mdItem' + this.id);
	//if (e.cbe) e.cbe.show();
	}

//--------------------------------

function menuNode (label, url) { /* object constructor */
	// vars
	this.id = menu_next_div_id++;
	this.url = url;
	this.level = 0;
	if (typeof(label)=="string") this.label = label;
	else if (typeof(label)=="object") {
		if (label.isImageRoll) {
			this.img_out = label.iout;
			this.img_over = label.iover;
			this.label = "";
			}
		}
	else this.label = "[ERROR]";
	// methods
	this.build = menuNode_build;
	this.display = menuNode_display;
	this.cbeInit = menuNode_cbeInit;
	}

menuNode.prototype = new docBuffer;

/**************************************/

// menuSeparator: generic separator node object

function menuSeparator_build (docptr) {
	var doc = docptr || document;
	doc.write (
		'#mdItem' + this.id + ' {\n' +
		'  color:' + menu_popup_toplevel.text_color + ';\n' +
		'  height:' + menu_popup_toplevel.sep_size + 'px;\n' +
		'  background-color:' + menu_popup_toplevel.sep_color + ';\n' +
		'  layer-background-color:' + menu_popup_toplevel.sep_color + ';\n' +
		'  }\n'
		);
	}

/**************************************/

function menuSeparator_display (docptr) {
	var doc = docptr || document;
	this.write (
		'<div id="mdItem' + this.id + '"><hr>' +
		'</div>\n'
		);
	this.writeBuffer (doc);
	}

/**************************************/

function menuSeparator() {
	// vars
	this.id = menu_next_div_id++;
	this.isSeparator = true;
	// methods
	//this.build = menuSeparator_build;
	this.display = menuSeparator_display;
	}

menuSeparator.prototype = new menuNode;

/**************************************/

// menuPopup: generic popup menu object derived from menuNode

function menuPopup_mouseover (did, level, img_over) {
	// NOTE: this function is not in the scope of the menuNode object.
	//       therefore, no 'this' pointer exists
	var i;
	var cbep, didp;
	var x, y;
	if (img_over) menuNode_mouseover (did, level, img_over);
	else menuNode_mouseover (did, level);

  var s = parseInt(did.replace('mdItem', ''));
  var pe = document.getElementById(menu_parent_did[s]);
  var px = pe.cbe.offsetLeft();
  var py = pe.cbe.offsetTop();

  var e = document.getElementById(did);
  if (e.cbe) {
		e.cbe.show();
		x = (px + parseInt(e.cbe.width()));
		y = (py + e.cbe.offsetTop());
		}

	didp = did.replace ('Item','Popup');
	cbep = document.getElementById(didp).cbe;
	cbep.moveTo (x,y);
	//x = cbep.left();   y = cbep.top();
	cbep.show();
	menu_last_popup_id[level] = didp;
	}


/**************************************/

function menuPopup_mouseout (did, level, img_out) {
	if (img_out) menuNode_mouseout (did, level, img_out);
	else menuNode_mouseout (did, level);
	}

/**************************************/

function menuPopup_addNode (n) {
	if (this.nodes.length==0) this.nodes = new Array();
	n.level = this.level + 1;
	apush (this.nodes, n);
	return n;
	}

/**************************************/

function menuPopup_displayPopup (docptr) {
	var i;
	var doc = docptr || document;
  var tmp = new docBuffer();
  tmp.write ('<div id="mdPopup' + this.id + '">\n');
  tmp.write (
    '<table border=' + menu_popup_toplevel.border_size +
    ' cellspacing=0 cellpadding=' + menu_popup_toplevel.border_padding +
    ' bgcolor=' + menu_popup_toplevel.bg_color +
    (menu_popup_toplevel.wall ? (' background=' + menu_popup_toplevel.wall) : "") +
    '><tr><td>\n'
    );
  for (i=0;i<this.nodes.length;i++) {
    this.nodes[i].display (tmp);
    menu_parent_did[this.nodes[i].id] = 'mdPopup' + this.id;
    }
  tmp.write (
    '</td>' +
    '<td class="' + menu_popup_toplevel.style_class + '" rowspan=2>' +
    '<img src="' + menu_popup_toplevel.trans_gif + '" border=0 width=1 height=1>' +
    '</td></tr><tr>' +
    '<td class="' + menu_popup_toplevel.style_class + '">' +
    '<img src="' + menu_popup_toplevel.trans_gif + '" border=0 width=1 height=1>' +
    '</td></tr></table>\n'
    );
  tmp.write ('</div>\n');
  for (i=0;i<this.nodes.length;i++) {
    if (this.nodes[i].isPopup) this.nodes[i].displayPopup (tmp);
    }
	tmp.writeBuffer (doc);
	}

/**************************************/

function menuPopup_build (docptr) {
	var i;
	var doc = docptr || document;
	var tmp = new docBuffer();
	tmp.write (
		'#mdPopup' + this.id + ' {\n' +
		'  visibility:hidden;\n' +
		'  position:absolute;\n' +
		'  left:' + this.left + ';\n' +
		'  top:' + this.top + ';\n' +
		'  color:' + menu_popup_toplevel.text_color + ';\n' +
		'  background-color:transparent;\n' +
		'  layer-background-color:transparent;\n' +
		'  }\n\n' +
		'#mdItem' + this.id + ' {\n' +
		'  color:' + menu_popup_toplevel.text_color + ';\n' +
		'  background-color:' + menu_popup_toplevel.bg_color + ';\n' +
		'  layer-background-color:' + menu_popup_toplevel.bg_color + ';\n' +
		'  }\n\n'
		);
	for (i=0;i<this.nodes.length;i++) this.nodes[i].build (tmp);
	tmp.writeBuffer (doc);
	}

/**************************************/

function menuPopup_cbeInit (x,y) {
	var orient = menu_popup_toplevel.orientation.charAt(0);
	var e;
	var ep;

	e = document.getElementById('mdItem' + this.id);
	if (e.cbe) {
		e.cbe.show();
		if ( (orient=='h') && (this.level==1) ) this.left = x;
		else this.left = (x + parseInt(e.cbe.width()));
		this.top = (y + e.cbe.offsetTop());
		}

	ep = document.getElementById('mdPopup' + this.id);
	if (ep.cbe) {
		ep.cbe.hide();
		ep.cbe.moveTo (this.left,this.top);
		}

  for (var i=0;i<this.nodes.length;i++) {
		this.nodes[i].cbeInit (this.left,this.top);
		}
	}

//--------------------------------

function menuPopup (label, url) {
	// vars
	this.id = menu_next_div_id++;
	if (typeof(label)=="string") this.label = label;
	else if (typeof(label)=="object") {
		if (label.isImageRoll) {
			this.img_out = label.iout;
			this.img_over = label.iover;
			this.label = "";
			}
		}
	else this.label = "[ERROR]";
	this.url = url;
  //TBD: url to display this popup case mouseover event failure?
	this.isPopup = true;
	this.left = 1;
	this.top = 1;
	this.nodes = new Array();
	// methods
	this.addNode = menuPopup_addNode;
	this.displayPopup = menuPopup_displayPopup;
	this.build = menuPopup_build;
	this.cbeInit = menuPopup_cbeInit;
	}

menuPopup.prototype = new menuNode;

/**************************************/
