/*
* Victor A.Spirin, victor_as@mail.ru
* 2003.03.01 - 2004.01.31
*/



function buildMenus( nodeName )
	{
	var es = document.getElementsByTagName(nodeName);
		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 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(element, 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];
		}
	
	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 )
		{
		try {
			if( document.isMSIE && element.contains(evt.fromElement) ) return;
			if( itemset == null ) _search();
		itemset.switchOn();
//		if (element.getAttribute('menu-layout') != null && element.getAttribute('menu-align') != null )
  		  itemset.layuot(element, element.getAttribute('menu-layout'), element.getAttribute('menu-align'));
		} catch(err) {
		alert(err);
		}
		}
	
	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);
			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';
				if( element.onswitchon != null && getComputedStyle(element, null).display != 'block' ) element.onswitchon();
		element.style.display = 'block';
//			document.getComputedStyle(element, null).display = 'block';
//			document.getOverrideStyle(element).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';
				if( element.onswitchoff != null && getComputedStyle(element, null).display != 'none' ) element.onswitchoff();
			element.style.display = 'none';
//			document.getOverrideStyle(element).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 = document.getElementSize(document.documentElement);//.body
		var ms = document.getElementSize(element);
		var p = document.getElementPosition(ce);
		var x, y;
			if( layout == 'top' )
			{
			x = (align == 'right' || 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' || 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' || ds.height < p.y + ms.height) ? p.y - ms.height + cs.height : p.y;
			}
			else
			{
			var cs = document.getElementSize(ce);
			x = (align == 'right' || 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);
	}

