/**
 * @author hooriza (ajaxUI team)
 */

(function(className) {

	SPS[className] = $Class({

		_instance : null,
		
		_o : null,

		_layers : null,
		_befChar : null,

		_hwData : null,
		_curPage : 1,
		_totalPage : 0,
		
		_ajax : null,
		_ffTimer : null,
		
		_autohideAC : null, // 자동완성 autohide
		_autohideHW : null, // HandWrite autohide
		
		_orgTitle : null, // 브라우저 제목
		
		_bLockedList : false,
		_sDefaultQuery : '',

		$init : function(sEl, oArg) {
			
			var self = this;
			
			this._instance = 'SPS.__inst.' + sEl;
			var oEl = $(sEl);

			// 각 엘리먼트 얻어내기
			var o = this._o = {
				wrap : oEl,
				
				form : $$('form', oEl)[0],
				inputbox : $$('input[type=text]', oEl)[0], // 검색어 입력폼

				handWriteBtn : $$('.hand', oEl)[0], // 필기인식 버튼
				handWrite : $$('.handwrite_layer', oEl)[0], // 필기인식 레이어
				close : $$('.txtbtn01', oEl)[0], // 필기인식 Close 버튼
				areaNoList : $$('.area_nolist', oEl)[0],
				chars : $$('.area_list', oEl)[0], // 글자 목록
				overlayer : $$('.overlayer', oEl)[0], // 오버레이어
				pinyin : $$('.pinyin', oEl)[0], // 병음표시 레이어
				zoom : $$('.zoom td', oEl)[0], // 한자 크게 보기
				paging : $$('.paging', oEl)[0], // 페이징 부분

				suggestionBtn : $$('.down', oEl)[0], // 자동완성 레이어 버튼
				suggestion : $$('.auto_complete_layer', oEl)[0], // 자동완성 레이어
				
				listPinyin : $$('.lst_pinyin', oEl)[0],
				listEnglish : $$('.lst_english', oEl)[0],
				listPrefix : $$('.lst_prefix', oEl)[0],
				listPostfix : $$('.lst_postfix', oEl)[0],
				
				areaPinyin : $$('.pinyin_area', oEl)[0],
				areaEnglish : $$('.english_area', oEl)[0],
				areaPrefix : $$('.prefix_area', oEl)[0],
				areaPostfix : $$('.postfix_area', oEl)[0],

				seperator : $$('.dot', oEl)[0],
				
				viewOthers : $$('.viewother', oEl),
				
				enableLink : $$('.enable_link', oEl)[0],
				disableLink : $$('.disable_link', oEl)[0],
				
				searchButton : $$('.inputbox a', oEl)[0]
			};
			
			// window.console.debug(o);
			
			if (o.chars) o.charsTable = $$('table', o.chars)[0];
			
			this._showHandwriteStep2(true);
			
			if (o.paging) {
				o.curPage = $$('.curpage', o.paging)[0];
				o.totalPage = $$('.totalpage', o.paging)[0];

				o.prev = $$('.prev', o.paging)[0];
				o.next = $$('.next', o.paging)[0];
			}
			
			/////
			
			this._orgTitle = document.title;
			
			this._ffTimer = new SPS.timer('interval');
			this._ajax = new SPS.Include();
			
			var self = this;
			
			if (o.handWriteBtn) {
			
				this._autohideHW = new SPS.autohide(o.handWrite, [ o.handWriteBtn ], {

					onShow : function() {
					
						self._setHandwriteData([]);
						self._showHandwritePage(1);
						
						self._showHandwriteStep2(true);
		
						try { findFlashObj('hanja_encoder_new').clearData(); } catch(e) {}
						// findFlashObj('hanja_encoder_new').clearData();
					}

				});
				
				o.handWriteBtn.onclick = function() { self._autohideHW.toggle(); return false; };
			
			}
			
			if (o.suggestionBtn) {
			
				this._autohideAC = new SPS.autohide(o.suggestion, [ o.suggestionBtn, o.inputbox ], {
				
					onHide : function() {
						// self._requestedValue = null;
					}
					
				});
	
				o.suggestionBtn.onclick = function() {
	
					var eLayer = $Element(o.suggestion);
					eLayer.addClass('message');
					
					self._requestedValue = null;
					self._autohideAC.toggle();
					
					return false; 
					
				};
				
			}

			try { this._hideOverLayer(); } catch(e) {}

			this._bindEvents();

			// 사파리2 에서의 텍스트필드 border 없애지 못하는 문제 해결
			this._setInputBoxForSafari();
			$Fn(function() {
				this._setInputBoxForSafari();
			}).owner(this).attach(window, 'load');

			if (!window['hanja_encoder_showHanja'])
				window['hanja_encoder_showHanja'] = function(sData) { self._requestHandwrite(sData) };
				
			if (!window['hanja_encoder_clearHanja'])
				window['hanja_encoder_clearHanja'] = function(sData) { self._requestHandwrite('=R 0') };
				
			this._setEnable(this._getEnable(), true);
			
			// 메인페이지인지 판달할때 HTML 에 learn 이라는 클래스명을 가진 엘리먼트가 있는지
			// 확인하므로 메인페이지 수정시에 주의할것
			var bIsMainPage = $$('.learn', o.wrap)[0] ? true : false;
			
			if (SPS.learningLang == 'zh' && bIsMainPage && this._autohideHW)
				this._autohideHW.show();

			if (
				($Element(o.inputbox).hasClass('needfocus') && self._getInputValue().length > 0) ||
				$Element(o.inputbox).hasClass('mustfocus')
			) {
				
				self._bLockedList = true;

				o.inputbox.select();
				o.inputbox.focus();
				
				self._sDefaultQuery = self._getInputValue().replace('?', '');

			}

		},
		
		_getInputValue : function() {
			return this._o.inputbox.value.replace(/\u3000/g, '');
		},
		
		_setInputBoxForSafari : function() {
		
			var o = this._o;
			
			var oSfr = SPS.borderNoneSafari(o.inputbox);
			if (oSfr) oSfr.css('margin', '6px 0 0 6px');
		
		},

		_showHandwriteStep2 : function(bFlag) {
		
			var o = this._o;
			
			if (o.chars) $Element(o.chars)[bFlag ? 'hide' : 'show']();
			if (o.areaNoList) $Element(o.areaNoList)[bFlag ? 'show' : 'hide']();
		
		},
		
		_aItemList : null,
		_eBefItem : null,
		_curIndex : null,
		
		_makeSuggestionList : function(oData, nNum) {
			
			var o = this._o;
			var self = this;
			
			var sHtml = '';
			var sPrefix = this._getInputValue().toHTML();
			
			$A(oData).forEach(function(sItem) {
				
				if (--nNum < 0) return;
				
				var rPrefix = [];
				for (var i = 0, len = sPrefix.length; i <len; i++) rPrefix[i] = sPrefix.charAt(i);
				rPrefix = new RegExp('(' + rPrefix.join('\\s*') + ')', 'i');
				
				sItem = sItem.replace(rPrefix, '<span class="tc_point02">$1</span>');
				sHtml += '<li><a href="#" onmouseover="' + self._instance + '._selectSuggestItem(this);" onclick="' + self._instance + '._inputSuggestionItem(this); return false;">' + sItem + '</a></li>\n';
				
			});

			return sHtml;
			
		},
		
		_setEnable : function(bFlag, bNoFocus) {
			
			var o = this._o;
			var aMethod = bFlag ? [ 'addClass', 'removeClass' ] : [ 'removeClass', 'addClass' ];
			
			if (!o.enableLink || !o.disableLink) return;

			$Element(o.enableLink)[aMethod[0]]('tc_sub');
			$Element(o.disableLink)[aMethod[1]]('tc_sub');
			
			SPS.setCookie('_nciku_ac_disable', !bFlag);
			$Element(o.suggestion).hide();
			
			$Element(o.suggestion)[aMethod[1]]('ac_off');
			
			if (!bNoFocus) {
				o.inputbox.focus();
				o.inputbox.select();
			}
			
			if (!bFlag) this._suggestionData = null;
			
		},
		
		_getEnable : function() {
			return (SPS.getCookie('_nciku_ac_disable') != 'true')
		},
		
		_viewPinyinOnly : function() {
			
			var o = this._o;
			var oData = this._suggestionData;

			this._setSuggestionHTML([ oData.py_list ]);
			o.inputbox.focus();
			
		},
		
		_viewEnglishOnly : function() {
			
			var o = this._o;
			var oData = this._suggestionData;
			
			this._setSuggestionHTML([ null, oData.en_list ]);
			o.inputbox.focus();
			
		},
		
		_viewAll : function(bSetOnlyOne) {
			
			var o = this._o;
			var oData = this._suggestionData;

			var aoPrList = $A(oData.pr_list);
			var aSuList = [];
			for (var i = 0, t; t = oData.su_list[i]; i++)
				if (aoPrList.indexOf(t) == -1)
					aSuList.push(t);
			
			this._setSuggestionHTML([ oData.py_list, oData.en_list, oData.pr_list, aSuList ], bSetOnlyOne);
			o.inputbox.focus();
			
		},

		_getItems : function() {
			
			var o = this._o;
			this._aItemList = $$('div ul a', o.suggestion);

			this._eBefItem = null;
			this._curIndex = null;
			
		},
		
		_setSuggestionData : function(oData) {
		
			if (SPS.debugMode) window.console.debug('AC response : ' + oData.q + ' ' + '-'.repeat(50));
			
			if (!this._getEnable()) return;
			//if (SPS.debugMode) window.console.debug(1);
			
			var self = this;
			var o = this._o;
			
			var eLayer = $Element(o.suggestion);
			eLayer.removeClass('message');
			
			var sPrefix = this._getInputValue();

			//if (SPS.debugMode) window.console.debug(2 + ' : ' + sPrefix.length);
			
			if (sPrefix.length == 0) {
				$Element(o.suggestion).hide();
				return;
			}

			this._suggestionData = oData;
			if (oData.q != sPrefix.replace(/\s/, '')) return;// 080107 park js

			this._viewAll(true);
			// this._selectSuggestItem();
			
		},

		_setSuggestionHTML : function(lists, bSetOnlyOne) {
		
			var o = this._o;
			var eLayer = $Element(o.suggestion);
			
			var oLists = {
				'pinyin' : lists[0] || [], 
				'english' : lists[1] || [], 
				'prefix' : lists[2] || [], 
				'postfix' : lists[3] || []
			};
			
			if (SPS.learningLang == 'en') oLists.pinyin = [];
			
			var oMethod = { 'true' : 'addClass', 'false' : 'removeClass' };

			var oExist = {
				'pinyin' : oLists.pinyin.length > 0,
				'english' : oLists.english.length > 0,
				'prefix' : oLists.prefix.length > 0,
				'postfix' : oLists.postfix.length > 0
			};
			
			var bExist = oExist.pinyin || oExist.english || oExist.prefix || oExist.postfix;
			var bOnlyOne = 1 == ((oExist.pinyin ? 1 : 0) + (oExist.english ? 1 : 0) + (oExist.prefix ? 1 : 0) + (oExist.postfix ? 1 : 0)); 
			
			var nNum = bOnlyOne ? 10 : 5;

			o.listPinyin.innerHTML = this._makeSuggestionList(oLists.pinyin, nNum);
			o.listEnglish.innerHTML = this._makeSuggestionList(oLists.english, nNum);
			o.listPrefix.innerHTML = this._makeSuggestionList(oLists.prefix, nNum);
			o.listPostfix.innerHTML = this._makeSuggestionList(oLists.postfix, nNum);

			$Element(o.suggestion)[oMethod[oExist.pinyin]]('pinyin');
			$Element(o.suggestion)[oMethod[oExist.english]]('english');
			$Element(o.suggestion)[oMethod[oExist.prefix]]('prefix');
			$Element(o.suggestion)[oMethod[oExist.postfix]]('postfix');
			
			$Element(o.suggestion)[oMethod[bOnlyOne]]('show_one');
			if (bSetOnlyOne) $Element(o.suggestion)[oMethod[bOnlyOne]]('only_one');

			// 검색결과가 하나라도 있으면 보여주기			
			if (bExist) {
				if (!this._bLockedList) {
					eLayer.show();
				}
			} else {
				eLayer.hide();
				eLayer.addClass('message');
			}
			
			this._getItems();		
		
		},
		
		_deEscapeSuggestItemValue : function( val ) {

		    val = val.replace("&amp;", "&"); 
		    val = val.replace("&lt;", "<"); 
		    val = val.replace("&gt;", ">"); 
		    val = val.replace("&apos;", "'"); 
		    val = val.replace("&quot;", "\""); 
		    return val;
			
		},
		_selectSuggestItem : function(nIdx, bFill) {
			
			if (!this._aItemList || !this._aItemList.length) return;

			var nLen = this._aItemList.length;
			
			if (typeof nIdx != 'number')
				nIdx = $A(this._aItemList).indexOf(nIdx);
			
			if (nIdx < 0) nIdx = nLen + nIdx;
			nIdx = nIdx % nLen;
			
			var oEl = this._aItemList[nIdx];
			
			if (this._eBefItem) this._eBefItem.removeClass('selected');
			var eEl = this._eBefItem = $Element(oEl);

			eEl.addClass('selected');
			
			this._curIndex = nIdx;
			
			if (bFill) this._o.inputbox.value = this._deEscapeSuggestItemValue (oEl.innerHTML.stripTags());
			
		},
		
		_onKeyUp : function(oEvent) {
			
			if (oEvent.keyCode == 38 || oEvent.keyCode == 40) return; // UP, DOWN
			
		},
		
		_onKeyDown : function(oEvent) {
			
			var self = this;
			
			if (oEvent.keyCode == 38 || oEvent.keyCode == 40) { // UP, DOWN
				
				var nOffset = oEvent.keyCode - 39;
				this._selectSuggestItem(this._curIndex === null ? 0 : this._curIndex + nOffset, true);
				
				this._requestedValue = this._getInputValue();
				$Event(oEvent).stop();
				
				return;

			} else if (oEvent.keyCode == 13 ) { // Enter
			
				this._requestSearch();
				$Event(oEvent).stop();		
				
				return;
				
			}
			
			setTimeout(function() { self._requestSuggestion(self._getInputValue()); }, 1);
			
		},
		
		_inputSuggestionItem : function(oEl) {
			
			this._selectSuggestItem(oEl, true);
			this._requestSearch();
			
		},

		_requestedValue : null,
		
		_requestSuggestion : function(sValue) {
		
			var self = this;
			var o = this._o;
			
			if (!this._getEnable()) return;
			if (!o.listPinyin) return;
			
			var sUniq = 'S' + parseInt(Math.random() * 100000000);
			
			if (sValue == this._requestedValue) return;
			this._requestedValue = sValue;

			// window.console.debug('req : ' + sValue);

			if (sValue.length) {
			
				var sUrl = SPS.autoCompleteURL + '/autocompl_ngd?m=s&q=' + encodeURIComponent(sValue);
				if (SPS.debugMode) window.console.debug('AC request : ' + sValue);
				this._ajax.request(sUrl, function(o) { self._setSuggestionData(o); });
				
			} else {
			
				var bHasData = this._suggestionData ? true : false;
			
				this._ajax.abort();
				this._suggestionData = null;
				
				if (bHasData) $Element(o.suggestion).hide();
			
			} 

		},
		
		_trID_hw : null,
		
		_requestHandwrite : function(sTrace) {
		
			var self = this;

			document.title = this._orgTitle;
			
			var oAjax = $Ajax('/proxy.nhn', {
				onload : function(res) {

					var aList = [];
					var aParts = res.text().split(';');
					
					if (aParts[0] != self._trID_hw) return;

					$A(aParts).forEach(function(sPart, nIdx) {
						if (nIdx && sPart.indexOf(',') > -1) aList.push(sPart.split(','));
					});

					self._showHandwriteStep2(false);

					self._setHandwriteData(aList);
					self._showHandwritePage(1);
				
				}
			});
			
			this._trID_hw = SPS.uniqid();

			oAjax.request({
				'ReqNum' : this._trID_hw,
				'InputStr' : sTrace,
				'auto' : 1,
				'charset' : 3
			});

		},

		_requestSearch : function() {
		
			var o = this._o;
			var sValue = this._getInputValue();
			
			var eInputbox = $Element(o.inputbox);
			
			if (eInputbox.hasClass('regard_null')) sValue = '';
			
			if (!eInputbox.hasClass('skip_nullcheck') && sValue.length == 0) {
				alert(SPS.text('FILL_SEARCHQUERY'));
				o.inputbox.focus();
				return;
			}
			
			var oSearchButton = o.searchButton;
			if( oSearchButton.href.match('detailpageEn.nhn') ){
				document.location.href = oSearchButton.href + "" + encodeURIComponent(sValue);
			} else {
				var searchKeyword = encodeURIComponent(sValue);
				document.location.href = oSearchButton.href + "" + searchKeyword;
			}
			
		},

		_setHandwriteData : function(aList) {
			this._hideOverLayer();
			this._hwData = aList;
		},

		_getHandwriteData : function(sKey) {

			var aRet = null;

			$A(this._hwData).forEach(function(aItem) {
				if (aItem[0] == sKey) aRet = aItem;
			});

			return aRet;

		},

		_showHandwritePage : function(nPage) {

			var o = this._o;

			if (!o.charsTable) return;

			var aCells = $$('a', o.charsTable);
			var nIdx = (nPage - 1) * 25; // 한페이지에 25개씩 보임

			var self = this;

			$A(aCells).forEach(function(oCell) {

				var bHasData = self._hwData[nIdx] && self._hwData[nIdx][0] ? true : false;

				oCell.innerHTML = bHasData ? self._hwData[nIdx][0] : '';
				$Element(oCell).css('cursor', bHasData ? 'pointer' : 'default');

				nIdx++;

			});

			var oCurPage = o.curPage;
			var oTotalPage = o.totalPage;

			var eCurPage = $Element(oCurPage);
			var eTotalPage = $Element(oTotalPage);

			var nNum = this._hwData.length;

			var nCurPage = nPage; // n페이지로 이동
			var nTotalPage = parseInt((nNum - 1) / 25) + 1; // 한페이지에 25개씩 보임
			
			if (nTotalPage < 1) nTotalPage = 1;

			this._curPage = nCurPage;
			this._totalPage = nTotalPage;

			eCurPage.text(nCurPage + '');
			eTotalPage.text(nTotalPage + '');

			eTotalPage[nCurPage == nTotalPage ? 'addClass' : 'removeClass']('tc_point01');

		},
		
		_hideOverLayer : function() {
			
			var o = this._o;
			
			this._befChar = null;
			$Element(o.overlayer).hide();
			
		},
		
		_bindEvents : function() {

			var self = this;
			var o = this._o;

			// 입력폼에 포커스가 갔을때
			$Fn(function() {
			
				if ($Agent().navigator().firefox) {
			
					self._ffTimer.start(100, function() {
						self._requestSuggestion(self._getInputValue());
					});
					
				}
			
				var inputbox = o.inputbox;
				if (!$Element(inputbox).hasClass('cleared')) {
					inputbox.value = '';
					$Element(inputbox).addClass('cleared');
					$Element(inputbox).removeClass('regard_null');
				}
				
				self._requestSuggestion(self._getInputValue());

			}).attach(o.inputbox, 'focus');
			
			$Fn(function() {
				self._bLockedList = false;
				self._requestSuggestion(self._getInputValue());
			}).attach(o.inputbox, 'click');
			
			$Fn(function() {
				self._bLockedList = false;
			}).attach(o.inputbox, 'keydown');
			
			$Fn(function() {
				self._bLockedList = false;
				self._ffTimer.stop();
			}).attach(o.inputbox, 'blur');

			$Fn(function() {
			
				if (!o.suggestion) return;

				self._bLockedList = false;
			
				var eLayer = $Element(o.suggestion);
				var bMethod = eLayer.visible() ? 'hide' : 'show';
			
				// 보여줄 데이터가 없으면
				if (bMethod == 'show' && !self._suggestionData)
					eLayer.addClass('message');
				
				eLayer[bMethod]();
				
			}).attach(o.inputbox, 'mousedown');

			if (o.close) {

				// 필기인식창의 close 버튼을 눌렀을때
				$Fn(function(oEvent) {

					if (!o.handWrite) return;

					$Element(o.handWrite).hide();
					oEvent.stop();

				}).attach(o.close, 'click');

			}

			if (o.chars) {

				// 글자 목록에 마우스를 올렸을때 병음 표시하도록
				$Fn(function(oEvent) {
					
					if (!this._hwData) return;

					// 어느 글자 위에 마우스를 올렸는지 좌표를 통해 계산해서 알아내자
					var oPos = oEvent.pos();
					var oGap = $Element(o.chars).offset();

					var oOffset = { col : oPos.pageX - oGap.left, row : oPos.pageY - oGap.top };

					// 한글자가 차지하고 있는 영역은 가로x세로 : 25x25 니까 나눠주자
					oOffset.col = parseInt(oOffset.col / 25);
					oOffset.row = parseInt(oOffset.row / 25);

					var oTable = o.charsTable;
					var oCell = null;

					// 얻어낸 행/열로 해당하는 TD 태그 찾기
					try { oCell = oTable.rows[oOffset.row].cells[oOffset.col]; } catch(e) {}

					if (!oCell) this._hideOverLayer();
					if (!oCell || oCell == this._befChar) return;
					
					var eCell = $Element(oCell);
					var eHandWrite = $Element(o.handWrite);

					// 말풍선의 글자 바꿔주기
					var sChar = eCell.text().replace(/(^\s+|\s+$)/g, '');
					if (!sChar) {
						this._hideOverLayer();
						return;
					}
					
					this._befChar = oCell;

					var sPinyins = this._getHandwriteData(sChar).join('<br />');
					sPinyins = sPinyins.replace(/^.<br\s?\/>/, '');

					$Element(o.overlayer)[oCell ? 'show' : 'hide']();

					if (sPinyins) {

						$$('.text', o.pinyin)[0].innerHTML = sPinyins;
						o.zoom.innerHTML = sChar;

						var oPos = eCell.offset();
						var oGap = eHandWrite.offset();

						$Element(o.overlayer).css({
							left : (oPos.left - oGap.left) + 'px',
							top : (oPos.top - oGap.top - o.overlayer.offsetHeight - 10) + 'px'
						});
						
					}

					$Element(o.overlayer)[sPinyins ? 'show' : 'hide']();

				}).owner(this).attach(o.chars, 'mousemove');

				// 문자 선택 영역 밖으로 마우스 이동하면 말풍선 숨기기
				$Fn(function(oEvent) {
					
					if (oEvent.of(o.chars)) return;
					this._hideOverLayer();

				}).owner(this).attach(o.chars, 'mouseout');

				// 필기인식 글자 클릭하면 입력되게
				$Fn(function(oEvent) {
				
					var o = this._o;
					var self = this;
					
					if (!$Element(o.overlayer).visible()) return;
					
					var sChar = $Element(o.zoom).text();

					o.inputbox.focus();
					
					try { findFlashObj('hanja_encoder_new').clearData(); } catch(e) {}
					self._setHandwriteData([]);
					self._showHandwritePage(1);
					
					setTimeout(function() {
						o.inputbox.value += sChar;
						self._requestSuggestion(self._getInputValue());
					}, 10);

					oEvent.stop();
					
				}).owner(this).attach(o.chars, 'click');

			}

			if (o.paging) {

				$Fn(function(oEvent) {

					if (this._curPage > 1)
						this._showHandwritePage(this._curPage - 1);

					oEvent.stop();

				}).owner(this).attach(o.prev, 'click');

				$Fn(function(oEvent) {

					if (this._curPage < this._totalPage)
						this._showHandwritePage(this._curPage + 1);

					oEvent.stop();

				}).owner(this).attach(o.next, 'click');

			}

		}
		
	});

})('cm_search01');
