/*
 * Copyright 2007 Kickmogu Co. Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



/*
 * 作成日: 2006/12/18
 *
 */
package com.kickmogu.rhythm.board.ws;

import java.util.Date;
import java.sql.*;
import org.apache.log4j.Category;
import com.kickmogu.rhythm.board.*;
import com.kickmogu.rhythm.core.*;
import com.kickmogu.rhythm.board.dao.BoardDao;
import com.kickmogu.s2.DAOSequence;
import com.kickmogu.s2.S2Util;

public class BoardWs {
	BoardDao boarddao = (BoardDao) S2Util.getS2Container().getComponent(BoardDao.class);
	static Category log = Category.getInstance(BoardWs.class.getName());

	public BaseResult addNode(Member loginMember, String name, int parentId) throws Exception {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		BoardTree boardtree = new BoardTree();
		boardtree.setId(DAOSequence.getNextId(BoardTree.UNIQ_KEYNAME));
		boardtree.setName(name);
		BoardTree parent = (BoardTree) RhythmTreeManager.getRoot(BoardTree.class).search(parentId);
		if (parent == null) {
			result.setStatusCode(100);
			return result;
		}
		boardtree.addToParent(parent);
		RhythmTreeManager.write(BoardTree.class);
		result.setResult(boardtree.getId());
		return result;
	}

	public BaseResult removeNode(Member loginMember, int targetId) throws Exception {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		BoardTree boardTree = (BoardTree) RhythmTreeManager.getRoot(BoardTree.class).search(targetId);
		boardTree.remove();
		RhythmTreeManager.write(BoardTree.class);
		result.setResult(boardTree.getId());
		return result;
	}

	public BaseResult updateNode(Member loginMember, int targetId, String newName) throws Exception {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		BoardTree boardTree = (BoardTree) RhythmTreeManager.getRoot(BoardTree.class).search(targetId);
		boardTree.setName(newName);
		RhythmTreeManager.write(BoardTree.class);
		result.setResult(boardTree.getId());
		return result;
	}
	
	public BaseResult post(Member loginMember, int categoryId, String subject, String body) {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		Board board = new Board();
		board.setId(DAOSequence.getNextId(Board.UNIQ_KEYNAME));
		board.setRegistrant(loginMember.getId());
		board.setRootId(board.getId());
		board.setSubject(subject);
		board.setBody(body);
		board.setBoardTreeId(categoryId);
		board.setRegistDate(new Date());
		boarddao.insert(board);
		result.setResult(board);
		return result;
	}
	
	public BaseResult reply(Member loginMember, int parentId, String subject, String body) throws Exception {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		Board parentBoard = boarddao.getBoard(parentId);
		int newSeq = getChildMaxSeq(parentBoard.getRootId(), parentBoard.getSeq(), parentBoard.getDepth()) + 1;
		updateThreadSeq(parentBoard.getRootId(), newSeq);
		Board board = new Board();
		board.setId(DAOSequence.getNextId(Board.UNIQ_KEYNAME));
		board.setRegistrant(loginMember.getId());
		board.setRootId(parentBoard.getRootId());
		board.setSubject(subject);
		board.setBody(body);
		board.setSeq(newSeq);
		board.setDepth(parentBoard.getDepth() + 1);
		board.setBoardTreeId(parentBoard.getBoardTreeId());
		board.setRegistDate(new Date());
		boarddao.insert(board);
		result.setResult(board);
		return result;
	}
	
	public BaseResult listRootBoards(Member loginMember, int categoryId) {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		result.setResult(boarddao.listRootBoards(categoryId));
		return result;
	}
	
	public BaseResult getBoard(Member loginMember, int boardId) {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		result.setResult(boarddao.getBoard(boardId));
		return result;
	}
	
	private int getChildMaxSeq(int rootId, int seq, int depth) throws Exception {
		int maxSeq = seq;
		Connection conn = S2Util.getConnection();
		PreparedStatement ps = conn.prepareStatement("select seq, depth from board where rootId = ? and seq > ? order by seq");
		try {
			ps.setInt(1, rootId);
			ps.setInt(2, seq);
			ResultSet rs = ps.executeQuery();
			while (rs.next()) {
				if (depth >= rs.getInt("depth")) {
					break;
				}
				maxSeq = rs.getInt("seq");
			}
		} finally {
			ps.close();
			conn.close();
		}
		return maxSeq;
	}
	
	private void updateThreadSeq(int rootId, int seq) throws Exception {
		Connection conn = S2Util.getConnection();
		PreparedStatement ps = conn.prepareStatement("update board set seq = seq + 1 where rootId = ? and seq >= ?");
		try {
			ps.setInt(1, rootId);
			ps.setInt(2, seq);
			ps.execute();
		} finally {
			ps.close();
			conn.close();
		}
	}
	
	private String toBoardXmlTag(Board board) {
		return "<board id=\"" + board.getId() + "\""
			+ " subject=\"" + board.getSubject() + "\""
			+ " registrantName=\"" + board.getRegistrantName() + "\""
			+ " registDate=\"" + board.getRegistDate().getTime() + "\""
			+ ">";
	}

	/**
	 * 特定のThreadの親子関係を含めたXML形式文字列を返す
	 * @param loginMember
	 * @param rootId
	 * @return
	 */
	public BaseResult listBoardThreads(Member loginMember, int rootId) {
		BaseResult result = new BaseResult();
		if (!loginMember.isLogined(result)) {
			return result;
		}
		Board[] threads = boarddao.listBoardThreads(rootId);
		StringBuffer out = new StringBuffer();
		int beforeDepth = -1;
		for (int i = 0; i < threads.length; i++) {
			if (beforeDepth < threads[i].getDepth()) {
				for (int j = 0; j < threads[i].getDepth() - beforeDepth; j++) {
					out.append(toBoardXmlTag(threads[i]) + "\n");
				}
			} else {
				for (int j = 0; j < beforeDepth - threads[i].getDepth() + 1; j++) {
					out.append("</board>\n");
				}
				out.append(toBoardXmlTag(threads[i]) + "\n");
			}
			beforeDepth = threads[i].getDepth();
		}
		for (int j = 0; j < beforeDepth + 1; j++) {
			out.append("</board>\n");
		}
		result.setResult(out.toString());
		return result;
	}
	
	public void wsdldummy(Board board) {
		
	}
}
