/*
 * MosP - Mind Open Source Project         http://www.mosp.jp/
 * Copyright (C) 1987-2009 MIND Co., Ltd.  http://www.e-mind.co.jp/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package jp.mosp.common.part;

import java.util.ArrayList;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.dao.CtWorkflowCommentDao;
import jp.mosp.common.dao.CtWorkflowDao;
import jp.mosp.common.dto.CtWorkflowCommentDto;
import jp.mosp.common.dto.CtWorkflowDto;

/**
 * ワークフローに関するPartクラス
 * @author yoshida
 *	@version	0.0.4
 */
public class WorkflowPart extends BasePart {

	/**
	 * コンストラクタ
	 */
	public WorkflowPart() {
		super();
	}

	/**
	 * コンストラクタ
	 * @param partInfo
	 */
	public WorkflowPart(PartInfo partInfo) {
		super(partInfo);
	}

	/**
	 * ワークフローテーブルDAOの取得
	 * @return	初期化済みCtWorkflowDaoインスタンス
	 * @throws Exception
	 */
	public CtWorkflowDao getCtWorkflowDao() throws Exception {
		return (CtWorkflowDao) getPreparedDao(CtWorkflowDao.class.getCanonicalName());
	}

	/**
	 * ワークフローコメントテーブル用DAOの取得
	 * @since	0.0.2
	 * @return	初期化済みCtWorkflowCommentDaoインスタンス
	 * @throws Exception
	 */
	public CtWorkflowCommentDao getCtWorkflowCommentDao() throws Exception {
		return (CtWorkflowCommentDao) getPreparedDao(CtWorkflowCommentDao.class.getCanonicalName());
	}

	/**
	 * ステータスコードリスト取得
	 * @return ステータスコードリスト配列
	 * <p>
	 * [0]…未承認（申請中）
	 * [1]…承認済
	 * [2]…差戻中
	 * [3]…承認解除
	 * [4]…下書き
	 * </p>
	 */
	public static String[] getStatusCodeArray() {
		// 配列の作成
		String[] aryStatus = new String[5];
		aryStatus[0] = CommonConst.CODE_REQUEST;
		aryStatus[1] = CommonConst.CODE_APPROVED;
		aryStatus[2] = CommonConst.CODE_RETURNED;
		aryStatus[3] = CommonConst.CODE_UNLOCK;
		aryStatus[4] = CommonConst.CODE_DRAFT;
		return aryStatus;
	}

	/**
	 * ステータスリスト取得
	 * @return ステータスリスト配列
	 * <p>
	 * [0]…未承認（申請中）
	 * [1]…承認済
	 * [2]…差戻中
	 * [3]…承認解除
	 * [4]…下書き
	 * </p>
	 */
	public static String[][] getStatusArray() {
		// 配列の作成
		String[][] aryStatus = new String[5][2];
		aryStatus[0][0] = getStatusCodeArray()[0];
		aryStatus[0][1] = CommonConst.NAM_REMAIN_APPROVED;
		aryStatus[1][0] = getStatusCodeArray()[1];
		aryStatus[1][1] = CommonConst.NAME_APPROVED;
		aryStatus[2][0] = getStatusCodeArray()[2];
		aryStatus[2][1] = CommonConst.NAME_RETURNED;
		aryStatus[3][0] = getStatusCodeArray()[3];
		aryStatus[3][1] = CommonConst.NAME_UNLOCK;
		aryStatus[4][0] = getStatusCodeArray()[4];
		aryStatus[4][1] = CommonConst.NAME_DRAFT;
		return aryStatus;
	}

	/**
	 * ワークフロー取得
	 * @param workflow		ワークフロー番号
	 * @return	検索結果(DTO)
	 * @throws Exception
	 */
	public CtWorkflowDto getWorkflowDto(long workflow) throws Exception {
		return getCtWorkflowDao().findForKey(workflow);
	}

	/**
	 * 承認状況コード取得
	 * @param workflow		対象ワークフロー番号
	 * @return	承認状況コード
	 * @throws Exception 
	 */
	public String getStatusCode(long workflow) throws Exception {
		CtWorkflowDto dto = getWorkflowDto(workflow);
		if (VariousPart.chkExistDto(dto)) {
			return dto.getCurrentStatus();
		}
		return "";
	}

	/**
	 * 未承認状況の確認
	 * @since	0.0.4
	 * @param code		対象コード
	 * @return	未承認状況の是非
	 * @throws Exception 
	 */
	public static boolean isRequest(String code) throws Exception {
		return getStatusCodeArray()[0].equals(code);
	}

	/**
	 * 未承認状況の確認
	 * @param workflow		対象ワークフロー番号
	 * @return	未承認状況の是非
	 * @throws Exception 
	 */
	public boolean isStatusRequest(long workflow) throws Exception {
		return isRequest(getStatusCode(workflow));
	}

	/**
	 * 承認済み状況の確認
	 * @since	0.0.4
	 * @param code		対象コード
	 * @return	承認済み状況の是非
	 * @throws Exception 
	 */
	public static boolean isApproved(String code) throws Exception {
		return getStatusCodeArray()[1].equals(code);
	}

	/**
	 * 承認済み状況の確認
	 * @param workflow		対象ワークフロー番号
	 * @return	承認済み状況の是非
	 * @throws Exception 
	 */
	public boolean isStatusApproved(long workflow) throws Exception {
		return isApproved(getStatusCode(workflow));
	}

