/**
 * ÀÌ ¼Ò½º´Â Spring ÇÁ·¹ÀÓ¿öÅ© ¿öÅ©ºÏ¿¡¼­ »ç¿ëÇÑ ¿¹Á¦ ¼Ò½ºÀÔ´Ï´Ù. 
 * ÀÌ ¼Ò½º´Â ¸ðµç °³¹ßÀÚµéÀÌ ÀÚÀ¯·Ó°Ô ¼öÁ¤ ¹× ¹èÆ÷ÇÒ ¼ö ÀÖ½À´Ï´Ù. 
 * ´Ü, ÀÌ ¼Ò½º¸¦ ±â¹ÝÀ¸·Î »õ·Î¿î ¾ÖÇÃ¸®ÄÉÀÌ¼ÇÀ» °³¹ßÇÒ °æ¿ì ÃâÃ³¸¦ ¸í½ÃÇØ ÁÖ½Ã¸é µË´Ï´Ù. 
 */
package net.javajigi.board.service;

import java.util.List;

import net.javajigi.board.dao.BoardDAO;
import net.javajigi.board.dao.BoardFileDAO;
import net.javajigi.board.model.Board;
import net.javajigi.board.model.BoardFile;
import net.javajigi.common.util.DateTimeUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

public class PragrammaticTemplateBoardService implements BoardService,
		InitializingBean {
	protected final Log logger = LogFactory.getLog(getClass());

	private PlatformTransactionManager transactionManager;

	private TransactionTemplate transactionTemplate;

	private BoardDAO boardDAO = null;

	private BoardFileDAO boardFileDAO = null;

	public void setTransactionManager(
			PlatformTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	public void setBoardDAO(BoardDAO newBoardDAO) {
		this.boardDAO = newBoardDAO;
	}

	public void setBoardFileDAO(BoardFileDAO newBoardFileDAO) {
		this.boardFileDAO = newBoardFileDAO;
	}

	public void afterPropertiesSet() throws Exception {
		transactionTemplate = new TransactionTemplate(transactionManager);
	}

	public Board addBoard(final Board board) {
		return (Board) transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction(TransactionStatus status) {
				board.setCreateDate(DateTimeUtil
						.getDateTimeByPattern("yyyyMMddHHmmss"));
				Board result = boardDAO.insert(board);

				if (logger.isDebugEnabled()) {
					logger.debug("added new board!!. New Board ID : "
							+ result.getBoardNo());
				}

				boardFileDAO.insert(result.getBoardNo(), board.getBoardFiles());

				return result;
			}
		});
	}

	public Board updateBoard(final Board board) {
		return (Board) transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction(TransactionStatus status) {
				Board result = boardDAO.update(board);
				if (logger.isDebugEnabled()) {
					logger.debug("updated board!!. Update Board ID : "
							+ result.getBoardNo());
				}

				boardFileDAO.insert(result.getBoardNo(), board.getBoardFiles());

				return result;
			}
		});
	}

	public int removeBoard(final int boardNo) {
		Integer result = (Integer) transactionTemplate
				.execute(new TransactionCallback() {
					public Object doInTransaction(TransactionStatus status) {
						boardFileDAO.deleteByBoardNo(boardNo);
						int result = boardDAO.delete(boardNo);

						return new Integer(result);
					}
				});

		return result.intValue();
	}

	public Board findBoard(final int boardNo) {
		return (Board) transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction(TransactionStatus status) {
				Board result = boardDAO.findBoard(boardNo);
				result.setBoardFiles(boardFileDAO.findBoardFileList(boardNo));

				return result;
			}
		});
	}

	public Board findBoardWithView(final int boardNo) {
		return (Board) transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction(TransactionStatus status) {
				boardDAO.updateHitCount(boardNo);

				return findBoard(boardNo);
			}
		});
	}

	public List findBoardList(final int currentPage, final int countPerPage) {
		return (List) transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction(TransactionStatus status) {
				return boardDAO.findBoardList(currentPage, countPerPage);
			}
		});
	}

	public int removeBoardFile(final int fileNo) {
		Integer result = (Integer) transactionTemplate
				.execute(new TransactionCallback() {
					public Object doInTransaction(TransactionStatus status) {
						int result = boardFileDAO.deleteByBoardFileNo(fileNo);
						return new Integer(result);
					}
				});

		return result.intValue();
	}

	public BoardFile findBoardFile(final int boardFileNo) {
		return (BoardFile) transactionTemplate
				.execute(new TransactionCallback() {
					public Object doInTransaction(TransactionStatus status) {
						return boardFileDAO.findBoardFile(boardFileNo);
					}
				});
	}

	public int getBoardTotalCount() {
		Integer result = (Integer) transactionTemplate
				.execute(new TransactionCallback() {
					public Object doInTransaction(TransactionStatus status) {
						int result = boardDAO.getTotalNo();
						return new Integer(result);
					}
				});

		return result.intValue();
	}
}
