/**
 * ÀÌ ¼Ò½º´Â Spring ÇÁ·¹ÀÓ¿öÅ© ¿öÅ©ºÏ¿¡¼­ »ç¿ëÇÑ ¿¹Á¦ ¼Ò½ºÀÔ´Ï´Ù. 
 * ÀÌ ¼Ò½º´Â ¸ðµç °³¹ßÀÚµéÀÌ ÀÚÀ¯·Ó°Ô ¼öÁ¤ ¹× ¹èÆ÷ÇÒ ¼ö ÀÖ½À´Ï´Ù. 
 * ´Ü, ÀÌ ¼Ò½º¸¦ ±â¹ÝÀ¸·Î »õ·Î¿î ¾ÖÇÃ¸®ÄÉÀÌ¼ÇÀ» °³¹ßÇÒ °æ¿ì ÃâÃ³¸¦ ¸í½ÃÇØ ÁÖ½Ã¸é µË´Ï´Ù. 
 */
package net.javajigi.board.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;

import javax.sql.DataSource;

import net.javajigi.board.model.Board;
import net.javajigi.common.dao.MyJdbcDaoSupport;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.jdbc.object.SqlUpdate;

public class SpringJDBCWithMSBoardDAO extends MyJdbcDaoSupport implements
        BoardDAO {
    private Insert insert;

    private Update update;

    private Delete delete;

    private UpdateHitCount updateHitCount;

    private SelectByBoardNo selectByBoardNo;

    private SelectList selectList;

    protected void initDao() throws Exception {
        super.initDao();

        insert = new Insert(getDataSource());
        update = new Update(getDataSource());
        updateHitCount = new UpdateHitCount(getDataSource());
        delete = new Delete(getDataSource());
        selectByBoardNo = new SelectByBoardNo(getDataSource());
        selectList = new SelectList(getDataSource());
    }

    public int delete(int boardNo) throws DataAccessException {
        return delete.update(boardNo);
    }

    public Board findBoard(int boardNo) throws DataAccessException {
        Board board = (Board) selectByBoardNo.findObject(boardNo);
        board.setBoardNo(boardNo);

        return board;
    }

    public List findBoardList(int currentPage, int countPerPage)
            throws DataAccessException {
        int start = (currentPage - 1) * countPerPage;

        return selectList.execute(start, countPerPage);
    }

    public int getTotalNo() throws DataAccessException {
        String sql = getMessageSourceAccessor().getMessage(
                "board.sql.totalcount");
        return getJdbcTemplate().queryForInt(sql);
    }

    public Board insert(Board board) throws DataAccessException {
        int boardNo = getIncrementer().nextIntValue();
        board.setBoardNo(boardNo);

        Object[] values = { new Integer(boardNo), board.getTitle(),
                board.getName(), board.getEmail(), board.getPassword(),
                board.getCreateDate(), board.getContent() };
        insert.update(values);

        return board;
    }

    public Board update(Board board) throws DataAccessException {
        Object[] values = { board.getTitle(), board.getName(),
                board.getEmail(), board.getContent(),
                new Integer(board.getBoardNo()) };
        update.update(values);

        return board;
    }

    public int updateHitCount(int boardNo) throws DataAccessException {
        return updateHitCount.update(boardNo);
    }

    protected class SelectList extends MappingSqlQuery {
        protected SelectList(DataSource ds) {
            super(ds, getMessageSourceAccessor().getMessage(
                    "board.sql.select.list"));
            declareParameter(new SqlParameter(Types.INTEGER));
            declareParameter(new SqlParameter(Types.INTEGER));
        }

        protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
            Board board = new Board();
            board.setBoardNo(rs.getInt("boardNo"));
            board.setTitle(rs.getString("title"));
            board.setName(rs.getString("name"));
            board.setEmail(rs.getString("email"));
            board.setCreateDate(rs.getString("createdate"));
            board.setHitCount(rs.getInt("hitCount"));

            return board;
        }
    }

    protected class SelectByBoardNo extends MappingSqlQuery {
        protected SelectByBoardNo(DataSource ds) {
            super(ds, getMessageSourceAccessor().getMessage(
                    "board.sql.select.byboardno"));
            declareParameter(new SqlParameter(Types.INTEGER));
        }

        protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
            Board board = new Board();
            board.setTitle(rs.getString("title"));
            board.setName(rs.getString("name"));
            board.setEmail(rs.getString("email"));
            board.setPassword(rs.getString("password"));
            board.setCreateDate(rs.getString("createdate"));
            board.setContent(rs.getString("content"));
            board.setHitCount(rs.getInt("hitCount"));

            return board;
        }
    }

    class Insert extends SqlUpdate {
        public Insert(DataSource dataSource) {
            super(dataSource, getMessageSourceAccessor().getMessage(
                    "board.sql.insert"));

            declareParameter(new SqlParameter(Types.INTEGER));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
        }
    }

    class Update extends SqlUpdate {
        public Update(DataSource dataSource) {
            super(dataSource, getMessageSourceAccessor().getMessage(
                    "board.sql.update"));

            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.VARCHAR));
            declareParameter(new SqlParameter(Types.INTEGER));
        }
    }

    class UpdateHitCount extends SqlUpdate {
        public UpdateHitCount(DataSource dataSource) {
            super(dataSource, getMessageSourceAccessor().getMessage(
                    "board.sql.update.hitcount"));

            declareParameter(new SqlParameter(Types.INTEGER));
        }
    }

    class Delete extends SqlUpdate {
        public Delete(DataSource dataSource) {
            super(dataSource, getMessageSourceAccessor().getMessage(
                    "board.sql.delete"));

            declareParameter(new SqlParameter(Types.INTEGER));
        }
    }
}
