/**********************************************************************************
 * hone_controller.js
 * 
 * Hone 프레임워크의 컨트롤러와 관련된 부분이 포함되어 있는 스크립트 파일
 * 'Hone.controller' 라는 네임스페이스를 사용하고 있음
 * 
 * @author 조만희
 **********************************************************************************/

Hone.controller.Controller = {
	/**
	 * 서버와 통신합니다.
	 * 
	 * @param control {Object} 서버 전송을 위한 컨트롤 객체
	 */
	transaction : function (control, flag) {
	
		var block = function (id) {
			var metadata = Hone.model.PageContext.getRecordSet(id).metadata;
			var useMsg = metadata.useProcessingMessage;
			var msg = metadata.processingMessage;
			if (useMsg) {
				$(".flexigrid:has(table#" + id + ")").block({  
					overlayCSS : {
					backgroundColor : "#FFF"
				},
				message : "<h2><img src=\"" + Hone.model.PageContext.WEB_RESOURCE_ROOT + "/img/ext/plugin/grid/ajax-loader.gif\" />&nbsp;&nbsp;&nbsp;" + msg + "</h2>" 
				}); 
			}//end if
		};
		
		var unblock = function (id) {
			$(".flexigrid:has(table#" + id + ")").unblock();
		};
	
		/*
		 * 서버와 통신할 경우에는 table에 처리 중이라는 표시를 해준다.
		 * 
		 * 2009.01.14 - Helexis
		 */
		$.each(control.commands, function (index, command) {
			switch (command.type) {
				case Hone.model.CommandType.SEARCH :
					$.each(command.o, function (i, output) {
						block(output);
					});
					break;
				case Hone.model.CommandType.SAVE :
					block(command.i);

					/*
					 * 입력된 값이 있을 경우에만 SAVE 하도록 한다.
					 * 모든 컬럼에 값이 없는 경우에는 무시한다.
					 */
					var rs = Hone.model.PageContext.getRecordSet(command.i);
					var records = rs.records;
					
					for (var i = 0; i < records.length; i++) {
						var f = true;
						var rec = records[i];
						for (var j = 0; j < rec.cell.length; j++) {
							if (Hone.Utils.hasText(rec.cell[j])) {
								f = false;
								break;
							}//end if
						}//end for
						if (f) {
							records.splice(i);
							i--;
						}//end if
					}//end for
					
					break;
				default :
					try {
						block(command.i);
					} catch (e) {}//ignored
			}//switch case
		});
	
		var __urlPath = Hone.model.PageContext.CONTEXT_ROOT + control.url;
		
		var __serviceExecutionContext = new Hone.model.ServiceExecutionContext(control, flag);
		
		/*
		 * 오류 처리 핸들러를 설정함.
		 * 만약, 오류 처리 핸들러가 없다면,
		 * alert() 로 서버와의 통신에 오류가 있음을
		 * 공지하는 기본 핸들러를 설정함.
		 * 
		 * TODO 메시지 처리 추가할 것
		 * 
		 * 2008.11.26 - Helexis
		 */
		var __errorHandler = function (xhr, status, e) {
			alert("서버와의 통신 중 오류가 발생하였습니다 : " + status + (e ? "\n" + e.description : ""));
			
			$.each(control.commands, function (index, command) {
				/*
				 * 블럭되었던 UI를 다시 원상복귀 시킨다.
				 */
				switch (command.type) {
					case Hone.model.CommandType.SEARCH :
						$.each(command.o, function (i, output) {
							unblock(output);
						});
						break;
					case Hone.model.CommandType.SAVE :
						unblock(command.i);
						break;
					default :
						try {
							unblock(command.i);
						} catch (e) {}//ignored
				}//switch case
			});
			
		};
		
		var __successHandler = function (data) {
			/*
			 * 컨트롤에 메시지가 설정되어 있으면, alert 띄워준다.
			 */
			if (control.successMessage) {
				alert(control.successMessage);
			}//end if
			
			/*
			 * 커맨드 별 결과 값 처리.
			 * 
			 * 커맨드 별로 IN/OUT이 정의되어 있으므로,
			 * 각각의 커맨드에 대해 OUT이 설정되어 있으면, 
			 * OUT을 처리한다.
			 */
			$.each(data.commands, function (n, command) {
				if (command.o.length > 0) {
					
					$.each(command.o, function (n, recordSetId) {
						var newRecordSet = command.recordSets[recordSetId];
						
						var originalRecordSet = Hone.model.PageContext.getRecordSet(recordSetId);
						
						originalRecordSet.records = newRecordSet.records;
						
						var newMetadata = newRecordSet.metadata;
						var originalMetadata = originalRecordSet.metadata;
						
						originalMetadata.volumePerPage = newMetadata.volumePerPage;
						
						if (newMetadata.totalRecordCount == 0 && newRecordSet.records.length > 0) {
							originalMetadata.totalRecordCount = newRecordSet.records.length;
						} else {
							originalMetadata.totalRecordCount = newMetadata.totalRecordCount;
						}//end if
						
						originalMetadata.currentPage = newMetadata.currentPage;
						
						$("#" + recordSetId).flexAddData({
							page: originalMetadata.currentPage,
							total: originalMetadata.totalRecordCount,
							rows : originalRecordSet.records
						});
						
						Hone.view.GridView.redraw(recordSetId, originalMetadata);
						
						/*
						 * 응답 핸들러가 설정된 테이블의 경우에는
						 * 해당 응답 핸들러를 호출해 준다.
						 */
						if (originalMetadata.responseHandler) {
							originalMetadata.responseHandler.call(this, "search");
						}//end if
					});
				}//end if
				
				/*
				 * 블럭되었던 UI를 다시 원상복귀 시킨다.
				 */
				switch (command.type) {
					case Hone.model.CommandType.SEARCH :
						$.each(command.o, function (i, output) {
							unblock(output);
						});
						break;
					case Hone.model.CommandType.SAVE :
						unblock(command.i);
						
						var processResult = command.recordSets[command.i].metadata.processResult;
						var oMetadata = Hone.model.PageContext.getRecordSet(command.i).metadata;
						
						/*
						 * 응답 핸들러가 설정된 테이블의 경우에는
						 * 해당 응답 핸들러를 호출해 준다.
						 */
						if (oMetadata.responseHandler) {
							oMetadata.responseHandler.call(this, "save", processResult);
						}//end if
						
						break;
					default :
						try {
							unblock(command.i);
						} catch (e) {}//ignored
				}//switch case
				
				/*
				 * 커맨드 초기화 작업
				 */
				command.searchCondition = null;
				command.recordSets = {};
			});
			
			/*
			 * 만약, 처리 후 다른 처리를 위한 컨트롤이 설정되어 있다면,
			 * 호출한다.
			 */
			if (control.chainControl) {
				Hone.model.PageContext.getControl(control.chainControl).eventHandler.call(this);
			}//end if
		};
		
		var data = {
			"hone.web.bind.GridContext" : Hone.Utils.toJSON(__serviceExecutionContext),
			"hone.web.mvc.client.type" : "HONE_TABLE"
		};
		
		if (Hone.model.PageContext.navigation.history) {
			data["hone.web.mvc.history"] = "true";
		}//end if
		
		/*
		 * Ajax 방식으로 서버와 통신
		 */
		$.ajax({
			url : __urlPath,
			type : "POST",
			dataType : "json",
			data : data,
			error : __errorHandler,
			success : __successHandler
		});
	},
	
	/**
	 * 주어진 레코드 셋 ID에 해당하는 레코드 셋에 레코드를 추가합니다.
	 * 
	 * @param recordSetId 레코드 셋 ID
	 */
	addRecord : function (recordSetId) {
		var recordId = "row_temp_" + Hone.model.PageContext.gridTempRecordSequence++;
		
		var recordSet = Hone.model.PageContext.getRecordSet(recordSetId);
		var columns = recordSet.metadata.columns;
		var value = [];
		for (var i = 0; i < columns.length; i++) {
			// TODO 그냥 타입과 관계없이 빈 공백 문자열만 넣으면 되는지 확인하도록
			value.push("");
		}//end for
		
		var record = recordSet.addRecord(recordId, value);
		
		Hone.view.GridView.addRecord(recordSetId, record);
	},
	
	/**
	 * 주어진 레코드 셋 ID에 해당하는 레코드 셋으로부터 레코드를 삭제합니다.
	 * 
	 * @param recordSetId 레코드 셋 ID
	 */
	deleteRecord : function (recordSetId) {
		Hone.view.GridView.deleteRecord(recordSetId);
	},
	
	/**
	 * 주어진 레코드 셋에 해당하는 컬럼을 정렬합니다.
	 * 
	 * @param recordSet {Hone.model.RecordSet} 레코드 셋
	 * @param colId {String} 정렬 대상 컬럼
	 * @param order {String} 정렬 순서
	 */
	changeSort : function (recordSet, colId, order) {
		var metadata = recordSet.metadata;
		var searchControlId = metadata.searchControlId;
		
		if (!Hone.Utils.hasText(searchControlId)) {
			alert("<hone:table> 태그의 searchControlId 속성 값이 지정되지 않아 정렬 기능을 사용할 수 없습니다.");
			return;
		}//end if
		
		if (!Hone.model.PageContext.getControl(searchControlId)) {
			alert("<hone:table> 태그의 searchControlId 속성 값이 잘못 지정되어 정렬 기능을 사용할 수 없습니다.");
			return;
		}//end if
		
		metadata.currentPage = 1;
		metadata.sortColumnId = colId;
		metadata.sortOrder = "asc" == order ? true : false;
		Hone.model.PageContext.getControl(searchControlId).eventHandler.call(this, null, true);
		Hone.model.PageContext.navigation.history = true;
	}
	
};

