// froatmenu.js
// ver 1.2.3
// @20090323
// Required common.js ver1.40 later

var VCOMN;
if (!VCOMN) {
	VCOMN = {};
}

VCOMN.FloatMenu = function() {this.initialize.apply(this, arguments)}

VCOMN.FloatMenu.prototype = {
	ZINDEX: 32767,
	TIMEOUT_MS: 0,
	MENU_ID_SUFFIX: '_menu_parent',
	AREA: {
		LIMIT: 'window'
	},
	CLASS_MENU: 'fmenu',
	NODE: {
		TOP: '',
		TOURS: 'tours',
		MULTI: ['menu', 'submenu']
	},
	isIE: !!(window.attachEvent && !window.opera),
	initialize: function (url) {
		this._opt = {};
		this._opt.area = {};
		this._opt.menuOffset = {};
		this._url = url;
		this._topOffset = this.isIE ? 1 : 0;
		var http = new JKL.ParseXML(this._url + '?t=' + new Date().getTime());
		http.async(VCOMN.bindFunc(this.onXMLLoad, this));
		http.onerror(VCOMN.bindFunc(this.onError, this));
		http.setOutputArrayElements(this.NODE.MULTI);
		http.parse();
		this.hideElemes = [];
		this.showElemes = [];
		this.swfStatus = undefined;
	},
	onXMLLoad: function (data) {
		if (!data || !data.MenuData) {
			alert('data error!');
			return;
		}
		data.MenuData.area = data.MenuData.area || {};
		data.MenuData.offset = data.MenuData.offset || {};
		this._opt.classMenu = data.MenuData.class_menu || this.CLASS_MENU;
		this._opt.area.limit = data.MenuData.area.limit || this.AREA.LIMIT;
		this._opt.area.margin = +data.MenuData.area.margin || 0;
		this._opt.menuOffset.top = +data.MenuData.offset.top || 0;
		this._opt.menuOffset.topRight = +data.MenuData.offset.top_right || 0;
		this._opt.menuOffset.left = +data.MenuData.offset.left || 0;
		this._opt.menuOffset.right = +data.MenuData.offset.right || 0;
		this._opt.timeoutMs = +data.MenuData.timeout || this.TIMEOUT_MS;
		this._opt.swfFix = eval(data.MenuData.swf_fix);
		var endSwapImage = !!VCOMN.swapImages;
		if (data.MenuData.parent) {
			this._parent = document.getElementById(data.MenuData.parent.id);
			if (!this._parent) return;
			var elemMenu = this._createRootMenu(data.MenuData.menu);
			elemMenu.style.display = 'block';
			elemMenu.className = this._opt.classMenu;
			if (data.MenuData.parent.tag) {
				this.elemRoot = document.createElement(data.MenuData.parent.tag);
				this.elemRoot.appendChild(elemMenu);
			} else {
				this.elemRoot = elemMenu;
			}
			var parentOffset = VCOMN.cumulativeOffset(this._parent);
			this.elemRoot.style.position = 'absolute';
			this.elemRoot.style.top = +data.MenuData.style.top + parentOffset[1] + 'px';
			this.elemRoot.style.left = +data.MenuData.style.left + parentOffset[0] + 'px';
			document.body.insertBefore(this.elemRoot, document.body.firstChild);
			if (endSwapImage && VCOMN.swapImage) {
				VCOMN.swapImage(this.elemRoot);
			}
		} else {
			this.menus = [];
			var rightestPos = 0;
			var leftestPos = 10000;
			for (var i = 0; i < data.MenuData.menu.length; i++) {
				var menu = data.MenuData.menu[i];
				if (!menu.parent) continue;
				var parent = document.getElementById(menu.parent.id);
				var parentOffset = VCOMN.cumulativeOffset(parent);
				if (leftestPos > parentOffset[0]) {
					leftestPos = parentOffset[0];
					this.leftestParent = parent;
				}
				if (rightestPos < parentOffset[0] + parent.offsetWidth) {
					rightestPos = parentOffset[0] + parent.offsetWidth;
					this.rightestParent = parent;
				}
				var elemMenu = this._createRootMenu(menu.submenu, menu.width);
				if (!elemMenu) {
					parent.onmouseover = VCOMN.bindFunc(this.hideAllMenu, this, false);
					continue;
				}
				var menuParent = document.createElement('div');
				menuParent.id = menu.parent.id + this.MENU_ID_SUFFIX;
				menuParent.className = this._opt.classMenu;
				menuParent.style.position = 'absolute';
				menuParent.style.zIndex = this.ZINDEX - data.MenuData.menu.length + i + 1;
				menuParent.style.display = 'none';
				menuParent._opt = {};
				if (menu.direction) {
					menuParent._opt.direction = menu.direction;
				}
				menuParent._opt.parent = parent;
				parent.onmouseover = VCOMN.bindFunc(this.showParentMenu, this, menuParent, parent);
				parent.onmouseout = VCOMN.bindFunc(this.hideAllMenu, this, true);
				this._attachMouseEvent(menuParent, elemMenu);
				menuParent.appendChild(elemMenu);
				document.body.insertBefore(menuParent, document.body.firstChild);
				this.menus.push(menuParent);
				if (endSwapImage && VCOMN.swapImage) {
					VCOMN.swapImage(menuParent);
				}
			}
		}
	},
	onError: function (data) {
		alert('error!\n' + this._url + '\n' + data);
	},
	_createRootMenu: function (menus, width) {
	  if (!menus) return;
		var _elemRoot = document.createElement('ul');
		for (var i = 0; i < menus.length; i++) {
			if (menus[i].show && menus[i].show == 'No') continue;
			var _elem = this._createSubMenu(menus[i]);
			_elemRoot.appendChild(_elem);
		}
		if (!_elemRoot.hasChildNodes()) return;
		if (width) {
			_elemRoot.style.width = width + 'px';
		}
		_elemRoot.style.display = 'none';
		return _elemRoot;
	},
	_createSubMenu: function (menu) {
		var _elemChild = document.createElement('li');
		var _elem = _elemChild;
		if (menu.url || menu.submenu) {
			_elem = document.createElement('a');
			menu.url = menu.url || '#';
			_elem.href = menu.url;
			if (menu.target) {
				_elem.target = menu.target;
			}
			if (menu.url == '#') {
				_elem.onclick = function () {return false;};
			}
			_elemChild.appendChild(_elem);
		}
		_elemChild._opt = {};
		_elemChild._opt.direction = menu.direction || '';
		if (menu.width) {
			_elemChild.style.width = menu.width + 'px';
		}
		if (menu.height) {
			_elemChild.style.height = menu.height + 'px';
		}
		_elem.innerHTML = menu.sysname;
		if (menu.submenu) {
			var _elemSub = this._createRootMenu(menu.submenu, menu.width);
			if (_elemSub) {
				_elem.className = 'haschild';
				_elemChild.appendChild(_elemSub);
				this._attachMouseEvent(_elemChild, _elemSub);
			}
		}
		return _elemChild;
	},
	_attachMouseEvent: function (targetElem, childElem) {
		targetElem.onmouseover = VCOMN.bindFunc(this.showChildMenu, this, childElem, targetElem);
		targetElem.onmouseout = VCOMN.bindFunc(this.hideMenu, this, childElem);
	},
	hideMenu: function (targetElem, e) {
		if (this.timerId) {
			clearTimeout(this.timerId);
		}
		this.timerId = setTimeout(VCOMN.bindFunc(this.hideMenuCB, this, targetElem, e), this._opt.timeoutMs);
		for (var i = 0; i < this.menus.length; i++) {
			if (this.menus[i].firstChild === targetElem) {
				this.swfEnableMouseEvent();
				break;
			}
		}
	},
	hideMenuCB: function (targetElem, e) {
		targetElem.style.display = 'none';
	},
	hideAllMenu: function (isAsync) {
		if (this.timerId) {
			clearTimeout(this.timerId);
		}
		var _menus = this.menus;
		var _func = isAsync ? VCOMN.bindFunc(this.swfEnableMouseEvent, this) : function (){};
		var _hideAllMenu = function () {
			for (var i = 0; i < _menus.length; i++) {
				_menus[i].style.display = 'none';
			}
			_func();
		}
		if (isAsync) {
			this.timerId = setTimeout(_hideAllMenu, this._opt.timeoutMs);
		} else {
			_hideAllMenu();
		}
	},
	showParentMenu: function (targetElem, parent) {
		this.hideAllMenu();
		this.swfDisableMouseEvent();
		var parentOffset = VCOMN.cumulativeOffset(parent);
		if (targetElem._opt.direction == 'Bottom') {
			targetElem.style.top =  parentOffset[1] + parent.offsetHeight + this._opt.menuOffset.top + 'px';
			targetElem.style.left = parentOffset[0] + 'px';
		} else {
			targetElem.style.top =  parentOffset[1] + this._opt.menuOffset.top + 'px';
			targetElem.style.left = parentOffset[0] - this._opt.menuOffset.right + 'px';
		}
		targetElem.style.display = 'block';
		if (targetElem.firstChild) this.showChildMenu(targetElem.firstChild, targetElem);
		for (var i = 0; i < targetElem.childNodes.length; i++) {
			if (targetElem.childNodes[i].style && targetElem.childNodes[i].style.display == 'none') {
				targetElem.childNodes[i].style.display = 'block';
			}
		}
		if (this._opt.area.limit == 'elements' && targetElem._opt.direction == 'Bottom' &&
			this.rightestParent) {
			var rightestOffset = VCOMN.cumulativeOffset(this.rightestParent);
			var limitLeft = rightestOffset[0] + this.rightestParent.offsetWidth;
			var offsetWidth = targetElem.offsetWidth;
			if (!offsetWidth) {
				for (var i = 0; i < targetElem.childNodes.length; i++) {
					if (targetElem.childNodes[i].offsetWidth) {
						offsetWidth = targetElem.childNodes[i].offsetWidth;
					}
				}
			}
			if (parentOffset[0] + offsetWidth > limitLeft) {
				targetElem.style.left = limitLeft - offsetWidth + 'px';
			}
		}
	},
	showChildMenu: function (targetElem, parentElem, e) {
		if (this.timerId) {
			clearTimeout(this.timerId);
			this.timerId = undefined;
		}
		this.swfDisableMouseEvent();
		var _prevParent = this.prevParent;
		this.prevParent = parentElem;
		if (_prevParent && _prevParent.parentNode === targetElem) {
			return;
		}
		var parent = parentElem;
		var parents = [];
		while (parent) {
			if (parent.nodeType == 1) {
				parents.push(parent);
			}
			if (parent.tagName == 'UL' || parent.className == this._opt.classMenu) {
				break;
			}
			parent = parent.parentNode;
		}
		var childs = [];
		var setChildDisplay = function (parentNode) {
			for (var i = 0; i < parentNode.childNodes.length; i++) {
				if (parentNode.childNodes[i].childNodes) {
					setChildDisplay(parentNode.childNodes[i]);
				}
				if (parentNode.childNodes[i].tagName == 'UL') {
					childs.push(parentNode.childNodes[i]);
				}
			}
		}
		setChildDisplay(parent || targetElem);
		var child;
		while (child = childs.pop()) {
			var _isParents = targetElem === child;
			if (!_isParents) {
				for (var j = 0; j < parents.length; j++) {
					if (parents[j] === child) {
						_isParents = true;
						break;
					}
				}
			}
			child.style.display = '';
			child.style.display = _isParents ? 'block' : 'none';
		}
		targetElem.style.display = 'block';
		if (parentElem.tagName == 'LI' && !parentElem.style.position) {
			parentElem.style.position = 'relative';
		}
		if (!parentElem) {
			return;
		}
		if (parentElem._opt && parentElem._opt.direction == 'Bottom') {
			if (parentElem.tagName == 'LI') {
				targetElem.style.top = parentElem.offsetTop + parentElem.offsetHeight + this._opt.menuOffset.top - this._topOffset + 'px';
			} else {
				targetElem.style.top = parentElem.offsetHeight + this._opt.menuOffset.top - this._topOffset + 'px';
			}
			targetElem.style.left = '0px';
		} else {
			if (!this._setMenuRight(targetElem, parentElem)) {
				this._setMenuLeft(targetElem, parentElem);
			}
		}
	},
	_setMenuRight: function (targetElem, parentElem) {
		var _top = this._opt.menuOffset.top;
		targetElem.style.top = _top + 'px';
		targetElem.style.left = (parentElem.clientWidth || parentElem.offsetWidth) - this._opt.menuOffset.right + 'px';
		if (this._opt.area.limit == 'elements' && this.rightestParent) {
			var rightestOffset = VCOMN.cumulativeOffset(this.rightestParent);
			var limitRight = rightestOffset[0] + this.rightestParent.offsetWidth;
		} else {
			var limitSize = VCOMN.getBrowserSize();
			var limitRight = limitSize[0];
		}
		targetElem._isLeftMenu = false;
		var cumulativeOffset = VCOMN.cumulativeOffset(targetElem);
		var space = limitRight - (cumulativeOffset[0] + (targetElem.clientWidth || targetElem.offsetWidth));
		return (space + this._opt.area.margin >= 0);
	},
	_setMenuLeft: function (targetElem, parentElem) {
		var _top = this._opt.menuOffset.topRight;
		targetElem.style.top = _top + 'px';
		targetElem.style.left = -  (targetElem.clientWidth || targetElem.offsetWidth) - this._opt.menuOffset.left + 'px';
		if (this._opt.area.limit == 'elements' && this.leftestParent) {
			var rightestOffset = VCOMN.cumulativeOffset(this.leftestParent);
			var limitLeft = rightestOffset[0];
		} else {
			var limitLeft = 0;
		}
		targetElem._isLeftMenu = true;
		var cumulativeOffset = VCOMN.cumulativeOffset(targetElem);
		var space = cumulativeOffset[0] - limitLeft;
		return (space + this._opt.area.margin >= 0);
	},
	getSwfObject: function () {
		if (!this._chkSwf) {
			this._chkSwf = true;
			this.swfObj = [];
			var tags = ['OBJECT', 'EMBED'];
			for (var i = 0; i < tags.length; i++) {
				var elems = document.getElementsByTagName(tags[i]);
				for (var j = 0; j < elems.length; j++) {
					if (typeof elems[j].swfDisableMouseEvent == 'function') {
						var is_child = false;
						for (var k = 0; k < this.swfObj.length; k++) {
							if (this.swfObj[k] == elems[j].parentNode) {
								is_child = true;
							}
						}
						if (!is_child) {
							this.swfObj.push(elems[j]);
						}
					}
				}
			}
			if (this.swfObj.length == 0) {
				this.swfObj = null;
			}
		}
		return this.swfObj;
	},
	swfDisableMouseEvent: function () {
		if (!this._opt.swfFix) return;
		var swfObj = this.getSwfObject();
		if (swfObj && this.swfStatus !== false) {
			for (var i = 0; i < swfObj.length; i++) {
				swfObj[i].swfDisableMouseEvent(true);
			}
			this.swfStatus = false;
		}
	},
	swfEnableMouseEvent: function () {
		if (!this._opt.swfFix) return;
		setTimeout(VCOMN.bindFunc(this.swfEnableMouseEventCB, this), 0);
	},
	swfEnableMouseEventCB: function () {
		if (!this.timerId) return;
		var swfObj = this.getSwfObject();
		if (swfObj && this.swfStatus !== true) {
			for (var i = 0; i < swfObj.length; i++) {
				swfObj[i].swfEnableMouseEvent();
			}
			this.swfStatus = true;
		}
	}
};
