/**
 *
 * by danny, 1stOmni
 *
 * MENU ITEM PROPERTIES:
 *
 * menuVisible:bool
 *              - current state of the menu
 * menuVisibleSchedule:bool
 *							- next visibility (highlight) state (usually there is some delayed function)
 * menuSwitchTimeout:timeout
 *							- scheduled item.fceSwitch
 * menuInitialized:bool
 *							- was the menu initialized?
 * fceUnhighlight:function
 *							- unhighlight the menu 
 * fceSwitch:function
 *							- switch the menu according to current menuVisibleSchedule property
 * submenu:HTMLListElement
 *							- The UL element with the submenu
 *							
 */

// You can define these function for various menu effects...
// There is already dynamicmenu-slide.js example
// 
//function menuAnimationShowBefore(item) {}
//function menuAnimationShowAfter(item) {}
//function menuAnimationHideBefore(item) {}}
//function menuAnimationHideAfter(item) {}}

/*------------------------------------------------------------------------*/

function autoSwitchSubMenu(item, event) {
    // initMenuItem(item);    
    // var currClass=(item.submenu.getAttribute('class') || item.submenu.className);
    // return switchSubMenu(item, currClass.match(/mouseOut/) ? true : false, event);
    //debug('autoSwitchSubMenu('+item.id+', '+event+')');    
    //debug(event);
    if (typeof item.menuVisible == 'undefined') {
		item.menuVisible=item.className.match('mouseOver');
    }
    return switchSubMenu(item, !item.menuVisible, event);
}

function switchSubMenu(item, show, event) {
    //debug('switchSubMenu('+item.id+', '+show+', '+event+')');
    //debug(event);
    if (item.menuVisibleSchedule == show) return; // Already scheduled (bubbling optimization)
    item.menuVisibleSchedule=show;

    initMenuItem(item);
    if (item.menuVisibleSchedule !== show) return; // something changed while initializing
    
    if (item.menuVisible == show) { // Already done
	item.menuVisibleSchedule=undefined;
	return; 
    }

    // Is it dynamicly loadable submenu?
    if (!downloadMenu(item, show, event)) { // Not downloadable or already downloaded
	switchSubMenu2(item, show, event);
    }
}

function switchSubMenu2(item, show, event) {
    //debug('switchSubMenu2('+item.id+', '+show+', '+event+')');    
    if (item.menuVisibleSchedule !== show) return true; // something changed while initializing
    //debug('switchSubMenu2...');        
		
    if (item.parentNode.menuOpened.length) { // Is other opened?
	var otherMenu;
	while(otherMenu=item.parentNode.menuOpened.pop()) {
	    if (otherMenu == item) continue;
	    //debug('This: '+item.id+', closing '+otherMenu.id);
	    switchSubMenu(otherMenu, false, event);
	}
    }

    // Delay the actual submenu showing/hidding because of the MOUSEOVER/MOUSEOUT problem when leaving DOM elements...
    item.menuSwitchTimeout=setTimeout(item.fceSwitch, show ? 50 : 100);		
}

function downloadMenu(item, show, event) {
    if (!item) return;
    if (!item.submenu) item.submenu=findMenu(item);
    if (!item.submenu || !item.submenu.id || !item.submenu.id.match(/^menu_.{32}$/)) return false; // Not downloadable

    //debug('Downloading menu: '+item.id+', show: '+show+', event: '+event);
    
    cmsMenuServerGet(item.submenu.id, function(newSubmenuTxt) {
	    var parent=item.submenu.parentNode;
	    parent.removeChild(item.submenu);
	    parent.innerHTML+=newSubmenuTxt;
	    item.menuInitialized=false;
	    initMenuItem(item);
	    if (show) {
		switchSubMenu2(item, true, event);
	    }
	});
    return true;
}    


