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

import java.io.Serializable;
import java.sql.ResultSet;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.BaseVo;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.common.MospUtility;
import jp.mosp.common.utils.DateUtil;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.kintai.common.action.KintaiCommonAction;
import jp.mosp.kintai.report.dao.ExportDataDao;
import jp.mosp.kintai.report.dto.MExportDto;
import jp.mosp.kintai.report.vo.ExportCardVo;

/**
 * @author yoshida
 *
 */
public class ExportCardAction extends KintaiCommonAction {
	
	// コマンド
	private static final String	CMD_EXPORT_SHOW	= "S1200";
	private static final String	CMD_EXPORT_DATA	= "S1206";
	

	/**
	 * コンストラクタ
	 */
	public ExportCardAction() {
		super();
	}
	
	/**
	 * アクション
	 */
	public void action() throws Exception {
		// VOの取得
		prepareVo();
		// 初期設定
		init();
		// コマンド毎の処理
		if (cmd.equals(CMD_EXPORT_SHOW)) {
			// 表示
			show();
		} else if (cmd.equals(CMD_EXPORT_DATA)) {
			// エクスポート
			export();
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}
	
	@Override
	protected BaseVo getSpecificVo() {
		return new ExportCardVo();
	}
	
	@Override
	protected void init() throws Exception {
		// DBコネクション取得
		getConnection();
		// 計算管理権限確認
		confirmCalculateAuth();
		ExportCardVo vo = (ExportCardVo)getVo();
		// プルダウンリスト
		vo.aryPltYear = StringUtil.getYearArray(MospUtility.getYear(DateUtil.getSystemDate()), 4, 1);
		vo.aryPltMonth = StringUtil.getMonthArray();
	}
	
	@Override
	protected void show() throws Exception {
		ExportCardVo vo = (ExportCardVo)getVo();
		Date date = DateUtil.getSystemDate();
		vo.setPltYear(String.valueOf(MospUtility.getYear(date)));
		vo.setPltMonth(String.valueOf(MospUtility.getMonth(date)));
		// 検索
		removeSessionDto();
		vo.setFields(part().export().getMExportDao().findForCondition());
		// 対象がなかった場合のメッセージ設定
		if (vo.getEscAryEName().length == 0) {
			vo.addErrMessage(getMessage(MospConst.MSG_NO_DATA, ""));
		}
		vo.setPageButton();
		sortList();
	}
	
	/**
	 * エクスポート
	 * @throws Exception 	例外処理が発生した場合
	 */
	protected void export() throws Exception {
		ExportCardVo vo = (ExportCardVo)getVo();
		// パラメータ取得
		vo.setParams(request);
		// VOに情報をセット
		// Export名称
		vo.setTxtEName(key1);
		// 対象ファイルID
		vo.setTxtEFile(key2);
		// 出力ファイル名
		StringBuffer fileName = new StringBuffer();
		fileName.append(vo.getPltYear());
		fileName.append(CommonConst.FILE_NAME_SEPARATOR);
		fileName.append(vo.getPltMonth());
		fileName.append(CommonConst.FILE_NAME_SEPARATOR);
		fileName.append(vo.getTxtEFile());
		fileName.append(CommonConst.FILE_COMMON_CSV);
		// 選択項目取得
		List<MExportDto> listSelected = part().export().getMExportDao().findForCondition(vo.getTxtEName(),
				vo.getTxtEFile());
		request.setAttribute(MospConst.ATT_FILE_NAME, fileName.toString());
		request.setAttribute(MospConst.ATT_FILE_OBJECT, makeHumanData(listSelected, vo.getTxtEFile(), vo.getPltYear(),
				vo.getPltMonth()));
		// 処理シーケンスを発行しない。
		setNeedProcSeq(false);
	}
	
	/**
	 * 人事情報作成
	 * @param listSelected		対象選択マスタ
	 * @param txtEFile			対象テーブル
	 * @param pltYear			対象年
	 * @param pltMonth			対象月
	 * @return 人事情報文字列
	 * @throws Exception 	例外処理が発生した場合
	 */
	protected StringBuffer makeHumanData(List<MExportDto> listSelected, String txtEFile, String pltYear, String pltMonth)
			throws Exception {
		// 帳票作成準備
		StringBuffer sb = new StringBuffer();
		// ヘッダー情報設定
		sb.append(appendHeader(listSelected));
		// データ追記
		sb.append(appendData(listSelected, txtEFile, pltYear, pltMonth));
		return sb;
	}
	
	/**
	 * ヘッダー情報設定
	 * @param listSelected		対象選択マスタ
	 * @return
	 * <p>
	 * 選択マスタのヘッダー情報
	 * <p>
	 * @throws Exception 	例外処理が発生した場合
	 */
	private StringBuffer appendHeader(List<MExportDto> listSelected) throws Exception {
		StringBuffer sb = new StringBuffer();
		int i = 0;
		int listSize = listSelected.size();
		// ヘッダー情報設定
		for (MExportDto dto : listSelected) {
			// ヘッダー情報設定
			sb.append(getCsvData(getEFnameItem(dto.getEFName(), 3)));
			// セパレータ設定
			if (i == listSize - 1) {
				sb.append(CommonConst.STR_CSV_NEW_LINE);
			} else {
				sb.append(CommonConst.STR_CSV_SEPARATOR);
			}
			i++;
		}
		return sb;
	}
	
	/**
	 * データ情報取得
	 * @param listSelected	対象選択マスタ
	 * @param txtEFile		対象テーブル
	 * @param pltYear		対象年
	 * @param pltMonth		対象月
	 * @return
	 * <p>
	 * 条件によるテーブルデータ文字列
	 * </p>
	 * @throws Exception 	例外処理が発生した場合
	 */
	protected StringBuffer appendData(List<MExportDto> listSelected, String txtEFile, String pltYear, String pltMonth)
			throws Exception {
		StringBuffer sb = new StringBuffer();
		// 検索範囲取得
		Date startDate = DateUtil.getFirstDateOfMonth(pltYear, pltMonth);
		Date endDate = DateUtil.getLastDateOfMonth(pltYear, pltMonth);
		// 基本、勤怠情報取得
		ExportDataDao dao = part().export().getExportDataDao();
		ResultSet rs = null;
		if (txtEFile.equals(CommonConst.CODE_TABLE_M_KIHON)) {
			// 人事基本情報の場合
			rs = dao.findForConditionKihon();
		} else if (txtEFile.equals(CommonConst.CODE_TABLE_M_KINTAI)) {
			// 勤怠情報の場合
			rs = dao.findForConditionKintai(DateUtil.convDateToStringYearMonthShort(startDate));
		} else if (txtEFile.equals(CommonConst.CODE_TABLE_M_SYUKKINBO)) {
			// 出勤簿の場合
			rs = dao.findForConditionSyukkinbo(DateUtil.convDateFormatted(startDate), DateUtil
				.convDateFormatted(endDate));
		} else if (txtEFile.equals(CommonConst.CODE_TABLE_M_YUKYU)) {
			// 有休情報の場合
			rs = dao.findForConditionYukyu(DateUtil.convDateToInteger(startDate), DateUtil.convDateToInteger(endDate));
		}
		// 上記以外
		if (rs == null) {
			addErrMessage(getMessage(CommonConst.MSG_NO_TARGET_CODE, ""));
			return sb;
		}
		sb.append(appendData(rs, listSelected));
		// 終了処理
		dao.closers();
		return sb;
	}
	
	/**
	 * データ情報追記
	 * @param rs			対象ResultSet
	 * @param listSelected	対象選択マスタ
	 * @return 			データ文字列
	 * @throws Exception 	例外処理が発生した場合
	 */
	protected StringBuffer appendData(ResultSet rs, List<MExportDto> listSelected) throws Exception {
		StringBuffer sb = new StringBuffer();
		int listSize = listSelected.size();
		while (rs.next()) {
			int i = 0;
			for (MExportDto dto : listSelected) {
				sb.append(getCsvData(rs.getString(getEFnameItem(dto.getEFName(), 2))));
				// セパレータ設定
				if (i == listSize - 1) {
					sb.append(CommonConst.STR_CSV_NEW_LINE);
				} else {
					sb.append(CommonConst.STR_CSV_SEPARATOR);
				}
				i++;
			}
		}
		return sb;
	}
	
	@Override
	protected void sortList() throws MospException {
		ExportCardVo vo = (ExportCardVo)getVo();
		vo.sortList(getComparator(vo.getFormerKey()));
		vo.setFields(vo.getList());
	}
	
	@Override
	protected Comparator<Object> getComparator(String key) throws MospException {
		ExportCardVo vo = (ExportCardVo)getVo();
		Comparator<Object> comp = null;
		if (key.equals(vo.KEY_E_NAME)) {
			comp = new CompExportName();
		} else {
			throw new MospException(MospConst.EX_SORTKEY_INVALID);
		}
		return comp;
	}
	

	/**
	 * 名称による比較クラス
	 */
	protected static class CompExportName implements Comparator<Object>, Serializable {
		
		private static final long	serialVersionUID	= -5375772027347639889L;
		

		public int compare(Object obj1, Object obj2) {
			MExportDto dto1 = (MExportDto)obj1;
			MExportDto dto2 = (MExportDto)obj2;
			return dto1.getEName().compareTo(dto2.getEName());
		}
	}
	
}
