﻿/*
 * CjMenu 객체
 * 
 * 메뉴 데이터를 관리하는 객체.
 *
 * Lee Won-Gyoon <richscript@gmail.com>, <@richscript>, <www.richscript.net>
 * e-motion Corp.
*******************************************************************************/

var CjMenu = {
	instanceName : "CjMenu",
	uiInstanceName : "CjMenuUI",
	userSession : {
		isLogin : false
	},
	event : new $js.lib.ObjectEvent(),
	menu : [],
	menuCodeMap : {},
	skinCodeMap : {},
	frameValue : {
		  T : "top"
		, C : "top.contentsFrame"
	},
	url : {
		  root : "/index.html"
		, home : "/main.asp"
	},
	menuCode : {
		  root : "ROOT"
		, home : "home"
		, login : "M1286562453537"
		, logout : "M1286562457497"
		, join : "M1286526802521"
		, userInfo : "M1288110047451"
		, sitemap : "M1286526812544"
	},
	msg : {
		  NO_MENU_CODE : "메뉴코드가 없거나 잘못된 메뉴코드입니다."
		, NO_SKIN_CODE : "스킨코드가 없거나 잘못된 스킨코드입니다."
		, NO_URL_FROM_MENU_CODE : "메뉴코드에 해당하는 URL이 정의되지 않았습니다."
		, BAD_TARGET : "올바른 Target이 아닙니다."
	},
	
	/**
	* CjMenu 객체가 생성되었는지 여부를 알려준다.
	* 프레임을 잘못찾거나 객체가없으면 Exception을 발생시킨다.
	* @return boolean
	*/
	isExist : function() {
		return true;
	},
	
	/**
	* CjMenuUI 객체가 생성되었는지 여부를 알려준다.
	* @return boolean
	*/
	isExistUI : function() {
		return ((window[this.uiInstanceName]!=undefined)?true:false);
	},
	
	/**
	* CjMenuUI 객체를 리턴한다.
	* @return boolean
	*/
	getUI : function() {
		return ((this.isExistUI())?window[this.uiInstanceName]:null);
	},
	
	/**
	* 코드에 맞는 프레임을 리턴한다.
	* @param _frameMode 프레임모드(T:최상위프레임, M:메인프레임, C:컨텐츠영역 iframe)
	* @return Frame객체
	*/
	getFrame : function(_frameMode) {
		return eval(this.frameValue[_frameMode]);
	},

	/**
	* 메뉴코드 값으로 메뉴 Array의 Index 정보를 리턴한다.
	* @param _menuCode 메뉴코드
	* @return String
	*/
	getMenuIndexFromMenuCode : function(_menuCode) {
		return this.menuCodeMap[_menuCode];
	},

	/**
	* 스킨코드 값으로 메뉴 Array의 Index 정보를 리턴한다.
	* @param _skinCode 스킨코드
	* @return String
	*/
	getMenuIndexFromSkinCode : function(_skinCode) {
		return this.skinCodeMap[_skinCode];
	},

	/**
	* 메뉴코드 값으로 메뉴 객체를 리턴한다.
	* @param _menuCode 메뉴코드
	* @return Object
	*/
	getMenuFromMenuCode : function(_menuCode) {
		return this.getMenuFromMenuIndex(this.getMenuIndexFromMenuCode(_menuCode));
	},

	/**
	* 스킨코드 값으로 메뉴 객체를 리턴한다.
	* @param _skinCode 스킨코드
	* @return Object
	*/
	getMenuFromSkinCode : function(_skinCode) {
		return this.getMenuFromMenuIndex(this.getMenuIndexFromSkinCode(_skinCode));
	},

	/**
	* 메뉴인덱스 값으로 메뉴 객체를 리턴한다.
	* @param _menuIndex 메뉴인덱스
	* @return Object
	*/
	getMenuFromMenuIndex : function(_menuIndex) {
		var menu = null;
		try {
			if (_menuIndex!=undefined) {
				menu = eval("this.menu["+_menuIndex.replace(/,/g,"].childMenu[")+"]");
			}
		} catch(e) {
			menu = null;
		}
		return menu;
	},

	/**
	* 홈 메뉴 객체를 리턴한다.
	* @return Object
	*/
	getHomeMenu : function() {
		return ({
			depth: -1
			, skinCode : ""
			, sectionCode : ""
			, sectionIndex : -1
			, menuCode : this.menuCode.home
			, title : ""
			, url : this.url.home
			, frame : "C"
			, parentMenuCodes : []
			, childMenu : null
		});
	},

	/**
	* frame이 C 인 메뉴의 URL을 리턴한다.
	* _option의 값이 "http://"나 "/"로 시작되면, URL을 _param으로 변환해 적용하고,
	* 그외의 값이 들어오면 menu.url에 파라미터로 추가한다.
	* @param _menu 메뉴객체
	* @param _option 예외처리할 파라미터
	* @return Void
	*/
	getMenuUrl : function(_menu, _option) {
		var url = "";
		if (_menu!=null&&typeof(_menu.url)=="string"&&_menu.url!="") {
			url = _menu.url;
			var customUrl = "";
			var isCustomContents = false;
			var option = (_option==undefined) ? "" : _option;
			if (typeof(option)=="string") {
				if (option.trim()!="") {
					if (option.toLowerCase().indexOf("http://")==0||option.indexOf("/")==0) {
						isCustomContents = true;
						customUrl = option;
					} else {
						if (_menu.frame!="J") {
							isCustomContents = true;
							customUrl = url.appendParameter(option);
						}
					}
				}
			}
			if (typeof(option)=="object"&&typeof(option.length)=="number") {
				var optionUrl = "";
				var optionParam = "";
				for (var i=0; i<option.length; i++) {
					if (option[i].indexOf("CONTENTS_URL=")==0) {
						optionUrl = option[i].replace("CONTENTS_URL=", "").trim();
					} else {
						if (optionParam!="") {
							optionParam += "&";
						}
						/*optionParam += option[i].replace(/\&/g,"%26").replace(/\?/g,"%3F");*/
						var point = option[i].indexOf("=");
						if (point>-1) {
							optionParam += option[i].substring(0,point+1);
							optionParam += escape(option[i].substring(point+1));
						} else {
							optionParam += escape(option[i]);
						}
					}
				}
				if (optionUrl=="") {
					if (_menu.frame!="J") {
						isCustomContents = true;
						customUrl = url.appendParameter(optionParam);
					}
				} else {
					isCustomContents = true;
					customUrl = optionUrl.appendParameter(optionParam);
				}
			}
			option = null;
			if (isCustomContents) {
				url = customUrl;
			}
		}
		_menu = _option = null;
		return url;
	},

	/**
	* 해당 메뉴로 이동한다.
	* _param의 값이 "http://"나 "/"로 시작되면, URL을 _param으로 변환해 적용하고,
	* 그외의 값이 들어오면 menu.url에 파라미터로 추가한다.
	* @param _menu 메뉴객체
	* @param _option 예외처리할 파라미터
	* @return Void
	*/
	openMenu : function(_menu, _option, _historyCall) {
		var menu = this.getValidMenu(_menu);
		if (menu!=null) {
			var url = menu.url;
			var frame = menu.frame;
			if (frame=="C") {
				this.event.onEvent(this, "openMenu", menu, _option, _historyCall);
				if (!this.isExistUI()) {
					url = this.getMenuUrl(_menu, _option);
					if (url!="") {
						location.href = url;
					} else {
						alert(this.msg.NO_URL_FROM_MENU_CODE);
					}
				}
			} else {
				this.openTargetFrameContents(url, frame);
			}
		} else {
			alert(this.msg.NO_URL_FROM_MENU_CODE);
		}
		menu = null;
	},

	/**
	* 타겟 프레임을 지정한 URL로 이동한다.
	* @param _url 메뉴 URL
	* @param _frame 타겟 프레임 코드
	* @return void
	*/
	openTargetFrameContents : function(_url, _frame) {
		if (_frame==undefined) _frame = "C";
		if (_url==undefined) _url = "";
		_url = _url.trim();
		try {
			if (_url!="" ) {
				if (_frame=="J") {
					location.href = "javascript:"+_url;
				} else if (_frame=="N") {
					open(_url, "_blank", "");
				}
			} else {
				alert(this.msg.NO_URL_FROM_MENU_CODE);
			}
		} catch(e) {
			location.href = _url;
		}
	},

	/**
	* 하위메뉴를 탐색하여 URL이 존재하는 메뉴가 나올면 리턴한다.
	* @param _menu 메뉴객체
	* @return Menu 메뉴객체
	*/
	getValidMenu : function(_menu) {
		if (_menu==undefined) {
			return null;
		}
		if (_menu.url!="") {
			return _menu;
		} else {
			if (_menu.childMenu!=null) {
				var _tempMenu;
				for (var i=0; i<_menu.childMenu.length; i++) {
					_tempMenu = this.getValidMenu(_menu.childMenu[i]);
					if (_tempMenu!=null) {
						return _tempMenu;
					}
				}
				_tempMenu = null;
				return null;
			} else {
				return null;
			}
		}
	},

	/**
	* 해당 메뉴로 이동한다.
	* @param _menuCode 메뉴코드
	* @param _option 예외처리할 파라미터
	* @return Void
	*/
	openMenuFromMenuCode : function(_menuCode, _option, _historyCall) {
		if (_menuCode!=this.menuCode.home) {
			var menuIndex = this.getMenuIndexFromMenuCode(_menuCode);
			if (menuIndex==undefined) {
				alert(this.msg.NO_MENU_CODE);
			} else {
				this.openMenu(this.getMenuFromMenuIndex(menuIndex), _option, _historyCall);
			}
		} else {
			this.openHome();
		}
	},

	/**
	* 해당 메뉴로 이동한다.
	* @param _skinCode 메뉴코드
	* @param _option 예외처리할 파라미터
	* @return Void
	*/
	openMenuFromSkinCode : function(_skinCode, _option) {
		var menuIndex = this.getMenuIndexFromSkinCode(_skinCode);
		if (menuIndex==undefined) {
			alert(this.msg.NO_SKIN_CODE);
		} else {
			this.openMenu(this.getMenuFromMenuIndex(menuIndex), _option);
		}
	},

	/**
	* 전체 메인페이지로 이동한다.
	* @return Void
	*/
	openHome : function(_historyCall) {
		var option;
		this.openMenu(this.getHomeMenu(), option, _historyCall);
	},

	/**
	* 사용자 정보를 셋팅한다.
	* @param _loginYN 로그인여부
	* @return Void
	*/
	updateUserSession : function(_loginYN) {
		var isLogin = (_loginYN=="Y") ? true : false;
		var isUpdated = true;
		if (this.userSession.isLogin===isLogin) {
			isUpdated = false;
		} else {
			this.userSession.isLogin = isLogin;
		}
		if (isUpdated) {
			this.event.onEvent(this, "updateUserSession", isLogin);
		}
	},

	/**
	* 사용자 정보가 변할 때마다 호출되어야하는 Function을 등록한다.
	* 등록한 Function에는 현재 상태의 로그인 여부(boolean) 파라미터가 담겨져 호출된다.
	* @param _func 처리할 Function
	* @return Void
	*/
	onUpdateUserSession : function(_func) {
		this.funcs.updateUserSession.push(_func);
	},

	/**
	* push()할때 depth정보로 상위메뉴의 메뉴코드를 가져온다.
	* @param _depth 메뉴뎁스
	* @return Array
	*/
	getParentMenuCodes : function(_depth) {
		var menuCodes = [];
		var menuDepth = (_depth==undefined) ? 0 : parseInt(_depth,10);
		if (menuDepth>1) {
			var parentMenu = this.menu;
			var lastIndex = 0;
			for (var i=1; i<menuDepth; i++) {
				lastIndex = parentMenu.length-1;
				menuCodes.push(parentMenu[lastIndex].menuCode);
				if (i<menuDepth-1) {
					parentMenu = parentMenu[lastIndex].childMenu;
				}
			}
			parentMenu = null;
		}
		return menuCodes;
	},

	/**
	* 메뉴데이터를 추가한다.
	* @param arguments[0] 메뉴뎁스
	* @param arguments[1] 메뉴코드
	* @param arguments[2] 메뉴명
	* @param arguments[3] 링크
	* @param arguments[4] 타겟프레임 ("C":컨텐츠영역 iframe, "N":새창, "J":자바스크립트)
	*/
	push : function() {
		var depth 		= arguments[0];
		var menuCode 	= arguments[1];
		var title 		= arguments[2];
		var url 		= arguments[3];
		var frame 		= arguments[4];
		
		var parentMenuCodes = this.getParentMenuCodes(depth);

		/* Menu Class */
		var menu = {
			  depth : depth
			, skinCode : ""
			, sectionCode : ""
			, sectionIndex : ""
			, menuCode : menuCode
			, title : title
			, url : url
			, frame : frame
			, parentMenuCodes : parentMenuCodes
			, childMenu : null
			, showProperty : function() {
				var s = "";
				var i = 0;
				for (prop in this ){
					if (""+typeof(this[prop])!="function") {
						if (i++>0) s += "\n";
						s += "- " + prop + " : ";
						if (prop=="childMenu") {
							try {
								s += this[prop].toString().split(",").length + "개";
							} catch(e) {
								s += "없음";
							}
						} else {
							s += this[prop];
						}
					}
				}
				return s;
			}
		};

		/* Add Menu */
		var menuIndex = "";
		var menuLastDepthIndex = "";
		var skinCode = "";
		var menuDepth = parseInt(menu.depth,10);
		if (menuDepth>1) {
			var parentMenuCode = menu.parentMenuCodes[menuDepth-2];
			var parentMenu = this.getMenuFromMenuCode(parentMenuCode);
			if (parentMenu) {
				if (parentMenu.childMenu==null) {
					parentMenu.childMenu = [];
				}
				menuLastDepthIndex = parentMenu.childMenu.length;
				menu.skinCode = parentMenu.skinCode + ((menuLastDepthIndex<10) ? "0"+menuLastDepthIndex : ""+menuLastDepthIndex);
				menu.sectionCode = menu.skinCode.substring(0,2);
				menu.sectionIndex = Math.toInt(menu.sectionCode);
				menuIndex = this.menuCodeMap[parentMenuCode] + "," + menuLastDepthIndex;
				parentMenu.childMenu.push(menu);
			}
			parentMenu = null;
		} else {
			menuLastDepthIndex = this.menu.length;
			menu.skinCode = (menuLastDepthIndex<10) ? "0"+menuLastDepthIndex : ""+menuLastDepthIndex;
			menu.sectionCode = menu.skinCode.substring(0,2);
			menu.sectionIndex = Math.toInt(menu.sectionCode);
			menuIndex = ""+menuLastDepthIndex;
			this.menu.push(menu);
		}
		
		/* menuCode Mapping. */
		this.menuCodeMap[menu.menuCode] = menuIndex;
		
		/* skinCode Mapping. */
		if (menu.skinCode!="") {
			this.skinCodeMap[menu.skinCode] = menuIndex;
		}
		
		menu = null;
		parentMenuCodes = null;
	}
};






