AE.namespace('AE.widget.xSelector');
(function () {
	var YL = YAHOO.lang,
		YUD = YAHOO.util.Dom,
		YUE = YAHOO.util.Event,
		get = YUD.get;

	AE.widget.xSelector = function () {
		var _self = this,
			isActive = false;
		_self.orgSelect = null;
		_self.options = null;
		_self.selectedIndex = -1;
		_self.browseIndex = 0;
		_self.addNodeStatus = 0;
		_self.DATA = {
			selectBox: null,
			inputEl: null,
			arrowEl: null,
			optionBox: null,
			optionOl: null,
			optionLis: [],
			mask: null
		};
		_self.onChange = new YAHOO.util.CustomEvent('onChange', _self);
		var defConfig = {
			selectId: '',
			fakeSelectId: '',
			selectBoxWH: [200, 18],
			selectBoxZIndex: 0,
			visibleOptions: 20,
			optionBoxTop: '',
			arrowBoxLeft: '',
			isStick: 0
		};
		_self.init = function (userConfig) {
			defConfig = YL.merge(defConfig, userConfig);
			var cfg = defConfig,
				D = _self.DATA;
			_self.orgSelect = get(cfg.selectId);
			D.selectBox = get(cfg.fakeSelectId);
			D.inputEl = YUD.getElementsByClassName('inputEl', 'input', D.selectBox)[0];
			D.arrowEl = YUD.getElementsByClassName('arrowNormal', 'div', D.selectBox)[0];
			if (!_self.orgSelect) {
				return;
			}
			_self.options = _self.orgSelect.options;
			_self.selectedIndex = _self.orgSelect.selectedIndex;
			D.inputEl.value = (_self.orgSelect[_self.selectedIndex]).text;
			bindListeners();
			formatSelector();
			_self.orgSelect.fakeSelect = _self;
		};
		_self.dropdown = function () {
			var D = _self.DATA;
			if (YUD.getStyle(D.optionBox, 'visibility') == 'hidden') {
				YUD.setStyle([D.optionBox, D.mask], 'visibility', 'visible');
			}
		};
		_self.rollup = function () {
			var D = _self.DATA;
			if (YUD.getStyle(D.optionBox, 'visibility') == 'visible') {
				YUD.setStyle([D.optionBox, D.mask], 'visibility', 'hidden');
			}
			if (defConfig.isStick && YUD.get('allCate')) {
				YUD.setStyle(YUD.get('allCate'), 'visibility', 'hidden');
			}
		};
		_self.select = function (inx) {
			var D = _self.DATA,
				option = D.optionLis[inx];
			if (option.innerHTML != '' && inx != _self.selectedIndex) {
				D.inputEl.value = option.childNodes[0].nodeValue;
				_self.orgSelect.options[inx].selected = true;
				_self.selectedIndex = inx;
				_self.onChange.fire(_self.orgSelect);
			}
		};
		var buildOptionList = function () {
				var cfg = defConfig,
					D = _self.DATA;
				D.optionBox = createEl('div', {
					'class': 'optionBox'
				});
				var listItems = '<ol class="optionOl">';
				for (var i = 0; i < _self.options.length; i++) {
					var option = _self.options[i];
					if (option.text.match(/^-{3,}$/ig) != null) {
						listItems += '<li id="simulateOption' + i + '" class="optionLi subLine"></li>';
					} else {
						listItems += '<li id="simulateOption' + i + '" class="optionLi ' + option.className + '">' + option.text + '</li>';
					}
				}
				listItems += '</ol>';
				D.optionBox.innerHTML = listItems;
				D.selectBox.appendChild(D.optionBox);
				D.optionOl = D.optionBox.firstChild;
				D.optionLis = D.optionOl.getElementsByTagName('li');
			};
		var formatSelector = function () {
				var cfg = defConfig,
					D = _self.DATA;
				var selectBoxW = cfg.selectBoxWH[0] + 'px';
				var selectBoxH = cfg.selectBoxWH[1] + 'px';
				YUD.setStyle(D.selectBox, 'z-index', cfg.selectBoxZIndex);
				if (parseInt(YAHOO.env.ua.ie) == 8) {
					YUD.setStyle(D.selectBox, 'display', 'inline-block');
				}
				YUD.setStyle(D.inputEl, 'width', selectBoxW);
				YUD.setStyle(D.inputEl, 'height', selectBoxH);
				YUD.setStyle(D.inputEl, 'line-height', selectBoxH);
				YUD.setStyle(D.arrowEl, 'left', cfg.arrowBoxLeft);
				YUD.setStyle(D.arrowEl, 'z-index', cfg.selectBoxZIndex + 2);
			};
		var formatOptionList = function () {
				var cfg = defConfig,
					D = _self.DATA;
				if (cfg.optionBoxTop && cfg.optionBoxTop != '') {
					YUD.setStyle(D.optionBox, 'top', cfg.optionBoxTop);
				}
				YUD.setStyle(D.optionBox, 'z-index', cfg.selectBoxZIndex + 1);
				YUD.setStyle(D.optionBox, 'visibility', 'hidden');
				if (YAHOO.env.ua.ie === 6) {
					YUD.setStyle(D.optionBox, 'width', '10px');
				}
				if (D.optionOl.offsetWidth < D.inputEl.offsetWidth) {
					YUD.setStyle(D.optionBox, 'width', D.inputEl.offsetWidth + 'px');
				} else {
					YUD.setStyle(D.optionBox, 'width', D.optionOl.offsetWidth + 'px');
				}
				if (D.optionLis.length > cfg.visibleOptions) {
					YUD.setStyle(D.optionBox, 'height', (D.optionLis[0].offsetHeight * cfg.visibleOptions) + 'px');
				}
				YUD.setStyle(D.optionOl, 'overflow', 'hidden');
			};
		var bindListeners = function () {
				var D = _self.DATA,
					cfg = defConfig;
				YUE.on(D.selectBox, 'click', function (e) {
					YUE.stopEvent(e);
					D.inputEl.focus();
					if (!isActive) {
						buildOptionList();
						formatOptionList();
						bindListenersOnActive();
						iframeMask();
						isActive = true;
					}
					if (YUD.getStyle(D.optionBox, 'visibility') == 'hidden') {
						D.optionBox.scrollTop = _self.selectedIndex * D.optionLis[0].offsetHeight;
						transOptionStyle(_self.selectedIndex);
						_self.dropdown();
						if (defConfig.isStick) {
							stickAllCate();
						}
					} else {
						_self.rollup();
					}
				});
				YUE.on(D.selectBox, 'mouseover', function (e) {
					YUD.addClass(D.arrowEl, 'arrowMouseover');
				});
				YUE.on(D.selectBox, 'mouseout', function (e) {
					YUD.removeClass(D.arrowEl, 'arrowMouseover');
				});
			};
		var bindListenersOnActive = function () {
				var D = _self.DATA,
					cfg = defConfig;
				YUE.on(document, 'click', _self.rollup);
				YUE.on(D.inputEl, 'keydown', function (e) {
					YUE.stopEvent(e);
					if (e.altKey && (e.keyCode == 38 || e.keyCode == 40)) {
						if (YUD.getStyle(D.optionBox, 'visibility') == 'hidden') {
							transOptionStyle(_self.selectedIndex);
							_self.dropdown();
						} else {
							_self.rollup();
						}
					}
					if (!e.altKey) {
						var inx = 0,
							optionHeight = D.optionLis[0].offsetHeight,
							scrollNum = Math.floor(D.optionBox.scrollTop / optionHeight);
						if (e.keyCode == 38) {
							inx = (_self.browseIndex < 1) ? 0 : _self.browseIndex - 1;
							if (_self.browseIndex == scrollNum) {
								D.optionBox.scrollTop = (scrollNum - 1) * optionHeight;
							}
							transOptionStyle(inx);
							_self.select(inx);
						} else if (e.keyCode == 40) {
							inx = (_self.browseIndex + 1 >= D.optionLis.length) ? (D.optionLis.length - 1) : (_self.browseIndex + 1);
							if (_self.browseIndex == scrollNum + cfg.visibleOptions - 1) {
								D.optionBox.scrollTop = (scrollNum + 1) * optionHeight;
							}
							transOptionStyle(inx);
							_self.select(inx);
						} else if (e.keyCode == 13) {
							_self.rollup();
							_self.select(_self.browseIndex);
						}
					}
				});
				for (var i = 0; i < D.optionLis.length; i++) {
					var optionLi = D.optionLis[i];
					YUE.on(optionLi, 'click', function (e) {
						YUE.stopEvent(e);
						_self.select(getIndex(this));
						_self.rollup();
					});
					YUE.on(optionLi, 'mouseover', function (e) {
						YUE.stopEvent(e);
						transOptionStyle(getIndex(this));
					});
				}
			};
		var iframeMask = function () {
				var cfg = defConfig,
					D = _self.DATA;
				D.mask = createEl('iframe', {
					'frameBorder': '0',
					'width': D.optionBox.offsetWidth,
					'height': D.optionBox.offsetHeight
				});
				YUD.setStyle(D.mask, 'position', 'absolute');
				YUD.setStyle(D.mask, 'left', YUD.getStyle(D.optionBox, 'left'));
				YUD.setStyle(D.mask, 'top', YUD.getStyle(D.optionBox, 'top'));
				YUD.setStyle(D.mask, 'visibility', 'hidden');
				YUD.setStyle(D.mask, 'z-index', cfg.selectBoxZIndex);
				D.selectBox.appendChild(D.mask);
			};
		var getIndex = function (option) {
				return parseInt(option.id.replace('simulateOption', ''));
			};
		var transOptionStyle = function (inx) {
				var D = _self.DATA;
				if (D.optionLis[inx].innerHTML != '') {
					YUD.removeClass(YUD.getElementsByClassName('currentLi', 'li', D.optionOl), 'currentLi');
					YUD.addClass(D.optionLis[inx], 'currentLi');
					if (defConfig.isStick && YUD.get('allCate')) {
						YUD.removeClass(YUD.get('allCate'), 'currentLi');
					}
				}
				_self.browseIndex = inx;
			};
		var createEl = function (tag, properties) {
				var el = document.createElement(tag);
				for (var p in properties) {
					if (p == 'class') {
						YUD.addClass(el, properties[p]);
					} else {
						el.setAttribute(p, properties[p]);
					}
				}
				return el;
			};
		var stickAllCate = function () {
				var D = _self.DATA,
					oLiLast = D.optionBox.getElementsByTagName('li')[D.optionBox.getElementsByTagName('li').length - 1];
				if (!_self.addNodeStatus) {
					var eAllCate = document.createElement('div'),
						eAllCateBg = document.createElement('div');
					tAllCate = document.createTextNode('\u00A0 In All Categories'), liHeight = 34, startTop = D.optionBox.offsetTop + D.optionBox.offsetHeight - liHeight, cateWidth = D.optionBox.clientWidth;
					eAllCateBg.className = 'stickSubLine';
					eAllCate.setAttribute('id', 'allCate');
					eAllCate.className = 'stickAllCate';
					eAllCate.style.cssText = 'top:' + startTop + 'px;width:' + cateWidth + 'px;';
					eAllCate.appendChild(eAllCateBg);
					eAllCate.appendChild(tAllCate);
					D.selectBox.appendChild(eAllCate);
					_self.addNodeStatus = 1;
				} else {
					eAllCate = YUD.get('allCate');
					YUD.setStyle(eAllCate, 'visibility', 'visible');
				}
				YUE.on(eAllCate, 'click', function (e) {
					YUE.stopEvent(e);
					_self.select(getIndex(oLiLast));
					_self.rollup();
				});
				YUE.on(eAllCate, 'mouseover', function (e) {
					YUE.stopEvent(e);
					var inx = getIndex(oLiLast);
					var D = _self.DATA;
					YUD.removeClass(YUD.getElementsByClassName('currentLi', 'li', D.optionOl), 'currentLi');
					YUD.addClass(eAllCate, 'currentLi');
					_self.browseIndex = inx;
				});
			};
	};
}());
