if (typeof GEL == 'undefined' || !GEL) {
    GEL = {
        widget: new Object()
    };
}

GEL.widget.MenuState = function(containerIDs, menuData, renderFunc){

    var containers = {},
    	_self= this;
    this.containers = containers;
    this.getTarget = function(e){
        return e.srcElement ? e.srcElement : e.target;
    };
    
    var getTarget = this.getTarget;
    
    this.evtGetItemContainer = function(target){
        var res = evtIsContainer(target)
        if (res > 0) {
            return {
                container: target,
                level: res
            };
        }
        else {
            if (target != undefined && (target.parentNode != null || target.parentNode != undefined)) {
                return evtGetItemContainer(target.parentNode);
            }
        }
        
    };
    
    var evtGetItemContainer = this.evtGetItemContainer;
    
    this.evtIsContainer = function(target){
        var result = 0;
	if(typeof target == 'object' && target && "id" in target) {
	  /*  for(var i=0,l=containers.length;i<l;i++){*/
	  	for ( var i in containers) {
                if (containers[i].id == target.id) {
                    result = parseInt(i.replace("level", ""));
                    break;
                }
            }
        }
        
        return result;
    };
    
    var evtIsContainer = this.evtIsContainer;
    
    this.getMenuItem = function(target){
        /*for a given event handler will traverse the target till it finds the menu node
         * or return undefined
         **/
        if (evtIsContainer(target)) {
            return undefined;
        }
        
        if (target.id != undefined && target.id.indexOf("node") == 0) {
            return target;
        }
        else {
            if (target.parentNode) {
                return getMenuItem(target.parentNode);
            }
        }
    };
    var getMenuItem = this.getMenuItem;
    
    this.mouseover = function(tgt){
        var menuElem = getMenuItem(tgt);
        if (menuElem != undefined) {
            var menuID = menuElem.id.replace("node", "");
            
            var activeContainer = evtGetItemContainer(menuElem);
            try {
                transitionMenu(menuElem, menuID, activeContainer);
            } 
            catch (ex) {
                throw ex;
            }
        }
    };
    
    this.transitionMenu = function(menuNode, menuID, menuContainer){
        var subMenuItem = _data[menuID] != undefined && _data[menuID].Menu != undefined ? _data[menuID].Menu : undefined;
        var showSubMenu = subMenuItem ? true : false;
        if (showSubMenu) {
            if (menuContainer.level > 1) {
                var elemPos = getElemPos(menuNode);
                /*
		   need pos -2 because of IE or css, 
		   in order for the mouseout to work, the submenus
                   need to bump up against each other, this is especially apparent in IE
                 */
                if (menuContainer.level == 2) {/*vertical under parent item*/
                    var subMenuOrigin = {
                        x: elemPos.bottom - 2,
                        y: elemPos.left
                    };
                    
                }
                else {/*vertical right of parent item*/
                    var subMenuOrigin = {
                        x: elemPos.top,
                        y: elemPos.right - 2
                    };
                }
            }
            else {
                var subMenuOrigin = undefined;
            }
            
            setSection(containers["level" + subMenuItem[0].MenuLevel], subMenuItem, subMenuOrigin);
        }
		else if (menuContainer.level == 1) {
			var subMenuOrigin = undefined;
			setSection(containers["level2"], [], subMenuOrigin);
		}
		
        
        switch (menuContainer.level) {
            case 1:
                 hideMenus(["level3"]);
				break;
            case 2:
                var mnus = [];
                if (!showSubMenu) {
                    mnus[mnus.length] = "level3";
					hideMenus(mnus);
                }
                
                break;
            default:
                break;
        }
        
        /*set css classes*/
        var css = {
            l1: {
                on: "level1-collapse",
                off: "level1-expand"
            },
            l2: {
                on: "level2-collapse",
                off: "level2-expand"
            },
            l3: {
                on: "level3-collapse",
                off: "level3-expand"
            }
        };
        
        toggleclass(menuNode, menuContainer.container, css["l" + menuContainer.level].on, css["l" + menuContainer.level].off);
        
    };
    
    var transitionMenu = this.transitionMenu;
    
    this.getElemPos = function(elem){
        if (elem) {
            if (elem.getBoundingClientRect) {
                return elem.getBoundingClientRect();
            }
            else {
                /*must be chrome or some other nonsense*/
                return {
                    bottom: elem.offsetTop + elem.offsetHeight,
                    top: elem.offsetTop,
                    left: elem.offsetLeft,
                    right: elem.offsetLeft+elem.offsetWidth
                };
            }
            
        }
        else {
            return undefined;
        }
    };
    
    var getElemPos = this.getElemPos;
    
    var toggleclass = function(node, container, onclass, offclass){
        node.className = onclass;
	var _cNodes= container.childNodes; 
	for(var i=0,l=_cNodes.length;i<l;i++){
            var c = _cNodes[i];
	    if(node === c) continue; 
	    if(c.nodeType) 
            	c.className = offclass;
        }
        
    };
    
    this.hideMenus = function(ids){
	for(var i=0,l=ids.length;i<l;i++){ 
            containers[ids[i]].style.display = "none";
        }
    };
    var hideMenus = this.hideMenus;
    
    this.mouseout = function(domEvent){
        var e= domEvent.domevent; 
        /*determine active element under mouse, if not in nav, then collapse 3 and 4*/
        var totarget = evtGetItemContainer(e.relatedTarget ? e.relatedTarget : e.toElement);
        if (totarget == undefined) {
            /*element not in menu*/
            //hideMenus(["level3", "level4"]);
			hideMenus(["level3"]);
        }
    };
    var _cnt= 1;  
    for (var i in containerIDs) {
        var e = document.getElementById(containerIDs[i]);
	var _containerId= containerIDs[i], _gel= null; 
	var e= GEL.ement(_containerId); 
        this.containers[i] = e.getElement();
        /*Wire-up events*/
	e.on("mouseover", 
		function(type, evt){ 
        		//var tgt= evt.srcElement ? evt.srcElement : evt.target;
			var _tgt= evt.getTarget(); 
			_self.mouseOverTimer= setTimeout( 
				function(){
					_self.mouseover(_tgt);
				},
				300
			); 
	});
	e.on("mouseout", function(t, e){ 
		clearTimeout(_self.mouseOverTimer);
		_self.mouseout(e); 
	});
    }
    this._data = menuData;
    var _data = this._data;
    
    
    
    /*other methods*/
    this.setSection = function(container, menu, pos){
        if (pos) {
            container.style.position = "absolute";
            //container.style.top = pos.x + "px";
            container.style.left = pos.y + "px";
        }
        var result = document.createDocumentFragment();
	for(var i=0,l=menu.length;i<l;i++){ 
            result.appendChild(renderFunc(menu[i]));
        }
        container.innerHTML = "";
        container.appendChild(result);
        container.style.display = "";
        
    };
    var setSection = this.setSection;
   
	
    this.initSections = function(container, menu){
	var _currnav = document.getElementById("NavigationMenuLevel1Div");
	if (_currnav.innerHTML==""){
	        /*start loop with no params, will call recursivley to MenuLevel2 and then break*/
	        if (container == undefined && menu == undefined) {
	            menu = this._data[0].Menu;
	            this.initSections(this.containers["level1"], menu);
	        }
	        else {
	            this.setSection(this.containers["level" + menu[0].MenuLevel], menu);
	            if (menu[0].MenuLevel < 3) {
	                try {
	                    var nextLevel = menu[0].MenuLevel + 1;
	                    if (this._data[menu[0].MenuID] != undefined) {
	                        /*its possible that data contains menuID that is undefined*/
	                        var nextMenu = this._data[menu[0].MenuID].Menu;
	                        this.initSections(this.containers["level" + nextLevel], nextMenu);
	                    }
	                } 
	                catch (ex) {
	                    throw ex;
	                    
	                }
	            }
	        }
		}
    };
   
    /*set initial state*/
    this.initSections();
    
}

GEL.widget.MenuState.renderMainItem = function(menuItem){
    if (menuItem.MenuLevel < 3) {
        var mainSpan = document.createElement('span');
        mainSpan.setAttribute('id', 'node' + menuItem.MenuID);
        
        var menuItemHref = document.createElement('a');
        menuItemHref.setAttribute('href', menuItem.Link);
        menuItemHref.menuItem = menuItem;
        
        if (menuItem.NewWindow == "True") {
            menuItemHref.setAttribute('target', '_blank');
        }
        
        menuItemHref.innerHTML = menuItem.Name;
        mainSpan.appendChild(menuItemHref);
        return mainSpan;
    }
    else {
        var mainSpan = document.createElement('span');
        mainSpan.setAttribute('id', 'node' + menuItem.MenuID);
        var subMenuHref = document.createElement('a');
        subMenuHref.setAttribute('href', menuItem.Link);
        
        if (menuItem.NewWindow == 'True') {
            subMenuHref.setAttribute('target', '_blank');
        }
        subMenuHref.appendChild(document.createTextNode(menuItem.Name));
        mainSpan.appendChild(subMenuHref);
        
        return mainSpan;
    }
}
