/**
 * @(#) dui_slidemenu.js version 1.0
 *
 *  Copyright(저작권) Do Not Erase This Comment!!! (이 주석문을 지우지 말것)
 *
 *  Do Not re-distribute with-out permission. especially out-side of LG-CNS.
 *  허가 없이 재배포 해서는 안된다. 특히 LG-CNS의 외부로 유출을 하여서는 안된다.
 *
 * AUTHORS LIST       E-MAIL  
 * jaehyun lim    jhylim@lgcns.com
 */
dui.SlideMenu = {};

dui.SlideMenu = function () {};
dui.SlideMenu.makeSlideMenu = function (elId, isFrame) {
	var el = $(elId);
	Object.extend(el, dui.SlideMenu.prototype);
	if(isFrame) el.isFrame = isFrame; 
	el.init();
	return el;
};
dui.SlideMenu.prototype = {
	menus : null,
	currentObj : null,
	clickedObj : null,
	currentMenu : null,
	acceleration : -0.8,
	isEffectRunning : false,
	setOpenMenu : null,
	animation : true,
	isFrame : false,
	
	beforeOpen : function(menuObj) {},
	afterOpen : function(menuObj) {},
	beforeClose : function(menuObj) {},
	afterClose : function(menuObj) {},

	init : function() {
		this.menus = this.childElements();
		this.setMenu(this.menus);
		this.initMenu();
	},
	
	setMenu : function(menus) { 
		for (var i=0; i<menus.length; i++) {
			var UL = menus[i].getElementsByTagName("ul")[0];
			menus[i].UL = $(UL);
			if (UL) {
				this.setMenu(UL.childElements());
				for(var j=0;j<UL.childElements().length;j++) {
					if(this.getChildUL(UL.childElements()[j])) {
						UL.childElements()[j].depth = "3";
					}
				}				
				menus[i].state = "closed";
			}
			else 
				menus[i].state = "none";
			
			var eventSrc = menus[i].getElementsByClassName("span")[0];
			if (!eventSrc) eventSrc = menus[i];
			eventSrc.onclick = this.toggle.bind(this);
		}
	},	
	
	initMenu : function() { 
		var linkObjs = this.getElementsByTagName("a");  
	    var currentMenu = this.currentMenu;	
		for(var i=0;i<linkObjs.length;i++) { 	
		    var obj = linkObjs[i].parentNode.parentNode;
		    if(obj.className.indexOf("Lcurrent") > -1) {
			     var selectMenu = obj;
				 if(selectMenu.parentNode.parentNode.parentNode.parentNode.tagName=="LI") { 
				     selectMenu.parentNode.parentNode.parentNode.parentNode.UL.height = selectMenu.parentNode.parentNode.parentNode.parentNode.UL.getHeight();
					 selectMenu.parentNode.parentNode.parentNode.parentNode.state="open";
					 selectMenu.parentNode.parentNode.UL.height = selectMenu.parentNode.parentNode.UL.getHeight();
					 selectMenu.parentNode.parentNode.state="open"; 
				 } else if(selectMenu.parentNode.parentNode.tagName=="LI") {
				 	 selectMenu.parentNode.parentNode.UL.height = selectMenu.parentNode.parentNode.UL.getHeight();
					 selectMenu.parentNode.parentNode.state="open";
				 } else if(selectMenu.tagName=="LI" && selectMenu.UL) {				 	 
					 selectMenu.UL.height = selectMenu.UL.getHeight();	 
					 selectMenu.state="open";
				 }
				 this.currentObj = selectMenu; 
				 this.currentMenu=selectMenu;
			}	
			if(this.isFrame) linkObjs[i].onclick = this.toggle.bind(this);	 			
		} 
	},	
	
	selectNode : function(selectMenus) { 
		var openMenusIndexes = selectMenus.split(">");  
		 
		if (openMenusIndexes.length == 1 && this.childElements().length > openMenusIndexes[0]) {
			this.childElements()[openMenusIndexes[0]].className += " Lcurrent"; 
		}else if (openMenusIndexes.length == 2 && this.childElements().length > openMenusIndexes[0] && this.childElements()[openMenusIndexes[0]].UL && this.childElements()[openMenusIndexes[0]].UL.childElements().length> openMenusIndexes[1]) {
			this.childElements()[openMenusIndexes[0]].UL.childElements()[openMenusIndexes[1]].className += " Lcurrent";
		}else if (openMenusIndexes.length == 3 && this.childElements().length > openMenusIndexes[0] && this.childElements()[openMenusIndexes[0]].UL && this.childElements()[openMenusIndexes[0]].UL.childElements().length > openMenusIndexes[1] && this.childElements()[openMenusIndexes[0]].UL.childElements()[openMenusIndexes[1]].UL && this.childElements()[openMenusIndexes[0]].UL.childElements()[openMenusIndexes[1]].UL.childElements().length > openMenusIndexes[2]) {
			this.childElements()[openMenusIndexes[0]].UL.childElements()[openMenusIndexes[1]].UL.childElements()[openMenusIndexes[2]].className += " Lcurrent";
		}else {
			alert("[DevOn UI SlideMenu] The menu('" + selectMenus + "') you selected does not exist!!");
			return; 
		}
		this.initMenu();
	},	
	 
	toggle : function(obj) { 	
	    if (obj) obj.stopPropagation();
		else window.event.cancelBubble = true;	
		
	    var targetObj = obj ? obj.target : window.event.srcElement;	
	    if ( this.isFrame && targetObj.tagName == "A") { 
			var menu = targetObj.parentNode.parentNode;
			
			if (menu.className && menu.className.indexOf("Lcurrent") > -1) {}
			else if (this.currentMenu) { 
			    var classStr="";
				menu.className += " Lcurrent ";				
					
				this.currentMenu.removeClassName("Lcurrent");
			}
			else menu.className += " Lcurrent ";
			
			this.currentMenu = menu;
			
			this.clickedObj = targetObj.parentNode.parentNode;
		} else {   	
			
			this.clickedObj = targetObj.parentNode;
		    var menu = targetObj.parentNode;
		}
		if (!menu.UL) { 
			this.closeOpenMenu();
			this.currentObj = menu;
			return;
		}
				
		if (menu.state == "closed") { 
			var callback = function() { 
				this.open(menu);
				menu.state = "open"; 
				this.currentObj = menu; 
			} 
			this.closeOpenMenu(callback.bind(this));			
		}
		else { 			
			this.close(menu);
			menu.state = "closed";
		}
	},
	
	closeOpenMenu : function (callback) { 	
        if(this.currentObj) { 
			if(this.currentObj.parentNode == this.clickedObj.parentNode) { 
				if (this.currentObj.state == "open") {
					this.currentObj.state = "closed";
					this.close(this.currentObj, callback);
				} else if(callback) callback();
			} else if(this.currentObj.parentNode.parentNode.parentNode.parentNode.parentNode == this.clickedObj.parentNode) {				
				this.currentObj.parentNode.parentNode.parentNode.parentNode.state = "closed";
				this.close(this.currentObj.parentNode.parentNode.parentNode.parentNode, callback);
			} else if(this.currentObj.parentNode.parentNode.parentNode == this.clickedObj.parentNode) {
				this.currentObj.parentNode.parentNode.state = "closed";  
				this.close(this.currentObj.parentNode.parentNode, callback);
			} else {  
			    var closeObj = this.closeAnother(this.clickedObj);
                if(closeObj) {
					closeObj.state = "closed";
					this.close(closeObj);
				}							
				if (callback) callback();				
			}
		} else {
			if(callback) callback();
		}		
	},
	
	open : function (menu, height) { 
		var UL = menu.UL;		
		var twoDepthObjs = "";
		var elHeight = 0;
		var slideMenu = this;
		if(this.clickedObj.depth != "3") { 
		    if (this.getChildUL(this.clickedObj)) {
				twoDepthObjs = this.getChildUL(this.clickedObj).childElements();
				for (var i = 0; i < twoDepthObjs.length; i++) {
					if (twoDepthObjs[i].depth == "3" && twoDepthObjs[i].state == "open") {
						if (isNaN(parseInt(this.getChildUL(twoDepthObjs[i]).style.height))) {
							elHeight = elHeight + this.getChildUL(twoDepthObjs[i]).height;
						}
						else {
							elHeight = elHeight + parseInt(this.getChildUL(twoDepthObjs[i]).style.height);
						}
					}
				}
			}
		}		
	
		if(!height) height=0;
		
		if (!UL.height) { 
			var dimensions = UL.getDimensions();
			UL.height = dimensions.height;
		}  
		if (this.animation) {
			var effect = new dui.effect.Scale(0, UL.height + height + elHeight);
			effect.acceleration = this.acceleration;
			effect.nodisplay = true;
			if (!height) 
				effect.initHeight = 0;
			else 
				effect.initHeight = 0;
			
			effect.callback = function(){
				slideMenu.isEffectRunning = false;
				slideMenu.afterOpen(menu);
			}
			this.isEffectRunning = true;
			this.beforeOpen(menu);
			this.toggleClassName(menu, "Lopen", "Lclose");
			effect.run(UL);
		} else { 
		    menu.state = "open"			;
			UL.style.display = "block";
			slideMenu.beforeOpen(menu);
			this.toggleClassName(menu, "Lopen", "Lclose");
		}
				
       if(menu.depth=="3") { 
           this.open(menu.parentNode.parentNode, UL.height); 
		   menu.parentNode.parentNode.state = "open";	
	   }
	},
	
	close : function (menu, callback, height) { 
		var UL = menu.UL;		
		var slideMenu = this;
		
		if(!UL) {
			if (callback) callback();
			return;
		} 		
		var objHeight = height ? height : UL.getHeight();			
		
		
        if (this.animation) { 
			if(menu.depth=="3") {	
               this.close(menu.parentNode.parentNode,callback,objHeight); 
	        }
			var effect = new dui.effect.Scale(0, 0 - objHeight);
			effect.acceleration = this.acceleration;
			effect.nodisplay = true;
			effect.callback = function(){
				slideMenu.isEffectRunning = false;
				if (menu.state == "closed") {
					slideMenu.toggleClassName(menu, "Lclose", "Lopen");
					slideMenu.afterClose(menu);
				}
				if (callback) 
					callback();
			}
			this.isEffectRunning = true;
			this.beforeClose(menu);
			effect.run(UL);
		} else { 
			menu.state = "closed"; 
			if(callback) callback();
			UL.style.display = "none";	
			this.toggleClassName(menu, "Lclose", "Lopen");
			slideMenu.afterClose(menu);		
		}
	},
	
	setCallback : function(effect, callback) {
	}, 	
		
	getChildUL : function(obj) { 
		var isChildUL = false;
		var childElements = obj.childElements(); 
		if (childElements[childElements.length-1].tagName == "UL") return childElements[childElements.length-1];
		else return null;
	},
	
	closeAnother : function(obj) {
        var closeObj = '';
		var els = obj.parentNode.childElements();
		
		for(var i=0;i<els.length;i++) { 
			if(els[i].state=="open") closeObj=els[i];
		}
				
		return closeObj;
	}, 
	
	toggleClassName : function(obj, addClass, removeClass) {
		if(obj.className.indexOf(addClass) > -1) {}
		else if(obj.className.indexOf(removeClass) > -1) { 
			obj.removeClassName(removeClass);
			obj.addClassName(addClass);
		} else obj.addClassName(addClass);
	}
}