// Title: Tigra Menu GOLD
// URL: http://www.softcomplex.com/products/tigra_menu_gold/
// Version: 3.0
// Date: 12/03/2008
// Notes: commercial software, licensing required

// --------------------------------------------------------------------------------
// MENU
// --------------------------------------------------------------------------------
function menu (a_items, a_tpl, a_params) {

	// store received parameters
	this.a_config = a_items;
	this.a_tpl = a_tpl;
	if (!a_params) a_params = {};
	this.a_params = a_params;

	// e_body is used in some methods but it's presentse indicates the compatible browser
	if (document.getElementsByTagName)
		this.e_body = document.getElementsByTagName("body").item(0);
	
	// flag to generate all layers at load
	this.b_noDynamic = /*b_ieMac || */b_opera6;

	// get menu id and register in global collection
	this.s_id = a_params.key ? a_params.key : A_MENUS.length;
	A_MENUS[this.s_id] = A_MENU_IDX[A_MENU_IDX.length] = this;
	

	// declare collections
	this.a_blocks = [];
	this.a_index  = [];
	this.a_activeItems = [];

	// declare required properties
	this.o_root     = this;
	this.n_depth    = -1;
	this.n_onBorder = 0;
	this.s_status   = '';

	// assign methods
	this.f_event = f_menuEvent;
	this.f_eventBcast = f_menuEventBcast;
	if (a_params.events && typeof(a_params.events) == 'function')
		this.f_evHandler = a_params.events;

	// get reference to closest parent shared by the menu instances in different frames	
	this.e_topWindow = parent;
	if (a_params.nesting)
		for (var i = 1; i < a_params.nesting; i++) 
			this.e_topWindow = this.e_topWindow.parent;

	// frames detected
	if (window != top) {
		var a_frameset = a_params.frames;
		// check if using frames as master or as slave
		if (a_frameset && (!a_frameset.length || !a_frameset[0].length)) {
			// master, no slaves
		}
		else if (a_frameset) {
			// master with slaves
			if (!this.e_topWindow.a_framesets)
				this.e_topWindow.a_framesets = {};
			this.b_frames = 1; // master
		}
		else
			// slave (2 - ready, 3 - waiting)
			this.b_frames = (this.e_topWindow.a_framesets && this.e_topWindow.a_framesets[this.s_id]) ? 2 : 3;
	}
	// create root level block
	new mblock(this);
	if (a_params.popup)	return;
	if (this.b_frames == 1)
		this.e_topWindow.a_framesets[this.s_id] = a_frameset;
}

// --------------------------------------------------------------------------------
function f_menuEventBcast (s_event, n_id) {

	if (window == top || !this.e_topWindow.a_framesets || !this.e_topWindow.a_framesets[this.s_id])
		return;
	var a_frameset = this.e_topWindow.a_framesets[this.s_id];
	
	// collect information about menu instances
	var a_menus = [], o_master;
	for (var i = 0; i < a_frameset.length; i++)
		for (var j = 0; j < a_frameset[i].length; j++) {
			if (!a_frameset[i][j]) continue;
			var e_frame = this.e_topWindow,
				a_windowLevels = a_frameset[i][j].split('.');
			for (var k = 0; k < a_windowLevels.length; k++)
				e_frame = e_frame.frames[a_windowLevels[k]];

			try {
				if (e_frame &&
					e_frame.A_MENUS &&
					e_frame.A_MENUS[this.s_id]
				) {
					var o_menu = e_frame.A_MENUS[this.s_id];
					if (o_menu.b_frames == 1)
						o_master = o_menu;
					else 
						a_menus[a_menus.length] = o_menu;
				}
			}
			catch (o_exception) {
			}
		}

	var b_result = o_master.f_event(s_event, n_id, 1);
	// determine if position update is needed
	var b_updatePos = (s_event == 'iclps' || ((s_event == 'iover' || s_event == 'iout' || s_event == 'idown') && !this.a_index[n_id].n_depth));

	for (var i = 0; i < a_menus.length; i++) {
		a_menus[i].f_event(s_event, n_id, 1);
		if (b_updatePos)
			a_menus[i].o_submenu.f_show();
	}
	return b_result;
}