Hone.controller.Page = {};

Hone.controller.Page.gotoPage = function (searchId, pageNum) {
	var target = $("form#" + searchId);
	var type = target.attr("hone:type");
	if (type == "search") {
		/*
		 * 현재 페이지 설정
		 */
		var pageForm;
		var temp = $("input[name=hone.condition.currentPage]", target);
		if (temp.size() > 0) {
			pageForm = temp;
		} else {
			pageForm = $("<input type=\"hidden\" name=\"hone.condition.currentPage\" />");
			target.append(pageForm);
		}//end if else
		pageForm.val(pageNum);
		
		/*
		 * 정렬 조건 설정
		 */
		var orderForm;
		temp = $("input[name=hone.dao.order.key]", target);
		if (temp.size() > 0) {
			orderForm = temp;
		} else {
			orderForm = $("<input type=\"hidden\" name=\"hone.dao.order.key\" />");
			target.append(orderForm);
		}//end if else
		if (Hone.Utils.hasText(Hone.model.PageContext.navigation.orderParam)) {
			orderForm.val(Hone.model.PageContext.navigation.orderParam);
		}//end if
		
		/*
		 * 조회 조건 설정
		 */
		var conditionForm;
		temp = $("input[name=hone.web.bind.condition]", target);
		if (temp.size() > 0) {
			conditionForm = temp;
		} else {
			conditionForm = $("<input type=\"hidden\" name=\"hone.web.bind.condition\" />");
			target.append(conditionForm);
		}//end if else
		if (Hone.Utils.hasText(Hone.model.PageContext.navigation.search)) {
			conditionForm.val(Hone.model.PageContext.navigation.search);
		}//end if
		
		Hone.model.PageContext.popSearchForm = false;
		target.submit();
	}//end if
};