function initMenuItem(item) {
    if (!item) return; // MSIE problem with auto-initializing all siblings?

    if (item.menuSwitchTimeout) {
	clearTimeout(item.menuSwitchTimeout); // If there is alrady something schedule cancel it
	item.menuSwitchTimeout=0;
    }

    // One time initialization
    if (item.menuInitialized) return;
    item.menuInitialized=true;

    if (typeof item.parentNode.menuOpened == "undefined") {
	item.parentNode.menuOpened=[];
    }
    
    item.fceSwitch=function() {
	if (!item.submenu || item.menuVisibleSchedule == item.menuVisible) return; // already visible/hidden
	item.menuVisible=item.menuVisibleSchedule;

	item.menuVisibleSchedule=undefined;

	if (item.menuVisible) {
	    switchMenuClassName(item.submenu, 'mouseOut', 'mouseOver');		
	    item.parentNode.menuOpened.push(item);
	    typeof menuAnimationShowBefore == 'function' && menuAnimationShowBefore(item.submenu); // Plugin - override this method with your own	    
	    switchMenuClassName(item, 'mouseOutChild', 'mouseOverChild');
	    typeof menuAnimationShowAfter == 'function' && menuAnimationShowAfter(item.submenu); // Plugin - override this method with your own
	} else {
	    typeof menuAnimationHideBefore == 'function' && menuAnimationHideBefore(item.submenu); // Plugin - override this method with your own
	    switchMenuClassName(item, 'mouseOverChild', 'mouseOutChild');
	    switchMenuClassName(item.submenu, 'mouseOver', 'mouseOut');
	    typeof menuAnimationHideAfter == 'function' && menuAnimationHideAfter(item.submenu); // Plugin - override this method with your own	    
	}
    }

    item.submenu=findMenu(item);

    // To improve user experience auto-initialize all siblings on the background
    for(var i=item.parentNode.childNodes.length - 1; i >= 0; i--) {
    	var nextItem=item.parentNode.childNodes[i];
    	if (nextItem.nodeType == 1 && nextItem != item) {
    	    //initMenuItem(nextItem);
    	    setTimeout(downloadMenu, i*100 + 500, nextItem, false, false);
    	}
    }
}

function findMenu(item) {
    var localName, submenu;
    for(var i=item.childNodes.length - 1; i >= 0; i--) {
	if (item.childNodes[i].nodeType != 1) continue;
	localName=(item.childNodes[i].localName && item.childNodes[i].localName.toLowerCase()) || (item.childNodes[i].tagName && item.childNodes[i].tagName.toLowerCase());
				
	if (localName.match(/ul|table|iframe/)) { // Gotcha!
	    return item.childNodes[i];
	}
    }
    return false;
}

function switchMenuClassName(node, oldValue, newValue) {
    //window.console.log([node, oldValue, newValue]);				
    if (!node) return; // MSIE
    if (!node['styleCache'+newValue]) { // Calculate the new className using RegExp and store it for later use...
	var oldClass=(node.getAttribute('class') || node.className);
	node['styleCache'+newValue]=oldClass.replace(new RegExp(oldValue+"|"+newValue, 'g'), ''); // Remove all - we use RegExp because there can be unknown class names added in XSL...
	node['styleCache'+newValue]+=' '+newValue;
    }
    node.setAttribute('class', node['styleCache'+newValue]);
    node.className=node['styleCache'+newValue]; // MSIE
}

/* DYNAMIC LOADABLE MENU */
function cmsMenuServerGet(id, callbackFce) {
    var req;
    if (window.XMLHttpRequest){
	req=new XMLHttpRequest();
    } else if (window.ActiveXObject){
	req=new ActiveXObject("Microsoft.XMLHTTP");
    } else {
	alert('Sorry your browser does not support dynamic menu!');
	return;
    }
    
    req.open('GET', '/modules/cms/menu/'+id+'.xml', true);
    req.onreadystatechange=function() {if (req.readyState == 4 && req.status == 200) callbackFce(req.responseText);}
    req.send("");
}

    // function debug(msg) {
    // 	if (typeof window.console != 'undefined' && typeof window.console.debug == 'function') window.console.debug(msg);
    // }