// --------------------------------------------------------------------------------
function f_menuEvent (s_event, n_id, b_broadcast) {

	// workaround for ff lost context on redirect issue
	try {window.status = '';} catch (e) { return; }

	// exit if oldest browser except for click
	if (!this.e_body && s_event != 'iclick')
		return true;
		
	if (this.b_frames && !b_broadcast)
		return this.f_eventBcast(s_event, n_id);

	// find the item reference
	var o_item;
	if (n_id != null) {
		o_item = this.a_index[n_id];
		if (!o_item) return;
	}

	//  custom event handler
	if (this.f_evHandler && !this.f_evHandler(s_event, n_id))
		return false;
	
	// item mouseout
	if (s_event == 'iout') {
	
		// cancel block display
		if (this.o_Timer) clearTimeout(this.o_Timer);

		// custom event handler
		if (o_item.f_oo && !o_item.f_oo()) return;
		
		if (!o_item.b_expanded)
			o_item.f_onMouseEvent(0);

		this.o_Timer = setTimeout(
			'A_MENUS[\''+ this.s_id +'\'].f_event(\'iclps\',' + n_id + ')',
			o_item.f_getProperty('dh')
		);
		return;
	}
	// item mouseover
	else if (s_event == 'iover') {

		// cancel menu collapse
		if (this.o_Timer) clearTimeout(this.o_Timer);

		// custom event handler
		if (o_item.f_oh && !o_item.f_oh()) return;

		// mouseover new item
		o_item.f_onMouseEvent(1);
		
		// refresh status bar message
		if (o_item.f_getProperty('sb'))
			this.s_status = o_item.o_lastProp;
		else {
			var s_caption = (typeof(o_item.a_config[0]) == 'object' ? o_item.a_config[0][0] : o_item.a_config[0]);
			this.s_status = unescape(s_caption.replace(/\<[^\>]*\>/g, '') + (o_item.a_config[1] ? " (" + o_item.a_config[1] + ")" : ''));
		}
		top.status = this.s_status;

		// open if positive delay provided
		if (o_item.f_getProperty('de') >= 1)
			this.o_Timer = setTimeout('A_MENUS[\''+ this.s_id +'\'].f_event(\'iexpd\',' + n_id + ')', o_item.o_lastProp);
		return true;
	}
	// item mousedown
	else if (s_event == 'idown') {
		o_item.f_onMouseEvent(2);
		return false;
	}
	// item click
	else if (s_event == 'iclick') {

		if (this.o_Timer != null)
			clearTimeout(this.o_Timer);

		// collapse item if needed
		if (o_item.f_getProperty('cc', this.b_frames)) {
			this.f_event('mclps');
		}
		else if (this.a_params.popup && o_item.a_config[1]) {
			this.f_event('mclps');
			this.o_submenu.f_hide();
		}
		else
			// open on click
			this.f_event('iexpd', n_id);

		if (!o_item.a_config[1] || (b_broadcast && this.b_frames > 1))
			return false;

		return Boolean(o_item.a_config[1]);
	}
	// block mouseover
	else if (s_event == 'bover') {
		this.n_onBorder = 1;
		return;
	}
	// block mouseout
	else if (s_event == 'bout') {
		this.n_onBorder = 0;

		if (!this.a_activeItems.length)
			return true;
		if (!this.n_onBorder) {
			if (this.o_Timer) clearTimeout(this.o_Timer);
			this.o_Timer = setTimeout(
				'A_MENUS[\''+ this.s_id +'\'].f_event(\'iclps\')',
				this.a_activeItems[this.a_activeItems.length - 1].f_getProperty('dh')
			);
		}
		return;
	}
	// item expand
	else if (s_event == 'iexpd') {

		// custom event handler
		if (o_item.f_oe && !o_item.f_oe()) return;
		
		// collapse previously expaned blocks to current parent
		var n_depth = o_item.n_depth;
		var o_prevItem = this.a_activeItems[n_depth];
		var n_collapseTo =  n_depth - (o_prevItem == o_item ? 0 : 1);
		for (i = this.a_activeItems.length - 1; i > n_collapseTo; i--) {
			if (this.a_activeItems[i])
				this.a_activeItems[i].f_collapse();
		}

		if (o_prevItem != o_item) {
			o_item.f_expand();
			this.a_activeItems[n_depth] = o_item;
		}
		this.a_activeItems.length = n_depth + 1;
		return;
	}
	// item collapse
	else if (s_event == 'iclps') {

		// postbone collapse if mouse is on the border
		if (this.n_onBorder)
			return;
		// collapse all blocks
		if (this.o_Timer != null)
			clearTimeout(this.o_Timer);
		for (i = this.a_activeItems.length - 1; i >= 0; i--)
			if (this.a_activeItems[i])
				this.a_activeItems[i].f_collapse();
		this.a_activeItems.length = 0;
		
		if (this.a_params.popup)
			this.o_submenu.f_hide();
		
		top.status = '';
		return;
	}
	// forced menu collapse
	else if (s_event == 'mclps') {
		this.n_onBorder = 0;
		return  this.f_event('iclps');
	}
	// show menu
	else if (s_event == 'mshow') {
//		this.f_event('mclps'); // >>> what's this for?
		this.o_submenu.f_show();
		return;
	}
	// >>> debug message for runaway event
	alert("Runaway Event:" + s_event + ", ID=" + n_id);
}

// --------------------------------------------------------------------------------
// MENU BLOCK
// --------------------------------------------------------------------------------
function mblock (o_parent) {

	// save parent reference in the properties
	this.o_parent = o_parent;
	this.o_root   = o_parent.o_root;
	this.n_depth  = o_parent.n_depth + 1;
	
	// register in the root collection
	this.n_id = this.o_root.a_blocks.length;
	this.o_root.a_blocks[this.n_id] = this;

	// register in parent
	o_parent.o_submenu = this;

	// assign methods
	this.f_getHTML     = mb_getHTML;
	this.f_getProperty = mb_getProperty;
	this.f_getStyle    = mb_getStyle;
	this.f_getPosition = mb_getPosition;
	this.f_syncGlass   = mb_syncGlass;
	this.f_init = mb_init;
	this.f_show = mb_show;
	this.f_hide = mb_hide;
	
	// create subm-items objects
	this.a_items = [];
	var o_current_item;
	for (var i = (this.n_depth ? 3 : 0); i < o_parent.a_config.length; i++) {
		o_current_item = o_parent.a_config[i];
		// skip corrupted items
		if (!o_current_item || typeof(o_current_item) != 'object')
			continue;
		// create subitem
		new mitem(this, o_current_item);
	}
	this.f_init();
}

