// Title: Tigra Menu PRO
// Description: Tigra Menu PRO is flexible menu solution for commercial
//	applications offering high reliability and wide browsers support.
//	See URL for complete feature list.
// URL: http://www.softcomplex.com/products/tigra_menu_pro/
// Version: 3.0
// Date: 03-12-2002 (mm-dd-yyyy)
// Notes: Registration needed to use this script legally.
//	Visit official site for details.

var o_doc,
	menus = [];
	states = ['mout', 'mover', 'mdown'];

function doc () {
	this.f_width   = window.innerWidth != null ? 
		function () { return window.innerWidth } : 
		function () { return document.body.clientWidth };
	this.f_height  = window.innerHeight != null ?
		function () { return window.innerHeight } :
		function () { return document.body.clientHeight };
	this.f_xscroll = window.pageXOffset != null ? 
		function () { return window.pageXOffset } :
		function () { return document.body.scrollLeft };
	this.f_yscroll = window.pageYOffset != null ?
		function () { return window.pageYOffset } :
		function () { return document.body.scrollTop };
	this.get_element = document.all ?
		function (i) { return document.all[i] } :
		function (i) { return document.getElementById(i) };

	this.update = doc_update;
	this.redraw = doc_redraw;
}

function doc_update () {
	var n_value, b_refresh;
	
	// verify in any environment paramenters changed
	if (this.width != (n_value = this.f_width())) {
		this.width = n_value;
		b_refresh = true;
	}
	if (this.height != (n_value = this.f_height())) {
		this.height = n_value;
		b_refresh = true;
	}
	if (this.xscroll != (n_value = this.f_xscroll())) {
		this.xscroll = n_value;
		b_refresh = true;
	}
	if (this.yscroll != (n_value = this.f_yscroll())) {
		this.yscroll = n_value;
		b_refresh = true;
	}
	if (b_refresh) {
		// ignore updates until parameters are stable
		if (this.o_timer) clearTimeout(this.o_timer);
		this.o_timer = setTimeout('o_doc.redraw()', 200);
//		o_doc.redraw();
	}
	window.setTimeout('o_doc.update()', 50);
}

function doc_redraw () {
	for (var i = 0; i < menus.length; i++)
		if (menus[i].active)
			menus[i].redraw();
}

// --------------------------------------------------------------------------------
// menu class constructor
function menu (item_struct, geom_struct) {
	this.item_struct = item_struct;
	this.geom_struct = geom_struct;
	this.items       = [];
	this.children    = [];
	this.a_position  = [];
	this.over_items  = 0;
	
	this.hide        = menu_hide;
	this.onclick     = menu_onclick;
	this.onmouseout  = menu_onmouseout;
	this.onmouseover = menu_onmouseover;
	this.onmousedown = menu_onmousedown;
	this.pos         = menu_position;
	this.redraw      = menu_redraw;

	// prepare environment object
	if (!o_doc) {
		o_doc = new doc();
		o_doc.update();
	}
	// register in global menus collection
	this.id = menus.length;
	menus[this.id] = this;

	// init children recursively
	for (var i = 0; i < this.item_struct.length; i++)
		new menu_item(i, this, this);
	
	// calculate menu sizes
	var max_x = 0,
		max_y = 0,
		min_x = Number.POSITIVE_INFINITY,
		min_y = Number.POSITIVE_INFINITY;
	for (var i = 0; i < this.children.length; i++) {
		max_x = Math.max(max_x, this.children[i].pos('left') + this.children[i].pos('width'));
		max_y = Math.max(max_y, this.children[i].pos('top')  + this.children[i].pos('height'));
		min_x = Math.min(min_x, this.children[i].pos('left'));
		min_y = Math.min(min_y, this.children[i].pos('top'));
	}

	// init sizes and positioning
	this.a_position.top = 0;
	this.a_position.left = 0;
	this.a_position.width  = max_x - min_x;
	this.a_position.height = max_y - min_y;
	
	this.active = true;
	this.redraw();
}


// --------------------------------------------------------------------------------
// menu methods
// --------------------------------------------------------------------------------
function menu_hide () {
	if (!this.hide_timer || this.over_items || !this.last_item)
		return;
	this.last_item.collapse(0);
	this.last_item = null;
}

