var Board = Class.create();
Object.extend(Object.extend(Board.prototype, Window.prototype), {
	initialize : function(option) {
		this._initialize(option);
		this.buildButtons();
		this.pages = this.buildElement(this.contentHeader, null, {display : "block"});
		this.attachListeners();
		this.currentPage = 1;
		this.rowsPerPage = 20;
		this.processMap = {
			list : {
				NotSelected : this.targetView + "_Select",
				uid : this.targetView + "_SelectByUserId",
				subject : this.targetView + "_SelectBySubject",
				content : this.targetView + "_SelectByContent"
			} 
		};
		this.behavior = new Behavior(option);
		this.view.list.bind(this)();
	},
	request : function() {
		this.resizeToContent();
	},
	buildButtons : function() {
		this.buttons = this.buildElement(this.contentHeader);
		this.insertButton = this.buildElement(this.buttons,
		{elementName : "img", src: "style/img/write.png"}, {width: "30px", height: "30px", cursor: "pointer"});
		this.searchTypeSelect = this.buildElement(this.buttons,
		{elementName : "select"});
		var optEempty = this.buildElement(this.searchTypeSelect,
		{elementName : "option", value: "NotSelected"});
		optEempty.innerHTML = "Not Selected";
		var optUser = this.buildElement(this.searchTypeSelect,
		{elementName : "option", value: "uid" });
		optUser.innerHTML = "작성자";
		var optSubject = this.buildElement(this.searchTypeSelect,
		{elementName : "option", value: "subject"});
		optSubject.innerHTML = "제목";
		var optContent = this.buildElement(this.searchTypeSelect,
		{elementName : "option", value: "content"});
		optContent.innerHTML = "내용";
		this.searchKeyInputText = this.buildElement(this.buttons,
		{elementName : "input", type: "text", name : "key"});
		this.listButton = this.buildElement(this.buttons,
		{elementName : "img", src: "style/img/refresh.png"}, {width: "30px", height: "30px", cursor: "pointer"});
	},
	attachListeners : function() {
		Event.observe(this.listButton, "click", this.view.list.bindAsEventListener(this));
		Event.observe(this.insertButton, "click", this.view.insert.bindAsEventListener(this));
	},
	generateSearchParameter : function() {
		this.searchType = this.searchTypeSelect[this.searchTypeSelect.selectedIndex].getAttribute("value");
		this.searchKey = this.searchKeyInputText.getValue();
		this.searchParameter = {process : this.processMap.list[this.searchType], key : this.searchKey};
	},
	generateData : function(row) {
		this.boardData = [];
		while(row) {
			this.boardData.push(this.generateRow(row));
			row = row.nextSibling;
		}
	},
	generateRow : function(row) {
		var columns = {};
		var column = row.firstChild;
		while(column) {
			if(column.tagName && column.firstChild.nodeValue)
				columns[column.tagName] = column.firstChild.nodeValue;			
			column = column.nextSibling;
		}
		return columns;
	},
	fillBoardData : function() {
		this.content.innerHTML = "";
		var boardTable = this.buildElement(this.content, {elementName : "table"}, {width: this.content.getWidth() - 20 + "px"});
		var boardTableHeader = this.buildElement(boardTable, {elementName: "thead"});
		var boardTableBody = this.buildElement(boardTable, {elementName: "tbody"});
		var boardTableFooter = this.buildElement(boardTable, {elementName: "tfoot"});
		this.buildBoardHeader.bind(this)(boardTableHeader);
		this.boardData.each(function(rows) {
			var tr = this.buildElement(boardTableBody, {elementName : "tr"}, {cursor : "pointer"});
			tr.setAttribute("rowId", rows.id);
			var level = rows.level || "0";
			level = parseInt(level) * 3;
			for(var row in rows) {
				if(this.hiddenColumns && this.hiddenColumns.include(row)) continue;
				var td = this.buildElement(tr, {elementName : "td"});
				var subject = rows[row];
				if("subject" == row) {
					for(var i=0; i< level; ++i)
						td.innerHTML += "&nbsp;";
					if(0 != level) td.innerHTML += "[답글]";
					if(subject.length > 15) subject = subject.substring(0, 15) + "...";
				}
				td.innerHTML += subject;
			}
			Event.observe(tr, "mouseover", function(evt) {
				tr.style.background = "khaki";
			}.bind(this));
			Event.observe(tr, "mouseout", function(evt) {
				tr.style.background = "";
			}.bind(this));
			Event.observe(tr, "click", function(evt) {
				this.currentRowId = tr.getAttribute("rowId");
				this.view.content.bind(this)();
			}.bind(this));
		}.bind(this));	
	},
	buildBoardHeader : function(headerElem) {
		var tr = this.buildElement(headerElem, {elementName: "tr"});
		for(var row in this.boardData[0]) {
			if(this.hiddenColumns && this.hiddenColumns.include(row)) continue;
			var th = this.buildElement(tr, {elementName: "th"}, {backgroundColor: "gold"});
			th.innerHTML = this.view.columnMap[row];
		}
	},
	findRow : function(id) {
		return this.boardData.findAll(function(rows) {
			return rows.id == id;
		})[0];
	},
	view : {
		columnMap : {
			id : "글 ID",
			uid : "사용자 ID",
			subject : "제목",
			content : "내용",
			written : "작성 시간",
			pid : "부모 아이디",
			gseq : "그룹 순서",
			level : "띄어야 하는 양",
			readed : "읽은 횟수"
		},
		list : function() {
			this.generateSearchParameter();
			this.view.rows.bind(this)();
			this.hiddenColumns = ["content", "pid", "gseq", "level"];
			var param = $H({process : this.searchParameter.process, currentPage : this.currentPage,
			rowsPerPage : this.rowsPerPage, key: this.searchParameter.key});
			new Ajax.Request("content/jsp/controller/execute.jsp", {
				parameters: param,
				onSuccess : function(response) {
					this.generateData.bind(this)(response.responseXML.firstChild.firstChild);
					this.fillBoardData.bind(this)();
				}.bind(this)
			});
		},
		rows : function () {
			var param = $H({process : this.searchParameter.process + "_Count", key : this.searchParameter.key});
			new Ajax.Request("content/jsp/controller/execute.jsp", {method: "post",
				parameters: param,
				onSuccess : function(response) {
					this.maxRows = response.responseXML.firstChild.firstChild.firstChild.firstChild.nodeValue;
					if(!this.displayRowElem)
						this.displayRowElem = this.buildElement(this.contentFooter);
					this.displayRowElem.innerHTML = " [전체 글 수] " + this.maxRows + "개";
					this.view.pageNumbers.bind(this)();
				}.bindAsEventListener(this),
				onFailure : function(response) {
					this.setContent("요청한 link가 없거나 서버 오류가 발생했습니다.");
				}.bindAsEventListener(this)}
			);
		},
		pageNumbers : function() {
			this.paging = new Paging(this.maxRows, this.currentPage, this.rowsPerPage);
			this.pages.innerHTML = "";
			var _min = this.paging.minPage();
			var _max = this.paging.maxPage();
			this.view.buildPageNum.bind(this)({num : 1, src : "style/img/play.png" });
			this.view.buildPageNum.bind(this)({num : _min, src : "style/img/backward.png" });
			this.view.buildPageNums.bind(this)({min : _min, max : _max});
			this.view.buildPageNum.bind(this)({num : _max, src : "style/img/forward.png" });
			this.view.buildPageNum.bind(this)({num : this.paging.getTotalPage(), src : "style/img/stop.png" });
		},
		buildPageNum : function(data) {
			var pageNum = this.buildElement(this.pages, {elementName: "img", src: data.src, num: data.num},
			{width: "30px", height: "30px", cursor: "pointer"});
			Event.observe(pageNum, "click", function(evt) {
				this.currentPage = parseInt(pageNum.getAttribute("num"));
				this.view.list.bind(this)();
			}.bindAsEventListener(this));
		},
		buildPageNums : function(data) {
			$R(data.min, data.max).each(function(i) {
				var pageNum = this.buildElement(this.pages, {elementName : "input", type: "button", value: "[" + i + "]",
				num : i});
				if(i == this.currentPage) pageNum.className = "currentPage";
				Event.observe(pageNum, "click", function(evt) {
					this.currentPage = parseInt(pageNum.getAttribute("num"));
					this.view.list.bind(this)();
				}.bindAsEventListener(this));
				this.pages.appendChild(pageNum);
			}.bind(this));
		},
		insert : function() {
			this.pages.innerHTML = "";
			new Ajax.Request("content/jsp/board/blackbook1/insertForm.jsp", {
				onSuccess : function(response) {
					this.setContent(response.responseText);
					var form = this.content.getElementsByTagName("form")[0];
					form.getElementsBySelector("input, textarea, password").each(function(elem) {
						elem.style.width = this.content.getWidth() - 100 + "px";
					}.bind(this));
					var member = taskManager.find("Member");
					if(member && member.userInformation.logged) {
						var userIdInputText = this.content.getElementsBySelector("input[name='uid']")[0];
						userIdInputText.setAttribute("value", member.userInformation.id);
						userIdInputText.setAttribute("readOnly", "true");
					}
					var modifyButton = this.content.getElementsByTagName("img")[0];
					Event.observe(modifyButton, "click", this.behavior.insert.bindAsEventListener(this));
				}.bind(this),
				onFailure : function(response) {
					this.setContent("요청한 link가 없거나 서버 오류가 발생했습니다.");
				}.bind(this)
			});
		},
		reply : function() {
			this.pages.innerHTML = "";
			new Ajax.Request("content/jsp/board/blackbook1/insertForm.jsp", {
				onSuccess : function(response) {
					this.setContent(response.responseText);
					var form = this.content.getElementsByTagName("form")[0];
					form.getElementsBySelector("input, textarea, password").each(function(elem) {
						elem.style.width = this.content.getWidth() - 100 + "px";
					}.bind(this));
					var member = taskManager.find("Member");
					if(member && member.userInformation.logged) {
						var userIdInputText = this.content.getElementsBySelector("input[name='uid']")[0];
						userIdInputText.setAttribute("value", member.userInformation.id);
						userIdInputText.setAttribute("readOnly", "true");
					}
					var pidInputHidden = this.content.getElementsBySelector("input[name='pid']")[0];
					pidInputHidden.setAttribute("value", this.currentRowId);
					var modifyButton = this.content.getElementsByTagName("img")[0];
					Event.observe(modifyButton, "click", this.behavior.reply.bindAsEventListener(this));
				}.bind(this),
				onFailure : function(response) {
					this.setContent("요청한 link가 없거나 서버 오류가 발생했습니다.");
				}.bind(this)
			});
		},
		content: function() {
			var aRow = $H(this.findRow(this.currentRowId));
			new Ajax.Request("content/jsp/board/blackbook1/insertForm.jsp", {
				onSuccess : function(response) {
					this.setContent(response.responseText);
					this.behavior.updateReaded.bind(this)();
					var form = this.content.getElementsByTagName("form")[0];
					Form.deserialize(form, aRow.toQueryString());
					var pwElement = this.content.getElementsBySelector("tr.javawide_blackbook1_pw_row")[0];
					pwElement.parentNode.removeChild(pwElement);
					var contentTextArea = form.getElementsBySelector("textarea")[0];
					var contentName = contentTextArea.getAttribute("name");
					var contentParent = contentTextArea.parentNode; 
					contentParent.removeChild(contentTextArea);
					form.getElementsBySelector("input, password").each(function(elem) {
						elem.style.width = this.content.getWidth() - 100 + "px";
						elem.setAttribute("readOnly", "true");						
					}.bind(this));
					var contentDiv = this.buildElement(contentParent, {elementName : "div", className : "JavawideWindow_Content"},
					{ width: this.content.getWidth() - 100 + "px", border: "0px"});
					contentDiv.innerHTML = aRow.content;
					var modifyButton = this.content.getElementsBySelector("img.javawide_blackbook_command")[0];
					modifyButton.setAttribute("src", "style/img/modify.png");
					Event.observe(modifyButton, "click",
					this.view.checkPassword.bindAsEventListener(this, this.view.update.bind(this)));
					modifyButton.setStyle({float: "left"});
					var deleteButton = this.buildElement(form,
					{elementName: "img", src: "style/img/delete.png"}, {cursor: "pointer"});
					deleteButton.setStyle({float: "left"});
					Event.observe(deleteButton, "click", 
					this.view.checkPassword.bindAsEventListener(this, this.behavior.doDelete.bind(this)));
					var replyButton = this.buildElement(form,
					{elementName: "img", src: "style/img/add.png"}, {cursor: "pointer"});
					replyButton.setStyle({float: "left"});
					Event.observe(replyButton, "click", this.view.reply.bind(this));					
				}.bind(this),
				onFailure : function(response) {
					this.setContent("요청한 link가 없거나 서버 오류가 발생했습니다.");
				}.bind(this)
			});
		},
		update: function() {
			var aRow = $H(this.findRow(this.currentRowId));
			new Ajax.Request("content/jsp/board/blackbook1/insertForm.jsp", {
				onSuccess : function(response) {
					this.setContent(response.responseText);
					var form = this.content.getElementsByTagName("form")[0];
					form.getElementsBySelector("input, textarea, password").each(function(elem) {
						elem.style.width = this.content.getWidth() - 100 + "px";
					}.bind(this));
					Form.deserialize(this.content.getElementsByTagName("form")[0], aRow.toQueryString());
					this.content.getElementsBySelector("input[name='uid']")[0].setAttribute("readOnly", "true");
					var modifyButton = this.content.getElementsByTagName("img")[0];
					modifyButton.setAttribute("value", "수정");
					Event.observe(modifyButton, "click", this.behavior.update.bind(this));
				}.bind(this),
				onFailure : function(response) {
					this.setContent("요청한 link가 없거나 서버 오류가 발생했습니다.");
				}.bind(this)
			});
		},
		checkPassword : function(evt, after) {
			new Ajax.Request("content/jsp/checkPasswordForm.jsp", {
			onSuccess : function(response) {
				this.setContent(response.responseText);
				var form = this.content.firstChild.getElementsByTagName("form")[0];
				var pwInputText = this.content.firstChild.getElementsBySelector("input[name=pw]")[0]
				Event.observe(pwInputText, "keydown",
				this.behavior.checkPassword.bindAsEventListener(this, after));
			}.bindAsEventListener(this),
			onFailure : function(response) {
				alert("서버 장애가 있습니다. 다시 시도해 주세요.");
			}.bindAsEventListener(this)
			});
		}
	}
});

