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)
	{
		if (el.tagName.toLowerCase() == 'a')
		{
			var mi_in_state = false;
			for (var i = 0; ! mi_in_state && i < menu_state.length; ++ i)
				mi_in_state = el.rel == menu_state[i];

			if ($C.has(el, 'main'))
			{
				if (mi_main_last_selected)
				{
					menu_toggle.apply(mi_main_last_selected);
					mi_main_last_selected = null;
				}

				el.expanded = false;
				if (mi_in_state)
				{
					$C.add(el, 'sub_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, 'sub_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(toggle_delay)
{
	if (typeof toggle_delay == 'undefined')
		toggle_delay = menu_delay;

	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 = 'hidden';
	}
	else
	{
		for (i in menu_items)
		{
			if (menu_items[i] == this) continue;
			if (menu_items[i].expanded)
				menu_toggle.apply(menu_items[i], [0]);
		}

		class_name_from = 'hidden';
		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, toggle_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, 'sub_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, 'sub_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;
}