function menu_redraw () {

	this.a_position.top =
	this.a_position.left = 0;

	if (this.geom_struct.align == 'center')
		this.a_position.left = Math.round((o_doc.width - this.a_position.width) / 2);
	else if (this.geom_struct.align == 'right')
		this.a_position.left = o_doc.width - this.a_position.width;

	if (this.geom_struct.valign == 'center')
		this.a_position.top = Math.round((o_doc.height - this.a_position.height) / 2);
	else if (this.geom_struct.valign == 'bottom')
		this.a_position.top = o_doc.height - this.a_position.height;
		
	if (this.geom_struct.scroll == 'horizontal' || this.geom_struct.scroll == 'both')
		this.a_position.left += o_doc.xscroll;
	if (this.geom_struct.scroll == 'vertical' || this.geom_struct.scroll == 'both')
		this.a_position.top += o_doc.yscroll;

	for (var i = 0; i < this.children.length; i++) {
		this.children[i].set_state('hidden', true);
		this.children[i].reposition(true);
		this.children[i].set_state('mout');
	}
}

function menu_position (coord) {
	return this.a_position[coord] ? this.a_position[coord] : 0;
}

// --------------------------------------------------------------------------------
// menu event handlers
// --------------------------------------------------------------------------------
function menu_onclick (id) {
	return (this.items[id].fields[1] ? true : false);
}

function menu_onmouseout (id) {
	this.over_items--;
	this.items[id].set_state('mout');
	if (this.items[id].expd_timer) clearTimeout(this.items[id].expd_timer);
	this.hide_timer = setTimeout('menus['+ this.id +'].hide();',
		this.geom_struct.hide_delay[this.items[id].depth]);
}

function menu_onmouseover (id) {
	this.over_items++;
	for (var item = this.items[id]; item.elements; item = item.parent) item.set_state('mover');
	clearTimeout(this.hide_timer);
	this.hide_timer = null;
	if (this.geom_struct.expd_delay && this.geom_struct.expd_delay[this.items[id].depth])
		this.items[id].expd_timer = setTimeout('menus["'+ this.id +'"].items['+ id +'].expand()',
			this.geom_struct.expd_delay[this.items[id].depth]);
	else this.items[id].expand();
}

function menu_onmousedown (id) {
	this.items[id].set_state('mdown');
}

// --------------------------------------------------------------------------------
// menu item class constructor
// --------------------------------------------------------------------------------
function menu_item (path, parent, container) {
	this.path = new String (path);
	this.parent = parent; this.container = container;
	this.arrpath = this.path.split('_');
	this.depth = this.arrpath.length - 1;

	// get reference to item's data in the structure
	var struct_path = '';
	for (var i = 0; i <= this.depth; i++)
		struct_path += '[' + (Number(this.arrpath[i]) + (i ? 3 : 0)) + ']';
	eval('this.fields = this.container.item_struct' + struct_path);
	if (!this.fields) return;

	// register self in the collections
	this.id = this.container.items.length;
	this.container.items[this.id] = this;
	parent.children[parent.children.length] = this;

	// assign browser dependent functions
	if (document.layers) {
		this.write = mitem_lay_write;
		this.set_state = mitem_lay_state;
		this.pos = mitem_lay_position;
	}
	else {
		this.write = mitem_css_write;
		this.set_state = mitem_css_state;
		this.pos = mitem_css_position;
	}
	// assign crossbrowser functions
	this.collapse = mitem_collapse;
	this.expand = mitem_expand;
	this.reposition = mitem_reposition;

	// init self	
	this.item_pos = [];
	this.elements = [];
	this.write(this.reposition(false));
	this.state = 'hidden';
	
	// init children recursively
	this.children = [];
	var child_count = this.fields.length - 3;
	for (var i = 0; i < child_count; i++)
		new menu_item (this.path + '_' + i, this, this.container);
}
// --------------------------------------------------------------------------------
// browser independent methods
// --------------------------------------------------------------------------------

// collapses menu to the level specified
function mitem_collapse(to_level) {
	for (var i = 0; i < this.children.length; i++)
		this.children[i].set_state('hidden');
	if (to_level >= this.depth) this.set_state('mout');
	else this.parent.collapse(to_level);
}

