var menu_items = [];
var menu_inited = false;
var menu_delay = 0;

if (typeof($D) == 'undefined') alert('dom must be exists!');
else if (typeof($E) == 'undefined') alert('event_handler must be exists!');
else if (typeof($C) == 'undefined') alert('class_handler must be exists!');
else
{
	menu_inited = true;
	if (typeof(menu_state) == 'undefined') menu_state = '';
	menu_create(menu_state);
}

// mi_ prefix refers to menu_item
function menu_create(menu_state)
{
	if (! menu_inited) return false;

	var content = $D.get('menu');
	content.style.display = 'none';

	var menu_state = menu_state.length > 0 ? menu_state.split(',') : [];
	var mi_main_last = null;
	var mi_main_last_selected = null;
	var el = $D.next(content.firstChild);
	while(el)
	{
		var mi_in_state = false;
		for (var i = 0; ! mi_in_state && i < menu_state.length; ++ i)
		{
			mi_in_state = el.href.indexOf(menu_state[i]) > -1;
		}

		if ($C.has(el, 'main'))
		{
			if (mi_main_last_selected)
			{
				var n = mi_main_last_selected.subs.length;
				for (var i = 0; i < n; ++ i)
				{
					$C.add(mi_main_last_selected.subs[i], 'displayed');
				}
				mi_main_last_selected.expanded = 1;
				mi_main_last_selected = null;
			}

			el.expanded = false;
			if (mi_in_state)
			{
				$C.add(el, 'selected');
				mi_main_last_selected = el;
			}
			el.subs = [];
			$E.add(el, 'onclick', menu_toggle);
			$C.add(el, 'displayed');
			mi_main_last = el;
		}
		else if ($C.has(el, 'sub'))
		{
			if (! mi_main_last) alert('Main menu item must be defined first!');

			if (el.href.match('#$'))
			{
				var par = el.parentNode;
				var _el = dom_create('span');
				_el.className = el.className;
				_el.innerHTML = el.innerHTML;
				par.replaceChild(_el, el)
				el = _el;
			}
			else
			{
				$E.add(el, 'onclick', menu_sub_clicked);
			}

			if (mi_in_state)
			{
				el.selected = true;
				$C.add(el, 'selected');
				mi_main_last_selected = mi_main_last;
			}

			mi_main_last.subs.push(el);
		}

		menu_items.push(el);
		el = $D.next(el.nextSibling);
	}

	if (mi_main_last_selected)
	{
		menu_toggle.apply(mi_main_last_selected);
	}

	menu_delay = 50;

	content.style.display = 'block';
}

function menu_toggle()
{
	var subs_len = this.subs.length;
	if (subs_len == 0) return;

	var sub_actual, sub_step, class_name_from, class_name_to;

	if (this.expanded)
	{
		sub_actual = subs_len - 1;
		sub_step = -1;
		class_name_from = 'displayed';
		class_name_to = 'not_displayed';
	}
	else
	{
		class_name_from = 'not_displayed';
		class_name_to = 'displayed';
		sub_actual = 0;
		sub_step = 1;
	}

	for (var i = 0; i < subs_len; ++ i)
	{
		var change_class = menu_swap_class(this.subs[sub_actual], class_name_from, class_name_to);
		setTimeout(change_class, menu_delay * i);
		sub_actual += sub_step;
	}

	this.expanded ^= 1;

	return false;
}

function menu_swap_class(el, class_name_from, class_name_to)
{
	return function()  {
		$C.swap(el, class_name_from, class_name_to);
		if (el.selected) $C.add(el, 'selected');
	}
}

function menu_sub_clicked()
{
	for (var i = 0; i < menu_items.length; ++ i)
	{
		if (menu_items[i].selected)
		{
			menu_items[i].selected = false;
			$C.remove(menu_items[i], 'selected');
		}
	}
	this.selected = true;
	$C.add(this, 'selected');
}

function menu_get_state()
{
	var state = '';
	for (var i = 0; i < menu_items.length; ++ i)
	{
		if (menu_items[i].expanded || menu_items[i].selected)
		{
			if (state.length > 0) state += ',';
			state += new String(i);
		}
	}
	return state;
}