// --------------------------------------------------------------------------------
function mb_init () {
	var n_zIndex = this.n_zIndex = (this.n_depth + 1) * 3
		+ (this.o_root.a_params.zIndex ? parseInt(this.o_root.a_params.zIndex) : 0);

	var n_left    = this.f_getProperty('bl'),
		n_top     = this.f_getProperty('bt'),
		n_opacity = this.f_getProperty('op');

	// position relative if root level 
	this.b_relative = !this.n_depth &&
		// ... and coordinates not specified
		(n_left == null || n_top == null) &&
		 // ... and non in frames or master frame
		(!this.o_root.b_frames || this.o_root.b_frames < 2) &&
		//  ... and not popup mode
		(!this.o_root.a_params.popup);

	// prepare filters
	var s_filter = '';
	if (this.f_getProperty('be')) {
		this.a_transitions = this.o_lastProp;
		s_filter += this.o_lastProp.join(' ');
	}
	if (this.f_getProperty('sd')) {
		this.a_shadow = this.o_lastProp;
		s_filter += ' progid:DXImageTransform.Microsoft.Shadow(strength=' + this.a_shadow.strength + ',direction=' + this.a_shadow.direction + ',color=' + this.a_shadow.color + ')';
	}
	if (n_opacity)
		s_filter += ' alpha(opacity=' + n_opacity + ')';
	
	// create statically in document
	if (this.b_relative) {
		document.write (this.f_getHTML());
	}
	// create dynamically in layers
	else if (!this.o_root.b_noDynamic && this.n_depth) {
	
		// absolute positioning - dynamicaclly created
		this.e_div = document.createElement("DIV");
		this.e_div.style.position = 'absolute';
		this.e_div.style.zIndex = n_zIndex;
		this.e_div.style.left = '-1000px';
		this.e_div.style.top  = '-1000px';
		this.e_div.style.visibility = 'hidden';
		this.e_div.style.filter = s_filter;
		if (n_opacity)	this.e_div.style.MozOpacity = n_opacity / 100;

		this.e_div.innerHTML = this.f_getHTML();
		this.o_root.e_body.appendChild(this.e_div);
		
		// selectbox suppression in IE6
		if (b_ie6) {
			this.e_iframe = document.createElement("IFRAME");
			// avoid non secure content message under HTTPS
			if (this.o_root.a_params.pixel)
				this.e_iframe.src = this.o_root.a_params.pixel;
			this.e_iframe.style.position = 'absolute';
			this.e_iframe.style.zIndex = n_zIndex - 1;
			this.e_iframe.style.visibility = 'hidden';
			this.e_iframe.style.filter = 'alpha(opacity=0)';
			this.o_root.e_body.appendChild(this.e_iframe);
		}
	}
	// create statically in layers
	else {
		if (!n_left || !n_top) n_left = n_top  = 0;

		document.write (this.f_getHTML(n_left, n_top));
		this.e_div = getElement('m' + this.o_root.s_id + 'bl' + this.n_id + 'tb');
		this.e_div.style.filter = s_filter;

		if (n_opacity)	this.e_div.style.MozOpacity = n_opacity / 100;
		if ((b_ie5 || b_ie6) && !b_opera6 && !b_ieMac) {
			document.write('<iframe' + (this.o_root.a_params.pixel ? ' src="' + this.o_root.a_params.pixel + '"' : '') +
				' style="position:absolute;visibility:hidden;z-index:' + (n_zIndex - 1) + '" id="m' +
				this.o_root.s_id + 'bl' + this.n_id + 'if"></iframe>');
			this.e_iframe = getElement('m' + this.o_root.s_id + 'bl' + this.n_id + 'if');
			this.e_iframe.style.filter = 'alpha(opacity=0)';
		}
//		this.f_syncGlass();
	}

	// exit on oldest browsers
	if (!this.o_root.e_body)
		return;
	this.e_table = getElement('m' + this.o_root.s_id + 'bl' + this.n_id + 'tb');
}
// --------------------------------------------------------------------------------
function mb_syncGlass (b_hide) {
	for (var i = 0; i < this.a_items.length; i++)
		this.a_items[i].f_syncGlass(b_hide);
}

// --------------------------------------------------------------------------------
function mb_hide () {
	if (!this.b_relative) this.f_syncGlass(1);

	if (this.a_transitions && this.a_transitions[1]) {
		try {
			if (this.o_root.e_transShow && this.o_root.a_params.oneTrans) {
				this.o_root.e_transShow.stop();
				this.o_root.e_transShow = null;
			}
			var e_transition = this.o_root.e_transHide = this.e_div.filters.item(this.a_transitions[0] ? 1 : 0);
			e_transition.apply();
			this.e_div.style.visibility = 'hidden';
			e_transition.play();
		}
		catch(e) {
			this.e_div.style.visibility = 'hidden';
		};
	}
	else
		this.e_div.style.visibility = 'hidden';

	if (this.e_iframe)
		this.e_iframe.style.visibility = 'hidden';

	return;
}