// expands menu to calling items
function mitem_expand() {
	if (this.container.last_item && this.depth <= this.container.last_item.depth)
			this.container.last_item.collapse(this.container.last_item.parent == this ? this.depth+1 : this.depth);
	if (!this.container.last_item || this.container.last_item.parent != this)
	    for (var i = 0; i < this.children.length; i++)
			this.children[i].set_state('mout');
	this.container.last_item = this;
}
// calculates items position and updates it if requested
function mitem_reposition (update) {

	if (this.arrpath[this.depth] == 0) {
		this.item_pos.left = this.parent.pos('left')
			+ (this.fields[2] != null && this.fields[2][0] != null
			? this.fields[2][0] : this.container.geom_struct.block_left[this.depth]);
		this.item_pos.top  = this.parent.pos('top') 
			+ (this.fields[2] != null && this.fields[2][1] != null
			? this.fields[2][1] : this.container.geom_struct.block_top[this.depth]);
	}
	else {
		this.item_pos.left = this.parent.children[this.arrpath[this.depth] - 1].pos('left')
			+ (this.fields[2] != null && this.fields[2][0] != null ? this.fields[2][0]
			: this.container.geom_struct.left[this.depth]);
		this.item_pos.top  = this.parent.children[this.arrpath[this.depth] - 1].pos('top')
			+ (this.fields[2] != null && this.fields[2][1] != null ? this.fields[2][1]
			: this.container.geom_struct.top[this.depth]);
	}
	this.item_pos.width  = (this.fields[2] != null && this.fields[2][2] != null
		? this.fields[2][2] : this.container.geom_struct.width[this.depth]);
	this.item_pos.height = (this.fields[2] != null && this.fields[2][3] != null
		? this.fields[2][3] : this.container.geom_struct.height[this.depth]);
	
	if (!update) return this.item_pos;
	this.pos('left', this.item_pos.left);
	this.pos('top',  this.item_pos.top);

	for (var i = 0; i < this.children.length; i++)
		this.children[i].reposition(true);
}

// --------------------------------------------------------------------------------
// CSS positioning methons version
// --------------------------------------------------------------------------------

// item initialisation
function mitem_css_write (pos) {
	for (var i = 0; i < states.length; i++) {
		document.write (
			'<div id="m' + this.container.id + 'i' + this.id + states[i]
			+ '" style="position: absolute; left: ' + pos.left + 'px; top: '
			+ pos.top + 'px; width: ' + pos.width + 'px; height: ' + pos.height
			+ 'px; visibility: hidden; z-index: ' + this.depth * 2 + ';" class="m'
			+ this.container.id + 'l' + this.depth + states[i] + 'o"><div class="m'
			+ this.container.id + 'l' + this.depth + states[i] + 'i">'
			+ (typeof(this.fields[0]) == 'object' ? this.fields[0][i] : this.fields[0])
			+ '</div></div>');
		this.elements[states[i]] = o_doc.get_element('m' + this.container.id + 'i' + this.id + states[i]);
	}
	document.write(
		'<div id="m' + this.container.id + 'i' + this.id + 'i" style="position: absolute; left: '
		+ pos.left + 'px; top: ' + pos.top + 'px; width: ' + pos.width + 'px; height: '
		+ pos.height + 'px; visibility: hidden; z-index: ' + (this.depth * 2 + 1) + ';"><a href="'
		+ (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][0] != null ? this.fields[1][0] : this.fields[1])
		+ '"' + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][1] != null ? ' target="' + this.fields[1][1]
		+ '"' : '') + ' onclick="return menus[' + this.container.id + '].onclick(' + this.id 
		+ ');" onmouseout="menus['  + this.container.id + '].onmouseout('  + this.id
		+ ');" onmouseover="menus[' + this.container.id + '].onmouseover(' + this.id
		+ ');" onmousedown="menus[' + this.container.id + '].onmousedown(' + this.id
		+ ');"><img src="' + this.container.geom_struct['pixel_path']
		+ '" width="' + pos.width +'" height="' + pos.height + '" border="0"'
		+ (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][2] != null ? ' alt="'
		+ this.fields[1][2] + '"' : '') + '></a></div>');
	this.link = o_doc.get_element('m' + this.container.id + 'i' + this.id + 'i');
}

// swithces states of menu item
function mitem_css_state(state, force) {
	if (!this.depth && state == 'hidden' && !force) state = 'mout';
	if (state == this.state) return;
	if (this.state == 'hidden') this.link.style.visibility = 'visible';
	else this.elements[this.state].style.visibility = 'hidden';
	if (state == 'hidden') this.link.style.visibility = 'hidden';
	else this.elements[state].style.visibility = 'visible';
	this.state = state;
}

