/**
 * Copyright 2007 SK Communications. All rights reserved
 * @since 2006.11.24
 * @author okjungsoo
 * 
 * 선행파일 : BrowserInfo.js, DOMCreator.js
 * 
 * ListBox : 두개의 column을 가지며, prevButton 또는 nextButton을 
 * 누를 때마다 server에 목록을 요청하여 이를 갱신합니다. 
 * 
 * 생성되는 html
 * <div id="participant_list"> <-- parentNode
 * <!-- list start -->
 * 		<div id="updatepost">
 * 			<ul id="list_post_title" class="list_post_title">
 * 				<li>
 * 					<!-- createLiElement로 생성되는 html --> 
 * 				</li>
 * 			</ul>
 * 		</div>
 * <!-- list end -->
 * <!-- nav start -->
 * 		<div id="num">
 * 			<div class="view">
 * 				<span id="prevButton" class="prev">이전</span>
 * 				<span id="nextButton" class="next">
 * 					<a href="#">다음</a>
 * 				</span>
 * 			</div>
 * 		</div>
 * <!-- nav end -->
 * </div>
 */
var ListBox = Class.create();

ListBox.prototype = {
	NUM_OF_PARTICIPANT : 30,
	LISTBOX_STR_PREV_BUTTON : "이전",
	LISTBOX_STR_NEXT_BUTTON : "다음",

	/**
	 * @param parentDiv ListBox를 붙이기 위한 paretnNode를 인자로 받습니다. 
	 * 			parent는 인자로 넘오올 시에 document에 append되어 있어야 합니다. 
	 * @param optoins ListBox에 설정할 수 있는 optoin값들을 hash형태로 받습니다. 
	 * 			wholeList - 새로운 list를 받아오기 위한 url 또는 전체 list가 담겨있는 array를 받습니다. 
	 * 			listLength - list의 전체길이를 인자로 받습니다. 
	 * 			numOfList - 한번에 보여줄 list 길이를 인자로 받습니다. 
	 * 			startIndex  - ListBox의 시작값을 인자로 받습니다. 
	 * 			createLiElement - list element를 생성하기 위한 function을 인자로 받습니다. 
	 * 			updateLiElement - list element의 요소를 update하기 위한 function을 인자로 받습니다. 
	 * 			ulClassName - ListBox의 list들이 보여주는 부분 ul element의 class를 설정합니다. 
	 * 			navDivClassName - ListBox의 navigation 부분의 div에 class를 설정합니다. 
	 */	
	initialize: function(parentDiv, options){
		this.options = Object.extend({
			wholeList: [],
			listLength: 5, 
			numOfList: 5,
			startIndex: 0,
			createLiElement: null,
			updateLiElement: null, 
			ulClassName: 'list_post_title',
			navDivClassName: 'view'
		}, arguments[1] || {});

		this.listDivElm  = this._getListDivElm(parentDiv, this.options.numOfList);
		this.navDivElm = this._getNavDivElm(parentDiv);

		this.sendRequest(this.options.wholeList, this.options.startIndex);
	}, 
	
	sendRequest: function(wholeList, startIndex){
		if(wholeList instanceof Array){
			var numOfList = this.options.numOfList;
			var list = this.options.wholeList.findAll(function(value, index){
				if(index >= startIndex && index < startIndex + numOfList){
					return true;
				}
				return false;
			});
			this._updateListBox(list);
		}else{
			var params = "startIndex=" +  startIndex + "&listLength=" + this.options.listLength + "&numOfList=" + this.options.numOfList;
			
			new Ajax.Request(wholeList, {
				asynchronus:false, 
				method:"post", 
				parameters: params,
				onSuccess: this._parseList.bindAsEventListener(this)}
			);
		}
	},
	
	/**
	 * response를 파싱해서 array객체로 만들고 이렇게 새로온 데이터를 바탕으로 
	 * list element를 update합니다. 
	 */
	_parseList: function(response){
		var res = decodeURIComponent(response.responseText);
		try{
			var list = eval(res);			
		}catch(e){
//			if(debug) debug("[ListBox parseList: " + e + "]")
		}
		this._updateListBox(list);
	},
	
	_updateListBox: function(list){
		var ulElm = $('list_post_title');

		for(var index=0; index < this.options.numOfList; index++){
			var liElm = ulElm.childNodes[index];
			
			if(index >= list.legnth){
				this.options.updateLiElement(liElm, null);
			}else{
				var listItem = list[index];
				this.options.updateLiElement(liElm, listItem);
			}
		}

		this.enablePrevButton();
		this.enableNextButton();		
	},

	enablePrevButton: function(){
		var isEnable = (this.options.startIndex - this.options.numOfList) >= 0;
		this._enableButton("prevButton", isEnable, this.LISTBOX_STR_PREV_BUTTON, this._getPrevList);		
	},	
	
	enableNextButton: function(){
		var isEnable = (this.options.startIndex + this.options.numOfList) < this.options.listLength;		
		this._enableButton("nextButton", isEnable, this.LISTBOX_STR_NEXT_BUTTON, this._getNextList);
	},
	
	_enableButton: function(buttonName, isEnable, buttonText, _getList){
		var button = $(buttonName)

		if(isEnable){
			var anchorElm = document.createElement("a");
			anchorElm.href = "#";
			anchorElm.appendChild(document.createTextNode(buttonText));
			button.replaceChild(anchorElm, button.childNodes[0]);
			button.onclick = _getList.bindAsEventListener(this);
		}else if(!isEnable){
			button.replaceChild(
				document.createTextNode(buttonText), button.childNodes[0]);
			button.onclick = "";
		}
	},	
	
	/**
	 * PrevButton의 click event handler
	 */
	_getPrevList: function(event){
		this.verifyRangeAndUpdate(this.options.startIndex - this.options.numOfList);
	},
	
	/**
	 * NextButton의 click event handler
	 */
	_getNextList: function(event){
		this.verifyRangeAndUpdate(this.options.startIndex + this.options.numOfList);
	},
	
	verifyRangeAndUpdate: function(newIndex){
		if(newIndex >= 0 && newIndex < this.options.listLength){
			this.options.startIndex = newIndex;
			this.sendRequest(this.options.wholeList, this.options.startIndex);			
		}
	},

	/**
	 * 다음의 코드를 생성합니다. 
	 * <div id="num">
	 * 		<div class="view">
	 * 			<span class="prev" id="prevButton">
	 * 				<a href="#">이전</a>
	 * 			</span>
	 * 			|
	 * 			<span class="next" id="nextButton">
	 * 				<a href="#">다음</a>
	 * 			</span>
	 * 		</div>
	 * </div>
	 */
	_getNavDivElm: function(parnetNode){
		return DOMCreator.graft(parnetNode, 
			["div", {id:"num"}, 
				["div", {className: this.options.navDivClassName}, 
					["span", {id:"prevButton", className:"prev"}, 
						["a", {href:"#"}, this.LISTBOX_STR_PREV_BUTTON]
					], 
					"|", 
					["span", {id:"nextButton", className:"next"}, 
						["a", {href:"#"}, this.LISTBOX_STR_NEXT_BUTTON]
					]
				]
			]);
	},
	
	/**
	 * 다음의 코드를 생성합니다. 
	 * <div id="updatepost">
	 * 		<ul class="list_post_title">
	 * 			<li>인자로 받은 createLiElement를 실행시켜서 li를 생성합니다. </li>
	 * 		</ul>
	 * </div>
	 */
	_getListDivElm: function(parentNode, numOfList){
		var divElm = DOMCreator.graft(parentNode, 
			["div", {id:"updatepost"}, 
				["ul", {id:"list_post_title", className:this.options.ulClassName}]
			]);
		var ulElm = divElm.childNodes[0];
		
		for(var i=0; i< numOfList; i++){
			ulElm.appendChild(this.options.createLiElement(ulElm));
		}
		return divElm;	
	}
}