// --------------------------------------------------------------------------------
function mb_show () {

	// ignore for relatively positioned block
	if (this.b_relative)
		return this.f_syncGlass();

	// adjust the position
	var n_left = this.f_getProperty('bl',0),
		n_top  = this.f_getProperty('bt',0),
		n_scrollLeft = f_scrollLeft(),
		n_scrollTop  = f_scrollTop(),
		n_selfWidth = this.e_table.offsetWidth,
		n_selfHeight = this.e_table.offsetHeight;

	// position submenu relatively to the parent
	if (this.n_depth) {
		var n_leftReg, n_topReg, n_leftRev, n_topRev,
			n_parentLeft = this.o_parent.f_getPosition('Left'),
			n_parentTop  = this.o_parent.f_getPosition('Top'),
			n_parentTable  = this.o_parent.f_getProperty('tb'),
			b_parentVertical = this.o_parent.o_block.f_getProperty('bv') == null ? this.o_parent.o_block.n_depth : this.o_parent.o_block.o_lastProp,
			b_wisePos = this.f_getProperty('wp') && !this.o_root.b_frames,
			b_reverse = this.f_getProperty('rv'),
			n_parentWidth  = this.o_parent.e_itemCell.offsetWidth,
			n_parentHeight = this.o_parent.e_itemCell.offsetHeight;
	
		if (b_wisePos || !b_reverse) {
			n_leftReg = n_parentLeft + n_left + (b_parentVertical ? n_parentWidth + n_parentTable[1] :  -n_parentTable[1]) - (b_ieMac ? n_parentTable[1] : 0);
			n_topReg  = n_parentTop  + n_top  + (b_parentVertical ? - n_parentTable[1] : n_parentHeight + n_parentTable[1]);
		}
		if (b_wisePos || b_reverse) {
			n_leftRev = n_parentLeft - n_left - (b_parentVertical ? n_selfWidth :  0) - n_parentTable[1] * (b_ieMac ? 2 : 1);
			n_topRev  = n_parentTop  - n_top - n_selfHeight + (b_parentVertical ? n_parentHeight + n_parentTable[1] : -n_parentTable[1]) ;
		}

		if (b_wisePos) {
			var n_windowWidth = f_clientWidth(),
				n_windowHeight = f_clientHeight();
			var b_overflowTReg = n_topReg  < n_scrollTop,
				b_overflowTRev = n_topRev  < n_scrollTop,
				b_overflowRReg = (n_leftReg - n_scrollLeft + n_selfWidth) > n_windowWidth,
				b_overflowRRev = (n_leftRev - n_scrollLeft + n_selfWidth) > n_windowWidth,
				b_overflowBReg = (n_topReg  - n_scrollTop  + n_selfHeight) > n_windowHeight,
				b_overflowBRev = (n_topRev  - n_scrollTop  + n_selfHeight) > n_windowHeight,
				b_overflowLReg = n_leftReg < n_scrollLeft,
				b_overflowLRev = n_leftRev < n_scrollLeft;


			//fit
			if ((b_reverse && !b_overflowTRev && !b_overflowBRev) || (!b_reverse && !b_overflowTReg && !b_overflowBReg));
			
			// overflow on both sides
			else if (n_windowHeight <= n_selfHeight)
				n_topReg = n_topRev = n_scrollTop;
			// overflow on one side (regular ok)
			else if (b_reverse  && (b_overflowTRev || b_overflowBRev) && !b_overflowTReg && !b_overflowBReg)
				n_topRev = n_topReg;
			// overflow on one side (reverse ok)
			else if (!b_reverse && (b_overflowTReg || b_overflowBReg) && !b_overflowTRev && !b_overflowBRev)
				n_topReg = n_topRev;
			// overflow on one side (none ok)
			else {
				n_topReg = n_windowHeight - n_selfHeight + n_scrollTop;
				n_topRev = n_scrollTop;
			}
				
			//fit
			if ((b_reverse && !b_overflowRRev && !b_overflowLRev) || (!b_reverse && !b_overflowRReg && !b_overflowLReg));
			
			// overflow on both sides
			else if (n_windowWidth <= n_selfWidth)
				n_leftReg = n_leftRev = n_scrollLeft;
			// overflow on one side (regular ok)
			else if (b_reverse  && (b_overflowLRev || b_overflowRRev) && !b_overflowLReg && !b_overflowRReg)
				n_leftRev = n_leftReg;
			// overflow on one side (reverse ok)
			else if (!b_reverse && (b_overflowLReg || b_overflowRReg) && !b_overflowLRev && !b_overflowRRev)
				n_leftReg = n_leftRev;
			// overflow on one side (none ok)
			else {
				n_leftReg = n_windowWidth - n_selfWidth + n_scrollLeft;
				n_leftRev = n_scrollLeft;
			}
		}
		
		n_left = (b_reverse ? n_leftRev : n_leftReg);
		n_top  = (b_reverse ? n_topRev  : n_topReg);
	}
	else if (this.o_root.b_frames > 1) {
		// slave menu
		var a_frameset = this.o_root.e_topWindow.a_framesets[this.o_root.s_id];
		 // delay display if no frameset information found
		if (!a_frameset) return;

		var n_left = 0, n_top  = 0,
			n_rowHeight, n_colWidth, n_offsetLeft, b_metMaster, b_metSelf;

		// scan row
		for (var i = 0; i < a_frameset.length; i++) {
			n_rowHeight = null;
			n_offsetLeft = 0;
			// scan cell
			for (var j = 0; j < a_frameset[i].length; j++) {

				if (!a_frameset[i][j]) continue;
				var e_frame = this.o_root.e_topWindow,
					a_windowLevels = a_frameset[i][j].split('.');
				for (var k = 0; k < a_windowLevels.length; k++)
					e_frame = e_frame.frames[a_windowLevels[k]];

				if (!e_frame || !e_frame.A_MENUS)
					continue;

				// get the size of the frame
				n_colWidth = e_frame.f_clientWidth();
				if (n_rowHeight == null)
					n_rowHeight = e_frame.f_clientHeight();
				var e_menu = e_frame.A_MENUS[this.o_root.s_id];

				if (e_menu && e_menu.a_params.frames) {
					b_metMaster = 1;
					n_left += e_menu.o_submenu.f_getPosition('Left') - e_frame.f_scrollLeft();
					n_top  += e_menu.o_submenu.f_getPosition('Top') - e_frame.f_scrollTop();
					
					// adjust own size by parent
					this.e_div.style.width  = e_menu.o_submenu.e_table.offsetWidth + 'px'; 
					this.e_div.style.height = e_menu.o_submenu.e_table.offsetHeight + 'px'; 
				}
				if (e_menu && e_menu == this.o_root) {
					b_metSelf = 1;
					n_left += n_scrollLeft;
					n_top  += n_scrollTop;
				}
				if (b_metMaster && b_metSelf)
					break;

				if (b_metMaster)
					n_offsetLeft -= n_colWidth;
				else if (b_metSelf)
					n_offsetLeft += n_colWidth;

			}
			if (b_metMaster && b_metSelf) {
				n_left += n_offsetLeft;
				break;
			}
			else if (b_metMaster)
				n_top -= n_rowHeight;
			else if (b_metSelf)
				n_top += n_rowHeight;
		}
		// delay display if master not found but self found
		if (!b_metMaster && b_metSelf) return;
	}
	// pop-up mode
	else if (this.o_root.a_params.popup) {
		n_left += n_mouseX;
		n_top  += n_mouseY;
	}
		
	// get coordinates of the parent item and calculate own coordinates
	this.e_div.style.left = n_left + 'px';
	this.e_div.style.top  = n_top  + 'px';

	if (this.e_iframe) {
		this.e_iframe.style.width = n_selfWidth + (this.a_shadow ? this.a_shadow.strength : 0) + 'px';
		this.e_iframe.style.height  = n_selfHeight + (this.a_shadow ? this.a_shadow.strength : 0) +  'px';
		this.e_iframe.style.left = n_left + 'px';
		this.e_iframe.style.top  = n_top  + 'px';
		this.e_iframe.style.visibility = 'visible';
	}

	// run transition
	if (this.a_transitions && this.a_transitions[0]) {
		try {
			if (this.o_root.e_transHide && this.o_root.a_params.oneTrans) {
				this.o_root.e_transHide.stop();
				this.o_root.e_transHide = null;
			}
			var e_transition = this.o_root.e_transShow = this.e_div.filters.item(0);
			e_transition.apply();
			this.e_div.style.visibility = 'visible';
			e_transition.play();
		} catch(e) {
			this.e_div.style.visibility = 'visible';
		};
	}
	else
		this.e_div.style.visibility = 'visible';

	// align mouse sensitive layer
	this.f_syncGlass();
}