// sets or retreives item's position on the page
function mitem_css_position (coord, value) {
	if (!coord) return;
	if (this.link.style.pixelLeft)
		if (coord == 'left')        coord = 'pixelLeft';
		else if (coord == 'top')    coord = 'pixelTop';
		else if (coord == 'width')  coord = 'pixelWidth';
		else if (coord == 'height') coord = 'pixelHeight';

	if (value) {
		for (var i = 0; i < states.length; i++)
			this.elements[states[i]].style[coord] = value + (this.link.style.pixelLeft?0:'px');
		this.link.style[coord] = value + (this.link.style.pixelLeft?0:'px');
		return (this.item_pos[coord] = value);
	}
	else {
		var re_num = /^(\-?\d+)/;
		if (re_num.exec(this.link.style[coord]))
			return new Number(RegExp.$1);
	}
}

// --------------------------------------------------------------------------------
// Layers positioning methods version
// --------------------------------------------------------------------------------

// item initialisation
function mitem_lay_write (pos) {
	for (var i = 0; i < states.length; i++) {
		document.write(
			'<layer name="m' + this.container.id + 'i' + this.id + states[i]
			+ '" left="' + pos.left + '" top="' + pos.top + '" z-index="'
			+ this.depth * 2  + '" width="' + pos.width + '" height="'
			+ pos.height + '" visibility="hide"><table cellpadding="0" cellspacing="0" border="0" width="'
			+ pos.width + '" height="' + pos.height + '" class="m'
			+ this.container.id + 'l' + this.depth + states[i] + 'o"><tr><td><div class="m'
			+ this.container.id + 'l' + this.depth + states[i] + 'o"><div class="m'
			+ this.container.id + 'l' + this.depth + states[i] + 'i">'
			+ (typeof(this.fields[0]) == 'object' ? this.fields[0][i] : this.fields[0])
			+ '</div></div></td></tr></table></layer>');
		this.elements[states[i]] = document.layers['m' + this.container.id + 'i' + this.id + states[i]];
	}	
	document.write(
		'<layer name="m' + this.container.id + 'i' + this.id + 'i" left="'
		+ pos.left + '" top="' + pos.top + '" z-index="' + (this.depth * 2 + 1)
		+ '" visibility="hide" width="' + pos.width +'" height="' + pos.height
		+ '"><a href="' + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][0] != null ? this.fields[1][0] : this.fields[1])
		+ '"' + (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][1] != null ? ' target="'
		+ this.fields[1][1] + '"' : '')	+ ' onclick="return menus[' + this.container.id
		+ '].onclick(' + this.id + ');" onmouseout="menus[' + this.container.id
		+ '].onmouseout(' + this.id + ');" onmouseover="menus[' + this.container.id
		+ '].onmouseover(' + this.id + ');" onmousedown="menus[' + this.container.id
		+ '].onmousedown(' + this.id + ');"><img src="' + this.container.geom_struct['pixel_path']
		+ '" width="' + pos.width +'" height="' + pos.height + '" border="0"'
		+ (this.fields[1] != null && typeof(this.fields[1]) != 'string' && this.fields[1][2] != null ? ' alt="'
		+ this.fields[1][2] + '"' : '')	+ '></a></layer>');
	this.link = document.layers['m' + this.container.id + 'i' + this.id + 'i'];
}

// swithces states of menu item
function mitem_lay_state(state) {
	if (!this.depth && state == 'hidden') state = 'mout';
	if (state == this.state) return;
	if (this.state == 'hidden') this.link.visibility = 'show';
	else this.elements[this.state].visibility = 'hide';
	if (state == 'hidden') this.link.visibility = 'hide';
	else this.elements[state].visibility = 'show';
	this.state = state;
}

// sets or retreives item's position on the page
function mitem_lay_position (coord, value) {
	if (!coord) return;
	if (value) {
		this.item_pos[coord] = value;
		for (var i = 0; i < states.length; i++) {
			this.elements[states[i]].moveTo   (this.item_pos.left, this.item_pos.top);
			this.elements[states[i]].resizeTo (this.item_pos.width, this.item_pos.height);
		}
		this.link.moveTo   (this.item_pos.left, this.item_pos.top);
		this.link.resizeTo (this.item_pos.width, this.item_pos.height);
	}
	return this.item_pos[coord];
}

// --------------------------------------------------------------------------------
// that's all folks