var Behavior = Class.create();
Behavior.prototype = {
	initialize : function(option) {
		Object.extend(this, option);
		//var param = {tableName : this.targetView, templateTableName: "Board_Default"};
		//new Ajax.Request("content/jsp/board/boardManager.jsp", { parameters: param });
	},
	insert : function() {
		var member = taskManager.find("Member");
		if(!member) return;
		if(member.userInformation.logged) {
			this.behavior.doInsert.bind(this)();
			return;
		}
		var param = $H({process : "hasMember"});
		new Ajax.Request("content/jsp/controller/execute.jsp", {
			parameters: Form.serialize(this.content.getElementsByTagName("form")[0]) + "&" + param.toQueryString(),
			onSuccess : function(response) {
				if("1" == response.responseXML.firstChild.firstChild.firstChild.firstChild.nodeValue) {
					alert("이 ID로는 입력할 수 없습니다. 로그인을 하거나 ID를 수정해 주기 바랍니다.");
				} else {
					this.behavior.doInsert.bind(this)();
				}
			}.bindAsEventListener(this),
			onFailure : function(response) {
				alert("입력 오류 입니다.");
			}.bindAsEventListener(this)
		});
	},
	doInsert : function() {
		var param = $H({process : this.targetView + "_Insert"});
		new Ajax.Request("content/jsp/controller/executeUpdate.jsp", {
			parameters: Form.serialize(this.content.getElementsByTagName("form")[0]) + "&" + param.toQueryString(),
			onSuccess : function(response) {
				this.currentPage = 1;
				this.view.list.bind(this)();
			}.bindAsEventListener(this),
			onFailure : function(response) {
				alert("입력 오류 입니다.");
			}.bindAsEventListener(this)
		});
	},
	doDelete : function() {
		var param = $H({process : this.targetView + "_Delete", id: this.currentRowId});
		new Ajax.Request("content/jsp/controller/executeUpdate.jsp", {
		parameters: param.toQueryString() + "&" + this.requestPWParam,
		onSuccess : function(response) {
			this.view.list.bind(this)();
		}.bindAsEventListener(this),
		onFailure : function(response) {
			alert("삭제 오류 입니다.");
		}.bindAsEventListener(this)
		});
	},
	checkPassword : function(evt, after) {
		var keyCode = evt.keyCode || evt.which;
		if(Event.KEY_RETURN != keyCode) {
			return;
		}
		Event.stop(evt);
		var param = $H({process: this.targetView + "_Check_Password", id : this.currentRowId});
		var form = this.content.getElementsByTagName("form")[0];
		this.requestPWParam = Form.serialize(form);
		new Ajax.Request("content/jsp/controller/execute.jsp", {
		parameters : this.requestPWParam + "&" + param.toQueryString(), 
		onSuccess : function(response) {
			if("1" == response.responseXML.firstChild.firstChild.firstChild.firstChild.nodeValue) {
				after();
			} else alert("틀린 암호 입니다.");
		}.bindAsEventListener(this),
		onFailure : function(response) {
			alert("서버 장애가 있습니다. 다시 시도해 주세요.");
		}.bindAsEventListener(this)
		});
	},
	update : function() {
		var param = $H({process : this.targetView + "_Update", id: this.currentRowId});
		new Ajax.Request("content/jsp/controller/executeUpdate.jsp", {
		parameters: Form.serialize(this.content.getElementsByTagName("form")[0]) + "&" + param.toQueryString() + "&prev" + this.requestPWParam,
		onSuccess : function(response) {
			this.view.list.bind(this)();
		}.bindAsEventListener(this),
		onFailure : function(response) {
			alert("수정 오류 입니다.");
		}.bindAsEventListener(this)
		});
	},
	updateReaded : function() {
		var param = $H({process : this.targetView + "_UpdateReaded", key: this.currentRowId});
		new Ajax.Request("content/jsp/controller/executeUpdate.jsp", {
		parameters: param});
	},
	reply : function() {
		var member = taskManager.find("Member");
		if(!member) return;
		if(member.userInformation.logged) {
			this.behavior.doReply.bind(this)();
			return;
		}
		var param = $H({process : "hasMember"});
		new Ajax.Request("content/jsp/controller/execute.jsp", {
			parameters: Form.serialize(this.content.getElementsByTagName("form")[0]) + "&" + param.toQueryString(),
			onSuccess : function(response) {
				if("1" == response.responseXML.firstChild.firstChild.firstChild.firstChild.nodeValue) {
					alert("이 ID로는 입력할 수 없습니다. 로그인을 하거나 ID를 수정해 주기 바랍니다.");
				} else {
					this.behavior.doReply.bind(this)();
				}
			}.bindAsEventListener(this),
			onFailure : function(response) {
				alert("서버 오류 입니다.");
			}.bindAsEventListener(this)
		});
	},
	doReply : function() {
		var param = $H({process : this.targetView + "_Reply_Insert"});
		new Ajax.Request("content/jsp/controller/executeUpdate.jsp", {
			parameters: Form.serialize(this.content.getElementsByTagName("form")[0]) + "&" + param.toQueryString(),
			onSuccess : function(response) {
				this.currentPage = 1;
				this.view.list.bind(this)();
			}.bindAsEventListener(this),
			onFailure : function(response) {
				alert("답글 오류 입니다.");
			}.bindAsEventListener(this)
		});
	},
	close : function() {
		delete this.behavior;
	}
}