/*
* Victor A.Spirin - victor_aspirin [at] mail [dot] ru
* version: 1.0.3
* date: 2004.03.03
*/



function buildMenus()
	{
	var es = document.getElementsByTagName('a');
		for( var i = 0 ; i < es.length ; i++ )
		{
			if( es[i].getAttribute('menu-id') != null && es[i].menuControl == null ) var mc = new MenuControl(es[i]);
		}
	}



// class
function MenuControl( htmlElement )
	{
	var DELAY_HIDE_MENU = 250;
	var ROLLOVER_REGEXP = /off\./gi;
	var ROLLOVER_SUFFIX = 'on.';
	
	var state;
	var element;
	var styles;
	var itemset;
	var parentItemset;
	
	var This = this;
	
	function init( e )
		{
		state = 'off';
		element = patchDOM(e);
		e.menuControl = This;
		e.addEventListener('mouseover', m_over, false);
		e.addEventListener('mouseout', m_out, false);
		
		styles = {init: {}};
		var s = getComputedStyle(e, null);
			if( s.length != null )
				for( var i = 0 ; i < s.length ; i++ )
				{
				var n = s.item(i);
				styles.init[n] = s.getPropertyValue(n);
				}
			else
				for( var n in s )
				styles.init[n] = s[n];
		var imgs = e.getElementsByTagName('img');
			if( imgs.length != 0 && !imgs[0].hasRollover && imgs[0].src.search(ROLLOVER_REGEXP) != -1 )
			{
			var r = new RolloverImage(imgs[0], ROLLOVER_REGEXP, ROLLOVER_SUFFIX);
//				if( (s.length != null ? s.getPropertyValue('display') : s.display) != 'none' )
//				document.getOverrideStyle(e, null).display = 'block';
			}
		}
	
	function _search()
		{
		var id = element.getAttribute('menu-id');
		var m = document.getElementById(id);
			if( m == null ) return alert('Illegal attribute menu-id: ' + id);
		itemset = new MenuItemset(m, This);
		
		var p = element;
			while( p != document.body )
			{
				if( typeof(p.menu) == 'object' )
				{
				parentItemset = p.menu;
				break;
				}
			p = p.parentNode;
			}
		}
	
	function _calc()
		{
		var s = getComputedStyle(element, null);
		var init = styles.init;
		styles.init = null;
		styles.off = {};
		styles.on = {};
			if( s.length != null )
				for( var i = 0 ; i < s.length ; i++ )
				{
				var n = s.item(i);
				var v = s.getPropertyValue(n);
					if( v != init[n] )
					{
					styles.off[n] = init[n];
					styles.on[n] = v;
					}
				}
			else
				for( var n in s )
					if( s[n] != init[n] )
					{
					styles.off[n] = init[n];
					styles.on[n] = s[n];
					}
		}
	
	function m_over( evt )
		{
			if( document.isMSIE && element.contains(evt.fromElement) ) return;
			if( itemset == null ) _search();
		itemset.switchOn();
		itemset.layuot(element, element.getAttribute('menu-layout'), element.getAttribute('menu-align'));
		}
	
	function m_out( evt )
		{
			if( document.isMSIE && element.contains(evt.toElement) ) return;
			if( styles.on == null ) _calc();
		itemset.switchOffAfter(DELAY_HIDE_MENU);
		}
	
	this.switchOn = function ()
		{
		_switch('on');
			if( parentItemset != null ) parentItemset.switchOn(This);
		}
	
	this.switchOff = function ()
		{
		_switch('off');
			if( parentItemset != null ) parentItemset.switchOff(This);
		}
	
	function _switch( st )
		{
		state = st;
		var s = document.getOverrideStyle(element, null);
			if( s.length != null )
				for( var n in styles[state] )
				s.setProperty(n, styles[state][n], '');
			else
				for( var n in styles[state] )
				s[n] = styles[state][n];
		}
	
	this.getElement = function ()
		{
		return element;
		}
	
	init(htmlElement);
	}



// class
function MenuItemset( htmlElement, menuControl )
	{
	var state;
	var isLocked;
	var thread;
	var element;
	var control;
	var childControl;
	
	var This = this;
	
	function init( e, mc )
		{
		state = 'off';
		isLocked = false;
		element = patchDOM(e);
		control = mc;
		e.menu = This;
		e.addEventListener('mouseover', m_over, false);
		e.addEventListener('mouseout', m_out, false);
		}
	
	function m_over( evt )
		{
			if( document.isMSIE && element.contains(evt.fromElement) ) return;
		isLocked = true;
		This.switchOn();
		}
	
	function m_out( evt )
		{
			if( document.isMSIE && element.contains(evt.toElement) ) return;
		isLocked = false;
		This.switchOffAfter(10);
		}
	
	this.switchOn = function ( c )
		{
		clearThread();
			if( state != 'on' )
			{
			state = 'on';
			var s = getComputedStyle(element, null);
				if( element.onswitchon != null && (s.length != null ? s.getPropertyValue('display') : s.display) != 'block' )
				element.onswitchon();
			document.getOverrideStyle(element, null).display = 'block';
			}
		control.switchOn();
			if( c != null ) childControl = c;
		}
	
	this.switchOff = function ( c )
		{
			if( c != null && c != childControl ) return;
			if( isLocked ) return;
		clearThread();
			if( state != 'off' )
			{
			state = 'off';
			var s = getComputedStyle(element, null);
				if( element.onswitchoff != null && (s.length != null ? s.getPropertyValue('display') : s.display) != 'none' )
				element.onswitchoff();
			document.getOverrideStyle(element, null).display = 'none';
			}
		control.switchOff();
		childControl = null;
		}
	
	this.switchOffAfter = function ( delay )
		{
		clearThread();
		thread = setTimeout(This.switchOff, delay, null);
		}
	
	function clearThread()
		{
			if( thread == null ) return;
		clearTimeout(thread);
		thread = null;
		}
	
	this.layuot = function ( ce, layout, align )
		{
		var ds = {width: document.body.clientWidth, height: document.body.clientHeight};
		var dp = {x: document.body.scrollLeft, y: document.body.scrollTop};
		var ms = document.getElementSize(element);
		var p = document.getElementPosition(ce);
		var x, y;
			if( layout == 'top' )
			{
			x = (align == 'right' || dp.x + ds.width < p.x + ms.width) ? p.x + document.getElementSize(ce).width - ms.width : p.x;
			y = p.y - ms.height;
			}
			else if( layout == 'left' )
			{
			x = p.x - ms.width;
			y = (align == 'bottom' || dp.y + ds.height < p.y + ms.height) ? p.y - ms.height + document.getElementSize(ce).height : p.y;
			}
			else if( layout == 'right' )
			{
			var cs = document.getElementSize(ce);
			x = p.x + cs.width;
			y = (align == 'bottom' || dp.y + ds.height < p.y + ms.height) ? p.y - ms.height + cs.height : p.y;
			}
			else
			{
			var cs = document.getElementSize(ce);
			x = (align == 'right' || dp.x + ds.width < p.x + ms.width) ? p.x + cs.width - ms.width : p.x;
			y = p.y + cs.height;
			}
		document.setElementPosition(element, x, y);
		}
	
	this.getElement = function ()
		{
		return element;
		}
	
	init(htmlElement, menuControl);
	}