// --------------------------------------------------------------------------------
// returns the block property
// first searches in block scope then in current level scope then inherits recursively
function mb_getProperty (s_prop, o_default) {

	// check if called for block or item
	var o_item = this.a_config ? this : this.o_parent;

	// use local property
	if (o_item
			&& o_item.a_config[2]
			&& typeof(o_item.a_config[2]) == 'object'
			&& o_item.a_config[2][s_prop]
		)
		return (o_item.a_config[2][s_prop] == 'auto'
			? (this.o_lastProp = null)
			: (this.o_lastProp = o_item.a_config[2][s_prop])
		);

	if (o_default == null)
		o_default = A_MENUDEFAULTS[s_prop];

	s_prop = A_MENUKEYS[s_prop];
	if (!s_prop)
		return (this.o_lastProp = null);

	var n_depth = this.n_depth,
		a_props = this.o_root.a_tpl,
		s_result;

	do {
		if (a_props[n_depth]) {
			if (a_props[n_depth][s_prop] == 'auto')
				break;
			if (a_props[n_depth][s_prop] != null)
				return (this.o_lastProp = a_props[n_depth][s_prop]);
		}
		n_depth--;
	}
	while(n_depth >= 0);
	
	if (this.o_root.a_params[s_prop])
		return (this.o_lastProp = this.o_root.a_params[s_prop]);

	return (this.o_lastProp = o_default);
}

// --------------------------------------------------------------------------------
function mb_getStyle (s_pos, n_state) {

	var a_oclass, a_css,
		o_item = this;

	do {
		a_css = o_item.f_getProperty('sl');
		if (a_css)
			a_oclass = a_css[s_pos];
		o_item = o_item.o_parent;
	}
	while(o_item && a_oclass == null);
	if (a_oclass == null)
		return '';

	// same class for all states	
	if (typeof(a_oclass) == 'string')
		return a_oclass;

	// inherit class from previous state if not explicitly defined
	for (var n_currst = n_state; n_currst >= 0; n_currst--)
		if (a_oclass[n_currst])
			return a_oclass[n_currst];
}

