/*********************************************************
*		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'});
		
		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 png', 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');	
		item.icon = this._insertDOM(item, {objType: 'img', objClass: 'element-submenu-item-icon png', src: options.icon, visibility: (options.icon)?'visible':'hidden'}, 'insertinto');
		item.icon.onerror = function(){this.src='/api/src/images/spacer.gif'};
		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;
		
		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){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){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;
		
		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');
		} else {
			this.disable = false;
			$WI.DOM._removeClass(this.txt, 'element-submenu-item-text-disabled');
		}
	},
	_onItemClick: function(event, _target, obj){		
		if(obj.disable) return false;
		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);
	}		
});
