/*
 * MosP - Mind Open Source Project         http://www.mosp.jp/
 * Copyright (C) 1987-2008 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.kintai.action;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.action.MosPWorkflowAction;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.common.MospUtility;

import jp.mosp.human.dao.MKihonDao;
import jp.mosp.human.dto.MKihonDto;

import jp.mosp.kintai.vo.EmployeeApprovalListVo;

public class EmployeeApprovalListAction extends MosPWorkflowAction {

	// コマンド
	private static final String CMD_APPROVAL_LIST_SHOW 		= "K2100";
	public  static final String CMD_APPROVAL_LIST_RE_SEARCH 	= "K2102";
	private static final String CMD_APPROVAL_LIST_SORT 		= "K2103";

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

	/**
	 * アクション
	 */
	public void action() throws Exception {
		// コネクション取得
		getConnection();
		// MANAGER権限確認
		confirmManagerAuth();
		// VOの取得
		EmployeeApprovalListVo vo;
		vo = (EmployeeApprovalListVo)getStoredVo(CommonConst.VO_EMPLOYEE_APPROVAL_LIST);
		if (vo == null) {
			vo = new EmployeeApprovalListVo();
		}
		vo.initVo(cfg, msg, cmd, aspUser, user);
		vo.clearMessage();
		vo.clearErrField();
		storeVo(CommonConst.VO_EMPLOYEE_APPROVAL_LIST, vo);
		session.setAttribute(MospConst.ATT_FORMER_VO, vo);
		// VO及びフォワード先URLの設定
		setVo(vo);
		setUrl(vo.getRetUrl());
		// ユーザー情報取得
		getInfo(user.getUserId());
		// 入力情報取得
		setParams(vo);
		// コマンド毎の処理
		if (cmd.equals(CMD_APPROVAL_LIST_SHOW)) {
			// 検索
			serachEmployeeList(vo);
			vo.setFormerKey(vo.KEY_K_CODE);
			vo.setIsAscending(true);
			vo.initListInfo();			
			sortList(vo);
		} else if (cmd.equals(CMD_APPROVAL_LIST_RE_SEARCH)) {
			// 再検索
			serachEmployeeList(vo);
			vo.setPageButton();
			sortList(vo);
		} else if (cmd.equals(CMD_APPROVAL_LIST_SORT)) {
			// ソート
			sortList(key1, vo);
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}

	/**
	 * 入力情報取得
	 * @param vo
	 * @throws Exception
	 */
	private void setParams(EmployeeApprovalListVo vo) throws Exception {
		// プルダウン取得
		vo.arySectionAll	= getSectionArrayAll();
		vo.aryPositionAll	= getPositionArray();
		vo.aryPltYear 		= util.getYearArray(MospUtility.getYear(getCalcMonth()));
		vo.aryPltMonth 		= util.getMonthArray();
		// 対象年月日取得
		vo.setParams(request);
		if (vo.getPltSelectYear() == null) {
			vo.setPltSelectYear(String.valueOf(MospUtility.getYear(getCalcMonth())));
			vo.setPltSelectMonth(String.valueOf(MospUtility.getMonth(getCalcMonth())));
		}
		// 人事基本情報設定
		vo.setLblKCode(mKihon.getKCode());
		vo.setLblKName(mKihon.getSimei());
		vo.setLblSectionName(util.getCodeName(mKihon.getSCode(), vo.arySectionAll));
	}

	/**
	 * 社員リスト検索
	 * @param vo EmployeeListVoインスタンス
	 * @throws Exception
	 */
	private void serachEmployeeList(EmployeeApprovalListVo vo) throws Exception {
		// DBコネクションの取得
		if (conn == null) {
			getConnection();
		}
		// 対象年月取得
		Date targetDate = util.getFirstDateOfMonth(vo.getPltSelectYear(), vo.getPltSelectMonth());
		// 検索範囲取得
		int startDate = util.convDateToInteger(getStartDate(targetDate));
		// 検索		
		MKihonDao mKihonDao = new MKihonDao();
		mKihonDao.initDao(cfg, cmd, aspUser, user, conn);
		// 情報の設定
		List<MKihonDto> mKihonList = new ArrayList<MKihonDto>();
		String[][] aryRouteInfo = getBelongRouteInfoArray(mKihon.getKCode(), targetDate);
		List<MKihonDto> addMkihonList = new ArrayList<MKihonDto>();
		for (int i = 0; i < aryRouteInfo.length; i++) {
			// 選択所属の社員情報一覧
			List<MKihonDto> selectSectionUserList = mKihonDao.findForApproval(
					aryRouteInfo[i][0],
					mKihon.getJCode(),
					mKihon.getKCode(),
					mospUser.getDataLevel(),
					startDate
			);
			Iterator<MKihonDto> it = selectSectionUserList.iterator();
			while (it.hasNext()) {
				MKihonDto mKihonDto = (MKihonDto)it.next();
				mKihonList.add(mKihonDto);
			}
			// 追加社員情報
			MKihonDto addMKihonDto = mKihonDao.findForKey(aryRouteInfo[i][1]);
			if (chkExistDto(addMKihonDto)) {
				boolean isExist = false;
				if (mKihonList.size() != 0) {
					for (int k = 0; k < mKihonList.size(); k++) {
						// 一覧にすでに追加社員情報が登録されているか検索
						if (addMKihonDto.getKCode().equals(mKihonList.get(k).getKCode())) {
							isExist = true;
							break;
						}
					}
				}
				// 一覧に存在しなければ追加。
				if (!isExist) {
					addMkihonList.add(addMKihonDto);
				}
			}
		}
		// 追加社員情報を一覧へ追加
		for (int i = 0; i < addMkihonList.size(); i++) {
			mKihonList.add(addMkihonList.get(i));
		}
		// 勤怠承認機能確認
		if (isAttendanceApprovalFunction()) {
			// VO設定
			vo.setFields(mKihonList);
			// 対象が無かった場合のメッセージ設定
			if (vo.getEscAryKCode().length == 0) {
				vo.addErrMessage(MospUtility.getMessage(msg, MospConst.MSG_NO_DATA, ""));
			}
		} else {
			// リストを空にする。
			mKihonList.clear();
			// VO設定
			vo.setFields(mKihonList);
			// 勤怠承認機能が無効場合のメッセージ設定
			vo.addErrMessage(CommonConst.MSG_ATTENDANCE_APPROVAL_FUNCTION3);
		}
	}

	/**
	 * ソート
	 * @param key ソートキー
	 * @param vo ソート対象Listを含むVO
	 * @throws MospException
	 */
	private void sortList(String key, EmployeeApprovalListVo vo) throws MospException {
		vo.sortList(key, getComparator(key, vo));
		vo.setFields(vo.getList());
	}

	/**
	 * ソート(VO内のキー情報でソート)
	 * @param vo ソート対象Listを含むVO
	 * @throws MospException
	 */
	private void sortList(EmployeeApprovalListVo vo) throws MospException {
		vo.sortList(getComparator(vo.getFormerKey(), vo));
		vo.setFields(vo.getList());
	}

	/**
	 * 比較クラス取得
	 * @param key ソートキー
	 * @param vo ソート対象Listを含むVO
	 * @throws MospException
	 */
	private Comparator getComparator(String key, EmployeeApprovalListVo vo) throws MospException {
		Comparator comp = null;
		if (key.equals(vo.KEY_K_CODE)) {
			comp = new CompKCode();
		} else if (key.equals(vo.KEY_K_NAME)) {
			comp = new CompKName();
		} else if (key.equals(vo.KEY_SECTION)) {
			comp = new CompSection();
		} else if (key.equals(vo.KEY_POSITION)) {
			comp = new CompPosition();
		} else {
			throw new MospException(MospConst.EX_SORTKEY_INVALID);
		}
		return comp;
	}

	/**
	 * 社員コードによる比較クラス
	 */
	protected static class CompKCode implements Comparator, Serializable {
		private static final long serialVersionUID = 1321988381196408314L;
		public int compare(Object obj1, Object obj2) {
			MKihonDto dto1 = (MKihonDto)obj1;
			MKihonDto dto2 = (MKihonDto)obj2;
			return dto1.getKCode().compareTo(dto2.getKCode());
		}
	}

	/**
	 * 社員名による比較クラス
	 */
	protected static class CompKName implements Comparator, Serializable {
		private static final long serialVersionUID = -2913545521784316945L;
		public int compare(Object obj1, Object obj2) {
			MKihonDto dto1 = (MKihonDto)obj1;
			MKihonDto dto2 = (MKihonDto)obj2;
			return dto1.getSimei().compareTo(dto2.getSimei());
		}
	}

	/**
	 * 所属による比較クラス
	 */
	protected static class CompSection implements Comparator, Serializable {
		private static final long serialVersionUID = 3158913862750258976L;
		public int compare(Object obj1, Object obj2) {
			MKihonDto dto1 = (MKihonDto)obj1;
			MKihonDto dto2 = (MKihonDto)obj2;
			return dto1.getSCode().compareTo(dto2.getSCode());
		}
	}

	/**
	 * 職位による比較クラス
	 */
	protected static class CompPosition implements Comparator, Serializable {
		private static final long serialVersionUID = 3947836481650506034L;
		public int compare(Object obj1, Object obj2) {
			MKihonDto dto1 = (MKihonDto)obj1;
			MKihonDto dto2 = (MKihonDto)obj2;
			//役職が等しい場合、等級で比較
			if (dto1.getYCode().equals(dto2.getYCode())) {
				return dto1.getTokyu().compareTo(dto2.getTokyu());
			} else {
				return dto1.getYCode().compareTo(dto2.getYCode());
			}
		}
	}

}