// --------------------------------------------------------------------------------
function mb_getHTML (n_left, n_top) {
	// if no parameters received generate relatively otherwise absolutely

	var a_items = [],
		b_vertical = this.f_getProperty('bv') == null ? this.n_depth : this.o_lastProp,
		n_width  = this.f_getProperty('bw'),
		n_height = this.f_getProperty('bh'),
		a_table  = this.f_getProperty('tb');

	for (var i = 0; i < this.a_items.length; i++)
		a_items[i] = this.a_items[i].f_getHTML();
		
	return ['<table id="m' + this.o_root.s_id + 'bl' + this.n_id + 'tb" cellpadding="', a_table[0], '" cellspacing="',
		a_table[1], '" border="', a_table[2], '"',
		(!b_vertical && a_table[3] != null ? ' width="'  + a_table[3]  + '"' : ''),
		(!b_vertical && n_height   != null ? ' height="' + n_height + '"' : ''),
		(b_vertical  && n_width    != null ? ' width="'  + n_width  + '"' : ''),
		' class="', this.f_getStyle('table', 0), '"',
		(n_left != null && n_top != null ? ' style="position: absolute;visibility:hidden;z-index:' +
			this.n_zIndex + ';left:' + n_left + 'px;top:' + n_top + 'px;' : ''),
		'" onmouseout="A_MENUS[\'', this.o_root.s_id ,'\'].f_event(\'bout\', ', this.n_id,
		')" onmouseover="A_MENUS[\'', this.o_root.s_id ,'\'].f_event(\'bover\', ', this.n_id,
		')"><tbody><tr>', a_items.join(b_vertical ? '</tr><tr>' : ''), '</tr></tbody></table>'
	].join('');
}

// --------------------------------------------------------------------------------
function mb_getPosition (s_coord) {
	return this.o_root.a_index[0].f_getPosition (s_coord, this.e_table)
}

/// --------------------------------------------------------------------------------
// MENU ITEM
// --------------------------------------------------------------------------------
function mitem (o_block, a_config) {

	// save parameters and properties from the block
	this.o_block  = o_block;
	this.o_parent = o_block.o_parent;
	this.o_root   = o_block.o_root;
	this.n_depth  = o_block.n_depth;
	this.a_config = a_config;
	this.n_state  = 0;

	// register in the root collection
	this.n_id = this.o_root.a_index.length;
	this.o_root.a_index[this.n_id] = this;
	
	// register in parent
	this.n_order = o_block.a_items.length;
	o_block.a_items[this.n_order] = this;
	
	// assign methods
	this.f_getHTML     = mi_getHTML;
	this.f_putGlass    = mi_putGlass;
	this.f_syncGlass   = mi_syncGlass;
	this.f_getProperty = mb_getProperty;
	this.f_getCaption  = mi_getCaption;
	this.f_getPosition = mi_getPosition;
	this.f_getStyle    = mb_getStyle;
	this.f_expand      = mi_expand;
	this.f_collapse    = mi_collapse;
	this.f_onMouseEvent = mi_onMouseEvent;

	var a_handlers = ['wr','oh','oe','oo','oc'];
	for (var i = 0; i < a_handlers.length; i++) {
		var f_handler = this.f_getProperty(a_handlers[i]);
		if (f_handler && typeof(f_handler) == 'function')
			this['f_' + a_handlers[i]] = f_handler;
	}

	// only init root level if oldest browser
	if (!this.o_root.e_body) return;

	// init recursively if not dynamic and has submenu
	if (!this.o_root.b_noDynamic || this.a_config.length < 3 || this.a_config[3] == null)
		return;
	new mblock(this);
}

// --------------------------------------------------------------------------------
function mi_getHTML () {

	// apply sizes if provided
	var b_vertical = this.b_vertical = this.o_block.f_getProperty('bv') == null ? this.o_block.n_depth : this.o_block.o_lastProp,
		n_width    = this.f_getProperty('sw'),
		n_height   = this.f_getProperty('sh');

	return ['<td id="m', this.o_root.s_id, 'io', this.n_id, '"',
		(b_vertical  && n_height != null ? ' height="' + n_height + '"' : ''),
		(!b_vertical && n_width  != null ? ' width="'  + n_width  + '"' : ''),
		// if width is specified for item in horizontal block or if width is specified for the vertical block then allow wrap
		((b_vertical && (this.o_block.f_getProperty('bw') != null || this.o_block.f_getProperty('sw') != null)) || (!b_vertical && n_width) ? '' : ' nowrap'),
		' class="', this.f_getStyle('outer', 0), '">', this.f_getCaption(0) ,'</td>'
	].join('');
}

// --------------------------------------------------------------------------------
function mi_putGlass (b_relative) {
	var s_img = [
		'<a href="', this.a_config[1], '"', 
		(this.f_getProperty('tw') ? ' target="' + this.o_lastProp + '"' : ''),
		(this.f_getProperty('ti') != null? ' tabindex="' + this.o_lastProp + '"' : ''),
		(this.f_getProperty('tt') ? ' title="' + this.o_lastProp + '"' : ''),
		' onclick="return A_MENUS[\'', this.o_root.s_id ,'\'].f_event(\'iclick\', ', this.n_id,
		')" ondblclick="A_MENUS[\'',   this.o_root.s_id ,'\'].f_event(\'idown\', ',  this.n_id,
		')" onmouseover="A_MENUS[\'',  this.o_root.s_id ,'\'].f_event(\'iover\', ',  this.n_id,
		')" onmouseout="A_MENUS[\'',   this.o_root.s_id ,'\'].f_event(\'iout\', ',   this.n_id,
		')" onmousedown="return A_MENUS[\'', this.o_root.s_id ,'\'].f_event(\'idown\', ', this.n_id,
		')" onmouseup="A_MENUS[\'', this.o_root.s_id ,'\'].f_event(\'iover\', ', this.n_id,
		')"><img src="', this.o_root.a_tpl[0]['pixel'], '" height="1" width="1" border="0" id="m',
		this.o_root.s_id, 'im', this.n_id, '"></a>'
	].join('');
	if (b_relative) {
		document.write('<div style="position:absolute;z-index:' + this.o_block.n_zIndex +';left:-1000px;top:-1000px;visibility:hidden;" id="m' + this.o_root.s_id + 'ig' + this.n_id + '">' + s_img + '</div>');
		this.e_glass = getElement('m' + this.o_root.s_id + 'ig' + this.n_id);
	}
	else {
		var e_glass = document.createElement("DIV");
			e_glass.style.position = 'absolute';
			e_glass.style.zIndex = this.o_block.n_zIndex;
			e_glass.style.left = '-1000px';
			e_glass.style.top  = '-1000px';
			e_glass.style.visibility = 'hidden';
			e_glass.innerHTML = s_img;
		this.o_root.e_body.appendChild(e_glass);
		this.e_glass = e_glass;
	}
}

