package first.sample.controller;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.annotation.JsonCreator.Mode;

import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import first.common.common.CommandMap;
import first.sample.service.SampleService;

@Controller
// [수정 시작] 클래스 선언부의 특수 공백 제거
public class SampleController
// [수정 끝] 클래스 선언부의 특수 공백 제거
{
	Logger log = Logger.getLogger(this.getClass()); //로그 찍고
	
	@Resource(name="sampleService")
	private SampleService sampleService; //샘플서비스 선언하고
	
	
	
	@RequestMapping(value="/sample/openBoardSearch.do")
	public ModelAndView openBoardSearch(CommandMap commandMap) throws Exception
	{
		ModelAndView mv = new ModelAndView("/sample/boardSearch");
		return mv;
	}
	
	
	@RequestMapping(value="/sample/openBoardList.do") //경로 맵핑해주고~
	public ModelAndView openBoardList(CommandMap commandMap, HttpSession session) throws Exception
	{

		ModelAndView mv = null;

			// [수정 시작] ModelAndView 선언부의 특수 공백 제거
			 mv = new ModelAndView("/sample/boardList"); //모델뷰 객체 선언뒤 jsp파일 지정
			// [수정 끝] ModelAndView 선언부의 특수 공백 제거
			
			Map<String, Object> resultMap = sampleService.selectBoardList(commandMap.getMap());
			//List<Map<String, Object>> list = sampleService.selectBoardList(commandMap);
			//앞에서 샘플서비스 선언한것 뒤에 selectBoardList라는 메서드 만들고 
			//mv.addObject("list", list); //앞에서 실행 다하고 list에 담긴건 list라고 선언하고
			
			mv.addObject("paginationInfo", (PaginationInfo)resultMap.get("paginationInfo"));
			mv.addObject("list", resultMap.get("result"));
			
			// 검색 파라미터(searchType, searchKeyword)를 JSP로 다시 전달
			// JSP에서 이전 검색 조건을 콤보박스와 입력창에 복원하는 데 사용됩니다.
			mv.addObject("searchType", commandMap.get("searchType"));
			mv.addObject("searchKeyword", commandMap.get("searchKeyword"));
			
			System.out.println("========JRebel Test============");
			log.debug("======JRebel Test2======");

		return mv;
		
		
	}
	
	@RequestMapping(value="/sample/testMapArgumentResolver.do")
	public ModelAndView testMapArgumentResolver(CommandMap commandMap, HttpSession session) throws Exception
	{
		ModelAndView mv = new ModelAndView("");
		
		if(commandMap.isEmpty() == false)
		{
			Iterator<Entry<String,Object>> iterator = commandMap.getMap().entrySet().iterator();
			Entry<String,Object> entry = null;
			while(iterator.hasNext())
			{
				entry = iterator.next();
				log.debug("key :"+entry.getKey()+", value :"+entry.getValue());
			}
		}
		
		return mv;
	}
	
	
	@RequestMapping(value="/sample/openBoardWrite.do")
	public ModelAndView openBoardWrite(CommandMap commandMap, HttpSession session) throws Exception
	{
		
		// [수정 시작] ModelAndView 선언부의 특수 공백 제거 및 주석 정리
		ModelAndView mv = new ModelAndView("/sample/boardWrite"); // JSP 파일 지정
		System.out.println("========JRebel Test============");
		return mv;
		// [수정 끝] ModelAndView 선언부의 특수 공백 제거 및 주석 정리
	}
	
	@RequestMapping(value="/sample/Test.do")
	public ModelAndView Test(CommandMap commandMap) throws Exception
	{
		
		// [수정 시작] ModelAndView 선언부의 특수 공백 제거 및 주석 정리
		ModelAndView mv = new ModelAndView("/sample/Test"); // JSP 파일 지정
		System.out.println("========Test Test============");
		return mv;
		// [수정 끝] ModelAndView 선언부의 특수 공백 제거 및 주석 정리
	}
	
	@RequestMapping(value="/sample/kk.do")
	public ModelAndView kk(CommandMap commandMap) throws Exception
	{
		
		// [수정 시작] ModelAndView 선언부의 특수 공백 제거 및 주석 정리
		ModelAndView mv = new ModelAndView("/sample/kk"); // JSP 파일 지정
		System.out.println("========kk Test============");
		return mv;
		// [수정 끝] ModelAndView 선언부의 특수 공백 제거 및 주석 정리
	}
	
	
	
	
	@RequestMapping(value="/sample/insertBoard.do")
	public ModelAndView insertBoard(CommandMap commandMap, HttpServletRequest request, HttpSession session) throws Exception
	{
		ModelAndView mv = new ModelAndView("redirect:/sample/openBoardList.do");
		
		sampleService.insertBoard(commandMap.getMap(), request);
		
		return mv;
	}
	
	@RequestMapping(value="/sample/openBoardDetail.do")
	public ModelAndView openBoardDetail(CommandMap commandMap, HttpSession session) throws Exception
	{
		ModelAndView mv = new ModelAndView("/sample/boardDetail");		// 가로 안이 화면 이름. 
		
		Map<String,Object> map = sampleService.selectBoardDetail(commandMap.getMap());		// map 안에 오른쪽 내용 담는다. a = b 형태. 
		
		mv.addObject("map", map.get("map"));
		mv.addObject("list", map.get("list")); //요건 첨부파일 목록 부를때 쓸거임
		
		mv.addObject("prevNextBoard", map.get("prevNextBoard"));
		
		return mv;			// 그러면 지금 mv에는 map이랑 list가 들어가 있는 거. 키로 보낸 거. 
	}
	
	@RequestMapping(value="/sample/openBoardUpdate.do") // 수정디테일화면
	public ModelAndView openBoardUpdate(CommandMap commandMap, HttpSession session) throws Exception
	{
		ModelAndView mv = new ModelAndView("/sample/boardUpdate");
		
		Map<String, Object> map = sampleService.boardUpdate(commandMap.getMap());
		
		// [수정 시작] mv.addObject 선언부의 특수 공백 제거 및 주석 정리
		mv.addObject("map", map.get("map")); // 내용
		mv.addObject("list", map.get("list")); // 첨부파일
		// [수정 끝] mv.addObject 선언부의 특수 공백 제거 및 주석 정리
		
		return mv;
	}
	
	@RequestMapping(value="/sample/updateBoard.do") // 수정하기 누르는~~ 혹은 저장하기 누르는~~
	public ModelAndView updateBoard(CommandMap commandMap, HttpServletRequest request, HttpSession session) throws Exception
	{
		ModelAndView mv = new ModelAndView("redirect:/sample/openBoardDetail.do");
		
		sampleService.updateBoard(commandMap.getMap(), request);
		
		mv.addObject("IDX", commandMap.get("IDX"));
		return mv;
	}
	
	@RequestMapping(value="/sample/deleteBoard.do")
	public ModelAndView deleteBoard(CommandMap commandMap, HttpSession session) throws Exception
	{
		ModelAndView mv = new ModelAndView("redirect:/sample/openBoardList.do");
		
		sampleService.deleteBoard(commandMap.getMap());
		
		return mv;
	}

	
}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<http://www.w3.org/TR/html4/loose.dtd>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판 목록</title>
<%@ taglib prefix="c" uri="<http://java.sun.com/jsp/jstl/core>" %>
<%@ taglib prefix="fn" uri="<http://java.sun.com/jsp/jstl/functions>" %>
<%@ taglib prefix="ui" uri="<http://egovframework.gov/ctl/ui>" %>
<%@ include file ="/WEB-INF/include/include-header.jspf" %>