	/**
	 * 差戻状況の確認
	 * @since	0.0.4
	 * @param code		対象コード
	 * @return	差戻状況の是非
	 * @throws Exception 
	 */
	public static boolean isReturned(String code) throws Exception {
		return getStatusCodeArray()[2].equals(code);
	}

	/**
	 * 差戻状況の確認
	 * @param workflow		対象ワークフロー番号
	 * @return	差戻状況の是非
	 * @throws Exception 
	 */
	public boolean isStatusReturned(long workflow) throws Exception {
		return isReturned(getStatusCode(workflow));
	}

	/**
	 * 下書き判断
	 * @since	0.0.3
	 * @param code		対象コード
	 * @return
	 */
	public static boolean isDraft(String code) {
		return getStatusCodeArray()[4].equals(code);
	}

	/**
	 * 下書き状況の確認
	 * @since	0.0.3
	 * @param workflow		対象ワークフロー番号
	 * @return	下書き状況の是非
	 * @throws Exception 
	 */
	public boolean isStatusDraft(long workflow) throws Exception {
		return isDraft(getStatusCode(workflow));
	}

	/**
	 * 承認者向けコメント取得
	 * @since	0.0.2
	 * @param workflow		対象ワークフロー番号
	 * @return				最新のコメント
	 * @throws Exception
	 */
	public CtWorkflowCommentDto getWorkflowCommentForApprover(long workflow) throws Exception {
		CtWorkflowCommentDto dto = new CtWorkflowCommentDto();
		CtWorkflowDto workflowDto = getWorkflowDto(workflow);
		if (VariousPart.chkExistDto(workflowDto)) {
			dto = getCtWorkflowCommentDao().findForMaxApprover(workflowDto.getRtCode(), workflow);
		}
		return dto;
	}

	/**
	 * 対象者向けコメント取得
	 * @since	0.0.2
	 * @param target		コメント対象社員コード	
	 * @param workflow		対象ワークフロー番号
	 * @return				最新のコメント
	 * @throws Exception
	 */
	public CtWorkflowCommentDto getWorkflowCommentForTarget(
			String target,
			long workflow
	) throws Exception {
		CtWorkflowCommentDto dto = new CtWorkflowCommentDto();
		if (VariousPart.chkExistDto(getWorkflowDto(workflow))) {
			dto = getCtWorkflowCommentDao().findForMaxTarget(target, workflow);
		}
		return dto;
	}

	/**
	 * 対象者向けコメント一覧
	 * @since	0.0.2
	 * @param target		コメント対象社員コード	
	 * @param workflow		対象ワークフロー番号
	 * @return	コメント一覧	最新のコメントから順に整列
	 * @throws Exception
	 */
	public List<CtWorkflowCommentDto> getWorkflowCommentListForTarget(
			String target,
			long workflow
	) throws Exception {
		List<CtWorkflowCommentDto> listComment = new ArrayList<CtWorkflowCommentDto>();
		if (VariousPart.chkExistDto(getWorkflowDto(workflow))) {
			listComment = getCtWorkflowCommentDao().findForTarget(target, workflow);
		}
		return listComment;
	}

	/**
	 * コメント一覧配列
	 * @since	0.0.2
	 * @param target		コメント対象社員コード	
	 * @param workflow		対象ワークフロー番号
	 * @return				コメント一覧配列
	 * @throws Exception
	 */
	public String[][] getWorkflowCommentArray(
			String target,
			long workflow
	) throws Exception {
		List<CtWorkflowCommentDto> list = getWorkflowCommentListForTarget(target, workflow);
		String[][] aryComments = new String[list.size()][2];
		for (int i = 0; i < aryComments.length; i++) {
			CtWorkflowCommentDto dto = (CtWorkflowCommentDto)list.get(i);
			aryComments[i][0] = human().getKName(dto.getKCode());
			aryComments[i][1] = dto.getAuthorComment();
		}
		return aryComments;
	}

	/**
	 * 勤怠承認ステータスコード取得
	 * @since	0.0.3
	 * @param workflow			対象ワークフロー番号
	 * @return	勤怠承認ステータスコード
	 * @throws Exception
	 */
	public String toKintaiApprovalStatus(long workflow) throws Exception {
		String status = "";
		CtWorkflowDto dto = getWorkflowDto(workflow);
		if (VariousPart.chkExistDto(dto)) {
			int number = dto.getLayerNumber();
			String current = dto.getCurrentStatus();
			// 下書き
			if (isDraft(current)) {
				status = getStatusArray()[4][1];
			}
			// 未承認（申請中）
			if (isRequest(current)) {
				status = VariousPart.getApprovalStatusCodeArray()[0];
			}
			// 一次
			else if (CommonConst.NUM_LAYER1 == number) {
				if (isApproved(current)) {
					status = VariousPart.getApprovalStatusCodeArray()[1];
				} else if (isReturned(current)) {
					status = VariousPart.getApprovalStatusCodeArray()[2];
				}
			}
			// 二次
			else if (CommonConst.NUM_LAST_LAYER == number) {
				if (isApproved(current)) {
					status = VariousPart.getApprovalStatusCodeArray()[3];
				} else if (isReturned(current)) {
					status = VariousPart.getApprovalStatusCodeArray()[4];
				}
			}
		}
		return status;
	}

}