// --------------------------------------------------------------------------------
function mi_syncGlass (b_hide) {
	if (b_hide) {
		this.e_glass.style.visibility  = 'hidden';
		return;
	}
	// create glass if doesn't exist
	if (!this.e_glass)
		this.f_putGlass();

	// get coordinates and size of the menu item
	if (!this.e_itemCell)
		this.e_itemCell = getElement('m' + this.o_root.s_id + 'io' + this.n_id);
	this.e_glass.style.left = this.f_getPosition('Left', 0) + 'px';
	this.e_glass.style.top  = this.f_getPosition('Top', 0, this.b_vertical) + 'px';

	if (!this.e_glassImg)
		this.e_glassImg = getElement('m' + this.o_root.s_id + 'im' + this.n_id);
	this.e_glassImg.style.width  = this.e_itemCell.offsetWidth + 'px';
	this.e_glassImg.style.height = this.e_itemCell.offsetHeight + 'px';
	this.e_glass.style.visibility  = 'visible';
}

// --------------------------------------------------------------------------------
function mi_getCaption (n_state) {
	// return if string
	var s_caption,
		n_currState = n_state;
	if (typeof(this.a_config[0]) == 'object') {
		// inherit if not specified
		while (n_currState && !this.a_config[0][n_currState])
			n_currState--;
		s_caption = this.a_config[0][n_currState];
	}
	else 
		s_caption = this.a_config[0];

	// return state specific value
	if (this.f_wr)
		s_caption = this.f_wr(s_caption, n_state);

	return [
		'<div class="', this.f_getStyle('inner', n_state), '" id="m',
		this.o_root.s_id, 'ii', this.n_id, '">', s_caption, '</div>'
	].join('');
}

// --------------------------------------------------------------------------------
function mi_onMouseEvent (n_state) {
	// skip if no state change
	if (n_state == this.n_state)
		return;

	// HTML rollover
	var s_newValue = this.f_getCaption(n_state);
	if (s_newValue != this.f_getCaption(this.n_state))
		this.e_itemCell.innerHTML = s_newValue;
	
	// Box style rollover
	s_newValue = this.f_getStyle('outer', n_state);
	if (s_newValue != this.f_getStyle('outer', this.n_state))
		this.e_itemCell.className = s_newValue;
	s_newValue = this.f_getStyle('inner', n_state);
	if (s_newValue != this.f_getStyle('inner', this.n_state)) {
		var e_element = getElement('m' + this.o_root.s_id + 'ii' + this.n_id);
		if (e_element)
			e_element.className = s_newValue;
	}

	this.n_state = n_state;
}

// --------------------------------------------------------------------------------
function mi_expand () {
	// exit if no submenu
	if (this.a_config.length < 3 || this.a_config[3] == null)
		return;

	// create the submenu if doesn't yet exist
	if (!this.o_submenu)
		new mblock(this);

	this.o_submenu.f_show();
	this.b_expanded = 1;
}

// --------------------------------------------------------------------------------
function mi_collapse () {
	// mouse out
	this.f_onMouseEvent(0);

	// exit if no submenu
	if (!this.b_expanded)
		return;

	// custom event handler
	if (this.f_oc)
		this.f_oc();
		
	this.o_submenu.f_hide();
	this.b_expanded = 0;
}


// --------------------------------------------------------------------------------
// calculates the coordinates of the parent item
function mi_getPosition (s_coord, e_elemRef, b_adjust) {
	var n_pos = 0, n_offset,
		e_elem = e_elemRef ? e_elemRef : this.e_itemCell;

	while (e_elem) {
		n_offset = e_elem["offset" + s_coord];
		n_pos += n_offset;
		e_elem = (b_adjust && (b_ie5 || b_safari)) && e_elem.tagName == 'TD'
			? e_elem.parentElement
			: e_elem.offsetParent;
	}
	// margin correction in some browsers
	if (b_ieMac/* && (!this.o_root.b_frames || this.o_root.b_frames == 1)*/)
		n_pos += parseInt(this.o_root.e_body[s_coord.toLowerCase() + 'Margin']);
	else if (b_safari && (!this.o_block.b_relative || this.n_depth))
		n_pos -= n_offset;
		
	e_elem = e_elemRef ? e_elemRef : this.e_itemCell;
	while (e_elem != this.o_root.e_body) {
		n_offset = e_elem["scroll" + s_coord];
		if (n_offset && e_elem.style.overflow == 'scroll')
			n_pos -= n_offset;
		e_elem = e_elem.parentNode;
	}
	return n_pos;
}