Hone.controller.Sort = {
	ASC : "ascending",
	DESC : "descending"
};

Hone.controller.Sort.sort = function (searchId, sortId, sortOrder) {
	var target = $("form#" + searchId);
	var type = target.attr("hone:type");
	if (type == "search") {
		var order = {
			id : sortId,
			direction : sortOrder
		};
		var orders = [];
		orders.push(order);
		var orderForm;
		var temp = $("input[name=hone.dao.order.key]", target);
		if (temp.size() > 0) {
			orderForm = temp;
		} else {
			orderForm = $("<input type=\"hidden\" name=\"hone.dao.order.key\" />");
			target.append(orderForm);
		}//end if else
		orderForm.val(Hone.Utils.toJSON(orders));
		
		/*
		 * 조회 조건 설정
		 */
		var conditionForm;
		temp = $("input[name=hone.web.bind.condition]", target);
		if (temp.size() > 0) {
			conditionForm = temp;
		} else {
			conditionForm = $("<input type=\"hidden\" name=\"hone.web.bind.condition\" />");
			target.append(conditionForm);
		}//end if else
		if (Hone.Utils.hasText(Hone.model.PageContext.navigation.search)) {
			conditionForm.val(Hone.model.PageContext.navigation.search);
		}//end if
		
		Hone.model.PageContext.popSearchForm = false;
		target.submit();
	}//end if
};

