/*********************************************************
*		Dynamic Menu CLASS
*		Designed & developed by Dima Svirid, 2007
*		Class: menu.js
*	  Extends: system.js
*********************************************************/
$WI.Class.Menu = new $WI.Class({
	Create: function(options) {
		if(!options) var options = {};
		this.options = options;
		if(!this.options.timeout)	this.options.timeout = 500;
		this.mainmenus = [];
		this.submenus = [];
		this.allitems = [];
		this.dataType = 'html';
		if(this._isIE6()) this.options.effect = false;
		this.obj = this._createDOM({objType: 'div', objClass: 'element-menu'});
		if (this.AddDOMEvent == undefined)
			this.AddDOMEvent = this.AddEvent;

		this.AddEvent({type: 'showmenu', obj: this, onevent: this.OpenMenu});
		this.AddDOMEvent({type: 'click', obj: document, onevent: function(){this.CloseAll()}.Apply(this)});
	},
	Data: function(d) {
		if(!$E(d)) return;
		this.data = this._getChildrenByHTMLTagName($E(d), 'li');
		if(this.data.length>0) this._createMenu();
		else return;
	},
	XMLData: function(xml, xpath) {
		if(!parent) return;
		this.dataType = 'xml';
		this.xpath = xpath.split('/');
		if(typeof xml=='string') var xml = $WI.Method.XML.Init(xml);
		this.data = this._getChildrenByHTMLTagName(xml.getElementsByTagName(this.xpath[0])[0], this.xpath[1]);
		if(this.data.length>0) this._createMenu();
		else return;
	},
	Write: function(where) {
		if(this.obj) {
			this._insertDOM((where&&$E(where))?$E(where):null, null, 'insertinto');
		}
	},
	OpenMenu: function(event, _target, obj) {
		this.Fire(event, 'showmenu', this.submenus[0]);
	},
	CloseAll: function(){
		for(var i=0;i<this.mainmenus.length;i++)
			this.Fire(null, 'closemenu', this.mainmenus[i]);
	},
	GetSelectedMenu: function() {
		var selected = [];
		for(var i=0;i<this.allitems.length;i++)
			if(this.allitems[i].selected)
				selected.push(this.allitems[i]);
		return selected;
	},
	AddMenu: function(options) {
		if(!options) var options = {};
		if(!this.submenus) this.submenus = [];
		var menu = this._insertDOM(this.obj, {objType: 'div', objClass: 'element-menu-submenu', config: options, top: '-1000px', left: '-1000px', display: 'none'}, 'insertinto');
		menu.shadow = this._insertDOM(menu, {objType: 'img', objClass: 'element-menu-submenu-shadow', src: '/api/src/images/shadow_light.png', width: '100%', height: '100%'}, 'insertinto');
		menu.mbody = this._insertDOM(menu, {objType: 'div', objClass: 'element-menu-submenu-body'}, 'insertinto');
		menu._construct = this;
		this._cancelSelect(null, true, menu);

		this.AddEvent({type: 'selectitem', obj: menu, onevent: this._onMouseEvent});
		this.AddEvent({type: 'unselectitem', obj: menu, onevent: this._onMouseEvent});

		this.AddEvent({type: 'showmenu', obj: menu, onevent: this._onMenuEvent});
		this.AddEvent({type: 'closemenu', obj: menu, onevent: this._onMenuEvent});

		this.AddDOMEvent({type: 'mouseover', obj: menu, onevent: this._onMouseFullEvent});
		this.AddDOMEvent({type: 'mouseout', obj: menu, onevent: this._onMouseFullEvent});

		if(options.button) {
			menu.button = $E(options.button);
			this.mainmenus.push(menu);
			this.AddEvent({type: 'click', obj: $E(options.button), onfire: {obj: menu, fire: 'showmenu'}});
			if(this.options.onMouseOver)
				this.AddEvent({type: 'mouseover', obj: $E(options.button), onfire: {obj: menu, fire: 'showmenu'}});
		}
		this.submenus.push(menu);
		return menu;
	},
	AddSubMenu: function(submenu) {
		this.submenu = submenu;
		submenu.parent = this;

		if(this.button)
			submenu.button = this.button;

		$WI.DOM.AddEvent({type: 'click', obj: this, onfire: {obj: this.submenu, fire: 'showmenu'}});
		$WI.DOM.AddEvent({type: 'closemenu', obj: this.parent, onfire: {obj: this.submenu, fire: 'closemenu'}});

		//if(this._construct.options.onMouseOver) {
			//$WI.DOM.AddEvent({type: 'mouseover', obj: this, onfire: {obj: this.submenu, fire: 'showmenu'}});
		//}

		$WI.DOM._isDisplay(this.subm, true);
	},
	AddItem: function(options) {
		if(!options.title) return this._createSeparator(options);
		var item = this._insertDOM(options.parent.mbody, {objType: 'div', objClass: 'element-submenu-item'}, 'insertinto');
		if(options.type == 'checkbox') {
			item.icon = this._insertDOM(item, {objType: 'div', objClass: 'element-submenu-checkbox'}, 'insertinto');
			this.AddDOMEvent({type: 'click', obj: item, onevent: this.SetStatus});
		} else if(options.type == 'radio') {
			item.icon = this._insertDOM(item, {objType: 'div', objClass: 'element-submenu-radio'}, 'insertinto');
			this.AddDOMEvent({type: 'click', obj: item, onevent: this.SetStatus});
		} else {
			if(options.icon)
				item.icon = this._insertDOM(item, {objType: 'img', objClass: 'element-submenu-item-icon png', src: options.icon}, 'insertinto');
			else
				item.icon = this._insertDOM(item, {objType: 'span', objClass: 'element-submenu-item-icon'}, 'insertinto');
		}

		item.txt = this._insertDOM(item, {objType: 'div', objClass: 'element-submenu-item-text', html: options.title}, 'insertinto');
		item.subm = this._insertDOM(item, {objType: 'div', objClass: 'element-submenu-item-right', display: 'none'}, 'insertinto');
		item.parent = options.parent;
		item.type = options.type;
		item.value = options.value;

		if(options.parent&&options.parent.button)
			item.button = options.parent.button;

		this.AddEvent({type: 'mouseover', obj: item, onfire: {obj: options.parent, fire: 'selectitem'}});
		this.AddEvent({type: 'mouseout', obj: item, onfire: {obj: options.parent, fire: 'unselectitem'}});

		if(options.onclick) {
			if(this._construct)
				this.AddDOMEvent({type: 'click', obj: item, onevent: function(event, _target, obj){if(item.disable)return false;this._onItemClick(event, _target, obj);options.onclick.apply(this._construct, [event, item.parent.button, item.parent]);}});
			else
				this.AddDOMEvent({type: 'click', obj: item, onevent: function(event, _target, obj){if(item.disable)return false;this._onItemClick(event, _target, obj);options.onclick(event, item.parent.button, item.parent);}});
		}

		if(options.params) item.params = options.params;
		item.AddSubMenu = this.AddSubMenu;
		item._construct = this;
		item.Disabled = this.Disabled;
		item.SetStatus = this.SetStatus;
		item.GetChecked = this.GetChecked;
		//disable the item
		if(options.disabled) item.Disabled();
		if(options.status) item.SetStatus(true);
		if(options.onchange) this.AddEvent({type: 'statuschange', obj: item, onevent: options.onchange});

		this.allitems.push(item);
		this._ajustDivs(options.parent.mbody);
		return item;
	},
	Disabled: function(status) {
		if($_VAR(status, true)) {
			this.disable = true;
			$WI.DOM._addClass(this.txt, 'element-submenu-item-text-disabled');
			if(this.type == 'checkbox')	$WI.DOM._addClass(this.icon, 'element-submenu-checkbox-disabled');
			else if(this.type == 'radio')	$WI.DOM._addClass(this.icon, 'element-submenu-radio-disabled');
		} else {
			this.disable = false;
			$WI.DOM._removeClass(this.txt, 'element-submenu-item-text-disabled');
			$WI.DOM._removeClass(this.icon, 'element-submenu-checkbox-disabled');
			$WI.DOM._removeClass(this.icon, 'element-submenu-radio-disabled');
		}
	},
	SetStatus: function(status, _target, obj) {
		//change status for checkbox
		if(typeof status == 'object') {
			if(obj.type == 'radio' && obj.checked) return false;
			if(obj.checked) obj.SetStatus(false);
			else obj.SetStatus(true);
			//fire on change event
			this.Fire(null, 'statuschange', obj);
			return true;
		}
		//check if elements belongs to any of the groups
		if(!_target && this.group && this.group.length > 0)
			for(var i=0;i<this.group.length;i++)
				if(this.group[i] != this)
					this.group[i].SetStatus(false, true);

		if($_VAR(status, true)) {
			this.checked = true;
			if(this.type == 'checkbox')	$WI.DOM._addClass(this.icon, 'element-submenu-checkbox-selected');
			else if(this.type == 'radio')	$WI.DOM._addClass(this.icon, 'element-submenu-radio-selected');
		} else {
			this.checked = false;
			$WI.DOM._removeClass(this.icon, 'element-submenu-checkbox-selected');
			$WI.DOM._removeClass(this.icon, 'element-submenu-radio-selected');
		}
	},
	SetGroup: function() {
		for(var i=0;i<arguments.length;i++)
			arguments[i].group = arguments;
	},
	GetChecked: function() {
		if(this.group && this.group.length > 0)
			for(var i=0;i<this.group.length;i++)
				if(this.group[i].group.checked)
					return this.group[i];
		return this;
	},
	_onItemClick: function(event, _target, obj){
		this._selectItem(obj);
		//fire close menu on all main menu objects
		for(var i=0;i<this.mainmenus.length;i++)
			this.Fire(null, 'closemenu', this.mainmenus[i]);
	},
	_selectItem: function(item){
		if(!this.options.staySelected) return;
		//unselect all others first
		for(var i=0;i<this.allitems.length;i++) {
			this.allitems[i].selected = false;
			this._removeClass(this.allitems[i], 'element-submenu-item-stay-selected');
		}
		this._addClass(item, 'element-submenu-item-stay-selected');
		item.selected = true;
	},
	_createSeparator: function(options){
		return this._insertDOM(options.parent.mbody, {objType: 'div', objClass: 'element-submenu-separator', html: '<font></font>'}, 'insertinto');
	},
	_ajustDivs: function(obj){
		var children = this._getChildren(obj);
		var h = 0;

		for(var i=0;i<children.length;i++) {
			h+= this._getHeight(children[i]);
		}
		//this._setStyle(obj, 'height', this._fixPx(h));
		this._setStyle(obj.parentNode, 'height', this._fixPx(h));
		this._setStyle(obj.parentNode.shadow, 'height', this._fixPx(h));
	},
	_onMenuEvent: function(event, _target, obj) {
		var fire = event;
	  if(typeof fire!='string') fire = event.fire;

  	if(fire=='showmenu'&&obj.style.display!='none')
			this.Fire(event, 'closemenu', obj);

		//show menu
		if(fire=='showmenu') {
			//close all the main menus if cursor moved to another target
			if(this.mainmenus.inArray(obj))
				this.CloseAll();
			//obj._target = _target;
			this._isDisplay(obj, true);
			this._ajustDivs(obj.mbody);


			var _target = this._getParentByClassName(_target, 'element-submenu-item', false);

			//if menu is disabled
			if(_target.disable)	return false;

			if(!this._hasClass(_target, 'element-submenu-item')) {
				var w = 0;
				var h = this._getHeight(_target);
				//run main timeout on menu close, to close menu if its not activated in a while
				this._setOpenTimeout(event);
			} else {
				var w = this._getWidth(obj)-3;
				var h = 0;
			}

			if(event.type=='contextmenu') {
				var xy = this._getMouseXY(event);
				this._applyConfig(obj, {top: this._fixPx(xy.y), left: this._fixPx(xy.x)});
			} else {
				var xy = this._getXY(_target);
				this._applyConfig(obj, {top: this._fixPx(xy.y+h), left: this._fixPx(xy.x+w)});
			}
			this.MaxZ(obj);
			this.MaxZ(obj);

			if(_target.auto_timeout)
				clearTimeout(_target.auto_timeout);
		} else {	//hide menu
			//obj._target = null;
			this._isDisplay(obj, false);
			this._applyConfig(obj, {top: '-1000px', left: '-1000px'});
			this._setMainTimeout(event, obj, false);
		}
		this._cancelEvent(event);
	},
	_onMouseEvent: function(event, _target, obj) {
		var _target = this._getParentByClassName(_target, 'element-submenu-item', false);
		if(event.type=='mouseover') {

			//if menu is disabled
			if(_target.disable)	return false;

			this._addClass(_target, 'element-submenu-item-selected');
			this._addClass(_target.subm, 'element-submenu-item-right-selected');
			//open submenu if exists after one second

			if(_target.submenu)
				if(this.options.onMouseOver)
					this.Fire(event, 'showmenu', _target.submenu);
				else
					_target.auto_timeout = setTimeout(function(){this.Fire(event, 'showmenu', _target.submenu)}.Apply(this), 1000);

			if(obj.parent&&obj.parent.parent)
				this._setSubTimeout(event, obj.parent.parent, false);

			this._setMainTimeout(event, obj, false);

		} else if(event.type=='mouseout') {


			this._removeClass(_target, 'element-submenu-item-selected');
			this._removeClass(_target.subm, 'element-submenu-item-right-selected');

			//if(_target.timeout)
				//clearTimeout(_target.timeout);

			if(_target.auto_timeout)
				clearTimeout(_target.auto_timeout);

			this._setMainTimeout(event, obj);
		}
	},
	_onMouseFullEvent: function(event, _target, obj) {
		if(event.type=='mouseover') {
			this._setMainTimeout(event, obj, false);
		} else if(event.type=='mouseout') {
			this._setMainTimeout(event, obj);
		}
	},
	_setOpenTimeout: function(event){
		this.timeout = setTimeout(function(){this.Fire(null, 'closemenu', this.submenus[0])}.Apply(this), 3000);
		this._cancelEvent(event);
	},
	_setMainTimeout: function(event, obj, status){
		if($_VAR(status, true)) {
			this.timeout = setTimeout(function(){this.Fire(null, 'closemenu', this.submenus[0])}.Apply(this), this.options.timeout);
			if(obj) this._setSubTimeout(event, obj);
		}	else if(this.timeout) {
			if(this.timeout) clearTimeout(this.timeout);
			if(obj) this._setSubTimeout(event, obj, false);
		}
		this._cancelEvent(event);
	},
	_setSubTimeout: function(event, obj, status){
		if($_VAR(status, true))
			obj.timeout = setTimeout(function(){this.Fire(null, 'closemenu', obj)}.Apply(this), this.options.timeout);
		else if(obj.timeout)
			clearTimeout(obj.timeout);

		this._cancelEvent(event);
	}
});