<!-- [수정 시작] 기본 CSS 스타일 추가 -->
<style>
	body { font-family: Arial, sans-serif; padding: 20px; }
	h2 { color: #333; border-bottom: 2px solid #ccc; padding-bottom: 10px; margin-bottom: 20px; }
	
	.search_area { 
		margin-bottom: 20px; 
		padding: 15px; 
		border: 1px solid #ddd; 
		background-color: #f9f9f9;
		display: flex; /* 검색 요소를 가로로 배치 */
		gap: 10px; /* 요소들 간의 간격 */
		align-items: center;
	}
	
	.search_area select, .search_area input[type="text"] {
		padding: 8px;
		border: 1px solid #ccc;
		border-radius: 4px;
	}
	
	.btn_search {
		padding: 8px 15px;
		background-color: #5cb85c;
		color: white;
		border: none;
		border-radius: 4px;
		cursor: pointer;
	}
	.btn_search:hover {
		background-color: #4cae4c;
	}

	.board_list { 
		width: 100%; 
		border-collapse: collapse; 
		margin-bottom: 15px;
	}
	.board_list th, .board_list td { 
		border: 1px solid #ddd; 
		padding: 12px; 
		text-align: center; 
	}
	.board_list th { 
		background-color: #f2f2f2; 
		color: #333; 
		font-weight: bold; 
	}
	.board_list td.title { 
		text-align: left; 
	}
	.board_list a { 
		text-decoration: none; 
		color: #337ab7; 
	}
	.board_list a:hover { 
		text-decoration: underline; 
	}

	.btn {
		display: inline-block;
		padding: 10px 20px;
		background-color: #007bff;
		color: white;
		text-decoration: none;
		border-radius: 4px;
		transition: background-color 0.3s;
	}
	.btn:hover {
		background-color: #0056b3;
	}
</style>
<!-- [수정 끝] 기본 CSS 스타일 추가 -->

</head>
<body>
	<h2>게시판 목록</h2>
	
	<!-- [수정 시작] 검색 UI (HTML) 추가 -->
	<div class="search_area">
		<select id="searchType" name="searchType">
			<option value="TITLE" <c:if test="${searchType eq 'TITLE'}">selected</c:if>>제목</option>
			<option value="CONTENTS" <c:if test="${searchType eq 'CONTENTS'}">selected</c:if>>내용</option>
			<option value="ID" <c:if test="${searchType eq 'ID'}">selected</c:if>>작성자 ID</option>
			<option value="ALL" <c:if test="${searchType eq 'ALL'}">selected</c:if>>전체</option>
		</select>
		<input type="text" id="searchKeyword" name="searchKeyword" value="${searchKeyword }" placeholder="검색어를 입력하세요">
		<a href="#this" class="btn_search" id="searchBtn">조회</a>
	</div>
	<!-- [수정 끝] 검색 UI (HTML) 추가 -->

	<table class="board_list">
		<colgroup>
			<col width="10%"/>
			<col width="*"/>
			<col width="15%"/>
			<col width="20%"/>
		</colgroup>
		<thead>
			<tr>
				<th scope="col">글번호</th>
				<th scope="col">제목</th>
				<th scope="col">조회수</th>
				<th scope="col">작성일</th>
			</tr>
		</thead>
		<tbody>
			<c:choose>
				<c:when test="${fn:length(list) > 0}">  <!-- boolean -->
					<c:forEach items="${list }" var="row" varStatus="status">
						<tr>
							<td>${row.IDX }</td>
							<td class="title">
								<a href="#this" name="title">${row.TITLE }</a>
								<input type="hidden" id="IDX" value="${row.IDX }">
							</td>
							<td>${row.HIT_CNT }</td>
							<td>${row.CREA_DTM }</td>
						</tr>
					</c:forEach>
				</c:when>
				<c:otherwise>
					<tr>
						<td colspan="4">조회된 결과가 없습니다.</td>
					</tr>
				</c:otherwise>
			</c:choose>
		</tbody>
	</table>
	
	<c:if test="${not empty paginationInfo }">
		<ui:pagination paginationInfo = "${paginationInfo }" type="text" jsFunction="fn_search"/>
	</c:if>
	<input type="hidden" id="currentPageNo" name="currentPageNo"/>
	
	<br/>
	<a href="#this" class="btn" id="write">글쓰기</a>
	
	<%@ include file="/WEB-INF/include/include-body.jspf" %>
	
	<!-- [수정 시작] JavaScript: 검색 버튼 클릭 이벤트 및 fn_search 함수 수정 -->
	<script type="text/javascript">
		$(document).ready(function(){
			// 기존 글쓰기 버튼 이벤트
			$("#write").on("click", function(e){ 
				e.preventDefault();
				fn_openBoardWrite();
			});	
			
			// 기존 제목 클릭 이벤트
			$("a[name='title']").on("click", function(e){ 
				e.preventDefault();
				fn_openBoardDetail($(this));
			});
			
			// 1. 검색 버튼 이벤트 추가
			$("#searchBtn").on("click", function(e){
				e.preventDefault();
				// 검색 시 첫 페이지(1)로 이동하도록 fn_search 호출
				fn_search('1'); 
			});
			
			// 2. 검색어 입력 후 Enter 키 이벤트 추가 (사용자 편의성 증대)
			$("#searchKeyword").on("keypress", function(e){
				if(e.which == 13){ // Enter key code
					e.preventDefault();
					fn_search('1');
				}
			});
			
			// 기존에 미완성된 코드 제거
			// $("#bb").
		});
		
		
		function fn_openBoardWrite(){
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardWrite.do' />");
			comSubmit.submit();
		}
		
		function fn_openBoardDetail(obj){   // obj는 현재 자기 자신을 뜻함. 인자값은 뭘 담아간다는 얘기. 
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardDetail.do' />");
			comSubmit.addParam("IDX", obj.parent().find("#IDX").val()); // key와 value값  			// 이 값을 부른 걸 키 값에 받겠다. 키가 가는 거.
			comSubmit.submit();	// 전송
		}
		
		// 3. fn_search 함수를 검색 파라미터까지 포함하도록 수정
		function fn_search(pageNo)
		{
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardList.do'/>");
			comSubmit.addParam("currentPageNo", pageNo);
			
			// 검색 파라미터 추가
			comSubmit.addParam("searchType", $("#searchType").val());
			comSubmit.addParam("searchKeyword", $("#searchKeyword").val());
			
			comSubmit.submit();
		}
	</script>	
	<!-- [수정 끝] JavaScript: 검색 버튼 클릭 이벤트 및 fn_search 함수 수정 -->
</body>
</html>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="<http://java.sun.com/jsp/jstl/core>"%>
<%@ taglib prefix="fn" uri="<http://java.sun.com/jsp/jstl/functions>"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<http://www.w3.org/TR/html4/loose.dtd>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="/WEB-INF/include/include-header.jspf" %>
</head>
<body>
	<table class="board_view">
		<colgroup>
			<col width="15%"/>
			<col width="35%"/>
			<col width="15%"/>
			<col width="35%"/>
		</colgroup>
		<caption>게시글 상세</caption>
		<tbody>
			<tr>
				<th scope="row">글 번호</th>
				<td>${map.IDX }</td>    // map 에 있는 IDX 이걸 꺼내라. 
				<th scope="row">조회수</th>
				<td>${map.HIT_CNT }</td>			// map에 있는 히트 카운트를 꺼내라. 
			</tr>
			<tr>
				<th scope="row">작성자</th>
				<td>${map.CREA_ID }</td>
				<th scope="row">작성시간</th>
				<td>${map.CREA_DTM }</td>
			</tr>
			<tr>
				<th scope="row">제목</th>
				<td colspan="3">${map.TITLE }</td>
			</tr>
			<tr>
				<td colspan="4">${map.CONTENTS }</td>
			</tr>
			<tr>
				<th scope="row">첨부파일</th>
				<td colspan="3">
				<c:choose>
					<c:when test="${fn:length(list) >0 }"> <!--  boolean  -->
						<c:forEach var="row" items="${list}">
							<input type="hidden" id="IDX" value="${row.IDX }">
							<a href="#this" name="file">${row.ORIGINAL_FILE_NAME }</a>
							(${row.FILE_SIZE }kb)
						</c:forEach>
					</c:when>
						<c:otherwise>첨부된 파일이 없습니다.!</c:otherwise>
				</c:choose>
				</td>
			</tr>
		</tbody>
	</table>
	
	<a href="#this" class="btn" id="list">목록으로</a>
	<a href="#this" class="btn" id="update">수정하기</a>	
	<a href="#this" class="btn" id="delete">삭제하기</a>
	
	<!-- 이전 글 버튼: PREV_IDX 값이 있을 때만 버튼 노출 -->
	<c:if test="${prevNextBoard.PREV_IDX != null}">
		<a href="#this" class="btn" id="preBtn">이전 페이지(게시글)</a>
	</c:if>
	
	<!-- 다음 글 버튼: NEXT_IDX 값이 있을 때만 버튼 노출 -->
	<c:if test="${prevNextBoard.NEXT_IDX != null}">
		<a href="#this" class="btn" id="nextBtn">다음 페이지(게시글)</a>
	</c:if>
	
	<%@ include file="/WEB-INF/include/include-body.jspf" %>
	<script type="text/javascript">

		$(document).ready(function(){
			$("#list").on("click", function(e){ //목록으로 버튼
				e.preventDefault();
				fn_openBoardList();
			});
			
			$("#update").on("click", function(e){ //수정하기 버튼
				e.preventDefault();
				fn_openBoardUpdate();
			});
			
			$("#delete").on("click", function(e) {
				e.preventDefault();
				fn_openBoardDelete();
			})
			
			$("#preBtn").on("click", function(e) {
				e.preventDefault();
				fn_openBoardPreview();
			})
			
			$("#nextBtn").on("click", function(e) {
				e.preventDefault();
				fn_openBoardNext();
			})
			
			$("a[name='file']").on("click", function(e){ //파일이름
				e.preventDefault();
				fn_downloadFile($(this));
			});
		});
		
		function fn_openBoardList(){
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardList.do' />");
			comSubmit.submit();
		}
		
		function fn_openBoardUpdate(){
			var idx = "${map.IDX}";
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardUpdate.do' />");
			comSubmit.addParam("IDX", idx);
			comSubmit.submit();
		}
		
		function fn_openBoardDelete(){
			if (confirm("정말로 삭제하시겠습니까?")) {
					var idx = "${map.IDX}";
					var comSubmit = new ComSubmit();
					comSubmit.setUrl("<c:url value='/sample/deleteBoard.do' />");
					comSubmit.addParam("IDX", idx);
					comSubmit.submit();
			}
		}
		
		function fn_openBoardPreview(){
			var idx = "${map.IDX}";
			var prev = "${prevNextBoard.PREV_IDX}";
			var next = "${prevNextBoard.NEXT_IDX}";
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardDetail.do' />");
			comSubmit.addParam("IDX", prev);
			comSubmit.submit();
		}
		
		function fn_openBoardNext(){
			var idx = "${map.IDX}";  // 현재 페이지
			var prev = "${prevNextBoard.PREV_IDX}";
			var next = "${prevNextBoard.NEXT_IDX}";
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/sample/openBoardDetail.do' />");
			comSubmit.addParam("IDX", next);
			comSubmit.submit();
		}
				
		function fn_downloadFile(obj)
		{
			var idx = obj.parent().find("#IDX").val();
			var comSubmit = new ComSubmit();
			comSubmit.setUrl("<c:url value='/common/downloadFile.do'/>");
			comSubmit.addParam("IDX", idx);
			comSubmit.submit();
		}
	</script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<http://www.w3.org/TR/html4/loose.dtd>">
<html>
<head>
<title>Insert title here</title>
<%@ include file="/WEB-INF/include/include-header.jspf" %>
</head>
<body>
HI~
<%@ include file="/WEB-INF/include/include-body.jspf" %>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="<http://java.sun.com/jsp/jstl/core>" %>
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	    <title>게시글 미리보기</title>
	    <style>
	    /* 기본 스타일 추가 (필요에 따라) */
	        body { font-family: Arial, sans-serif; padding: 20px; }
	        h2 { color: #333; }
	        .detail-box { border: 1px solid #ccc; padding: 15px; }
	        .detail-title { font-size: 1.5em; font-weight: bold; margin-bottom: 10px; }
	        .detail-content { white-space: pre-wrap; /* 줄바꿈 유지 */ }
	    </style>
	
</head>
<body>
	<h2>게시글 미리보기</h2>
	<div class="detail-box">
		<div class="detail-title">제목: <c:out value="${map.TITLE}"/></div>
		<hr>
		<div class="detail-content">
			<c:out value="${map.CONTENTS}"/>
		</div>
	</div>
	
	<tbody>
		<td>${row.TITLE}</td>
		<td>${row.CONTENTS}</td>
	</tbody>	
	
</body>
</html>
function gfn_isNull(str) {
	if (str == null) return true;
	if (str == "NaN") return true;
	if (new String(str).valueOf() == "undefined") return true;    
    var chkStr = new String(str);
    if( chkStr.valueOf() == "undefined" ) return true;
    if (chkStr == null) return true;    
    if (chkStr.toString().length == 0 ) return true;   
    return false; 
}

function ComSubmit(opt_formId)  //-> 입력한 폼아이디값   // 공통 전송 이란 뜻.
{
	this.formId = gfn_isNull(opt_formId) == true ? "commonForm" : opt_formId;
	this.url = "";   	// 이렇게 url도 받아온데. 
	
	if(this.formId == "commonForm"){
		$("#commonForm")[0].reset();
	}
	
	this.setUrl = function setUrl(url){
		this.url = url;
	};
	
	this.addParam = function addParam(key, value)		// 키, 밸류를 받는 함수 addParam 도 만들어 놓음.
	{
		$("#"+this.formId).append($("<input type='hidden' name='"+key+"'id='"+key+"' value='"+value+"'>"));
	};
	
	this.submit = function submit()
	{
		var frm = $("#"+this.formId)[0];
		frm.action = this.url;
		frm.method = "post";
		frm.submit();	
	};
}

 var gfv_ajaxCallback = "";
 
 function ComAjax(opt_formId)
 {
	 this.url = "";
	 this.formId = gfn_isNull(opt_formId) == true?"commonForm":opt_formId;
	 this.param = "";
	 
	 if(this.formId == "commonForm")
	 {
		 var frm = $("#commonForm");
		 if(frm.length>0){
			 frm.remove();
		 }
		 
		 var str = "<form id='commonForm' name='commonForm'></form>";
		 $('body').append(str);
	 }
	 
	 this.setUrl = function setUrl(url)
	 {
		 this.url = url;
	 };
	 
	 this.setCallback = function setCallback(callBack)
	 {
		 fv_ajaxCallback = callBack;
	 };
	 
	 this.addParam = function addParam(key, value)
	 {
		 this.param = this.param + "&" + key + "=" + value;
	 };
	 
	 this.ajax = function ajax()
	 {
		 if(this.formId != "commonForm"){
			 this.param += "&" + $("#" + this.formId).serialize();
		 }
		 $.ajax({
			 url : this.url,
			 type : "post",
			 data : this.param,
			 async : false,
			 success : function(data, status){
				 if(typeof(fv_ajaxCallback) == "function"){
					 fv_ajaxCallback(data);
				 }else{
					 eval(fv_ajaxCallback + "(data);");
				 }
			 }
		 });	 
	 };
 }
 
 //페이징 태그부분
 /*
  * divId : 페이징 태그가 그려질 div
  * pageIndx : 현재 페이지 위치가 저장될 input 태그 id
  * recordCount : 페이지당 레코드 수
  * totalCount : 전체 조회 건수
  * eventName : 페이징 하단의 숫자 등의 버튼이 클릭되었을때 호출될 함수 이름
  */
 
 var gfv_pageIndex = null;
 var gfv_eventName = null;
 
 function gfn_renderPaging(params)
 {
	 var divId = params.divId; //페이징이 그려질 div id
	 gfv_pageIndex = params.pageIndex; //현재 위치가 저장될 input 태그
	 var totalCount = params.totalCount; //전체 조회 건수
	 var currentIndex = $("#"+params.pageIndex).val(); //현재 위치
	 if($("#"+params.pageIndex).length == 0 || gfn_isNull(currentIndex) == true){
		 currentIndex = 1;
	 }
	 
	 var recordCount = params.recordCount; //페이지당 레코드 수
	 if(gfn_isNull(recordCount) == true){
		 recordCount = 20;
	 }
	 
	 var totalIndexCount = Math.ceil(totalCount/recordCount); //전체 인덱스 수
	 gfn_eventName = params.eventName;
	 /*
	  * Math.floor : 소수점 버림
	  * Math.ceil : 소수점 올림
	  * Math.round : 반올림
	  * Math.random : 랜덤함수
	  * Math.sqrt : 제곱근
	  * Math.pow : 제곱
	  * Math.abs : 절대값
	  */
	 
	 $("#"+divId).empty();
	 var preStr = "";
	 var postStr = "";
	 var str = "";
	 
	 var first = (parseInt((currentIndex-1)/10)*10) + 1;
	 var last = (parseInt(totalCount/10)==parseInt(currentIndex/10))?totalIndexCount%10:10;
	 var prev = (parseInt((currentIndex-1)/10)*10) - 9 > 0 ? (parseInt((currentIndex-1)/10)*10) - 9 : 1; 
	 var next = (parseInt((currentIndex-1)/10)+1) * 10 + 1 < totalIndexCount ? (parseInt((currentIndex-1)/10)+1) * 10 + 1 : totalIndexCount;

	 if(totalIndexCount>10){
		 preStr += "<a href='#this' class='pad_5' onclick='_movePage(1)'>[<<]</a>"
	 }
	 
	 
 }