// --------------------------------------------------------------------------------
// Global functions and variables
// --------------------------------------------------------------------------------
getElement = document.all ?
	function (s_id) { return document.all[s_id] } :
	function (s_id) { return document.getElementById(s_id) };

// --------------------------------------------------------------------------------
function f_clientWidth() {
	if (typeof(window.innerWidth) == 'number')
		return window.innerWidth;
	if (document.documentElement && document.documentElement.clientWidth)
		return document.documentElement.clientWidth;
	if (document.body && document.body.clientWidth)
		return document.body.clientWidth;
	return null;
}
function f_clientHeight() {
	if (typeof(window.innerHeight) == 'number')
		return window.innerHeight;
	if (document.documentElement && document.documentElement.clientHeight)
		return document.documentElement.clientHeight;
	if (document.body && document.body.clientHeight)
		return document.body.clientHeight;
	return null;
}
function f_scrollLeft() {
	if (typeof(window.pageXOffset) == 'number')
		return window.pageXOffset;
	if (document.body && document.body.scrollLeft)
		return document.body.scrollLeft;
	if (document.documentElement && document.documentElement.scrollLeft)
		return document.documentElement.scrollLeft;
	return 0;
}
function f_scrollTop() {
	if (typeof(window.pageYOffset) == 'number')
		return window.pageYOffset;
	if (document.body && document.body.scrollTop)
		return document.body.scrollTop;
	if (document.documentElement && document.documentElement.scrollTop)
		return document.documentElement.scrollTop;
	return 0;
}

// --------------------------------------------------------------------------------
// Global Event Handlers
function f_syncGlass() {
	for (var i = 0; i < A_MENU_IDX.length; i++)
		A_MENU_IDX[i].o_submenu.f_syncGlass();
}

function f_onLoad() {
	for (var i = 0; i < A_MENU_IDX.length; i++) {
		var o_menu = A_MENU_IDX[i];
		if (!o_menu.a_params.popup && o_menu.b_frames != 3)
			o_menu.o_submenu.f_show();
		if (o_menu.b_frames == 1)
			o_menu.f_eventBcast('mshow');
	}
}

function f_windowChange() {
	for (var i = 0; i < A_MENU_IDX.length; i++) {
		var o_menu = A_MENU_IDX[i];
		if (o_menu.b_frames == 1)
			o_menu.f_eventBcast('mclps');
		else
			o_menu.f_event('mclps');
	}
	f_syncGlass();
}

function f_onMouseMove(e_event) {
	if (!e_event && window.event) e_event = window.event;
	if (e_event) {
		n_mouseX = e_event.clientX + f_scrollLeft();
		n_mouseY = e_event.clientY + f_scrollTop();
	}
	return true;
}

// assign mouseover event	
if (window.addEventListener) {
	window.addEventListener('scroll', f_windowChange, false);
	window.addEventListener('resize', f_windowChange, false);
	window.addEventListener('load', f_onLoad, false);
}
else if (window.attachEvent) {
	window.attachEvent('onscroll', f_windowChange);
	window.attachEvent('onresize', f_windowChange);
	window.attachEvent('onload', f_onLoad);
}
else {
	window.onscroll = f_windowChange;
	window.onresize = f_windowChange;

	var f_oldOnload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = f_onLoad;
	}
	else {
		window.onload = function () {
			f_oldOnload();
			f_onLoad();
		}
	}
}

var A_MENUS = [],
	A_MENU_IDX = [],
	n_mouseX = 0,
	n_mouseY = 0;

// --------------------------------------------------------------------------------
var s_userAgent = navigator.userAgent.toLowerCase(),
	re_webkit = /WebKit\/(\d+)/i;

var b_mac = s_userAgent.indexOf('mac') != -1,
	b_ie5 = s_userAgent.indexOf('msie 5') != -1,
	b_ie6 = s_userAgent.indexOf('msie 6') != -1 && s_userAgent.indexOf('opera') == -1,
	b_ieMac = b_mac && b_ie5,
	b_safari = b_mac && re_webkit.exec(s_userAgent) && Number(RegExp.$1) < 500,
	b_opera6 = s_userAgent.indexOf('opera 6') != -1;

// --------------------------------------------------------------------------------
// KEY MAPPING
var A_MENUKEYS = {
	'fm': 'forms',
	'zi': 'zIndex',
	'wr': 'wrapper', 
	'cc': 'clickcollapse',
	'oh': 'onhover',
	'oe': 'onexpand',	
	'oo': 'onmouseout',
	'oc': 'oncollapse',
	'bw': 'width',
	'sw': 'width',
	'bh': 'height',
	'bt': 'block_top',
	'bl': 'block_left',
	'sh': 'height',
	'bv': 'vertical',
	'tb': 'table',
	'sl': 'css',
	'de': 'expd_delay',
	'dh': 'hide_delay',
	'wp': 'wise_pos',
	'rv': 'reverse',
	'be': 'transition',
	'op': 'opacity',
	'sd': 'shadow'
},
// DEFAULTS
A_MENUDEFAULTS = {
	'de': 200,
	'dh': 700,
	'op': 100,
	'tb': [4,1,0],
	'wp': 1
};

// --------------------------------------------------------------------------------

