/*
 * 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.report.action;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.common.MospUtility;
import jp.mosp.common.common.PoiUtility;

import jp.mosp.kintai.action.AttendanceTotalAction;
import jp.mosp.kintai.dto.MSyukkinboDto;
import jp.mosp.kintai.vo.AttendanceListVo;

import jp.mosp.report.dao.AttendanceTableDao;
import jp.mosp.report.dto.AttendanceTableDto;

public class AttendanceTableAction extends AttendanceTotalAction {

	// コマンド
	private static final String CMD_ATTENDANCE_TABLE 	= "R1051";

	// フィールド
	private List<AttendanceTableDto>	titleList	;

	//印刷プログラム制御変数
//	int		i			= 0;
	int		r			= 0;	//Row(行) 0〜
//	int		c			= 0;	//Cel(桁) 0〜
	int		pageno		= 0;	//ページ数
//	int		strl		= 0;	//開始位置
	int		endl		= 68;	//最終位置getLastRow()で取得
	int		endpagel	= 72;	//1ページの最終行数
	int		gyol		= 2;	//明細の改行数
	int		titlel		= 3;	//1ページのタイトル印刷位置
	int		firstl		= 7;	//1ページの明細開始位置
	int		lastl		= 68;	//1ページの明細最終行(合計行は含まない)
	int		totall		= 69;	//1ページの合計印刷行
	int		printcnt	= 0;
	String	file1		= "";
	//エクセル・セル番号
	int    cc[]   = {1,4,6,8,13,18,23,28,33,39,43,47,51,55,61};
	//明細項目定義 0-14上段　15-29下段
//	String    detail[]   = new String[30];
	//合計項目定義 0-14上段　15-29下段
	int    total[]    = new int[30];
	//テーブル項目定義
//	String	sikyuym		= "";
//	String	simei		= "";
//	int		nen			= 0;
//	int		tuki		= 0;
//	int		hi			= 0;
//	String	wbiko		= "";
//	String	yobi[];
//	int		dw1;

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

	/**
	 * アクション
	 */
	public void action() throws Exception {		
		// DBコネクション取得
		getConnection();
		// VOの取得
		AttendanceListVo vo = new AttendanceListVo();
		vo.initVo(cfg, msg, cmd, aspUser, user);
		// VO及びフォワード先URLの設定
		setVo(vo);
		setUrl(vo.getRetUrl());
		session.setAttribute(MospConst.ATT_FORMER_VO, vo);
		// コマンド毎の処理
		if (cmd.equals(CMD_ATTENDANCE_TABLE)) {
			vo = (AttendanceListVo)getStoredVo(CommonConst.VO_ATTENDANCE_LIST);
			if (vo == null) {
				vo = new AttendanceListVo();
			}
			vo.initVo(cfg, msg, cmd, aspUser, user);
			vo.clearMessage();
			vo.clearErrField();
			// パラメータ取得
			vo.setParams(request);
			// 表示月
			Date targetMonth = util.getYearMonth(vo.getPltYear(), vo.getPltMonth());
			// データ取得
			getTitleList(vo.getHidKCode());
			getAttendanceList(vo.getHidKCode(), targetMonth);
			// 帳票作成
			PoiUtility poi = makeAttendanceTable(targetMonth);
			// 帳票設定
			StringBuffer fileName = new StringBuffer();
			fileName.append(util.convDateToStringYearMonth(targetMonth));
			fileName.append(CommonConst.FILE_NAME_SEPARATOR);
			fileName.append(vo.getHidKCode());
			fileName.append(CommonConst.FILE_NAME_SEPARATOR);
			fileName.append(CommonConst.FILE_ATTENDANCE_TABLE);
			request.setAttribute(MospConst.ATT_FILE_NAME, fileName.toString());
			request.setAttribute(MospConst.ATT_FILE_OBJECT, poi.getWorkbook());
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}

	/**
	 * 勤務表作成
	 * @param targetMonth       対象月
	 * @return PoiUtilityインスタンス
	 * @throws Exception 
	 */
	private PoiUtility makeAttendanceTable(	Date targetMonth) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 帳票作成準備
		PoiUtility poi = new PoiUtility();
		poi.crtNewDocR(0, cfg.getProperty(MospConst.PPT_APP_DOCBASE) + CommonConst.TEMPLATE_M_KINMUHYO);
		// ヘッダー情報設定
		prtTitle(targetMonth, poi);
		// 日集計データ配列作成
		makePoiAttendance(poi);
		// データ情報設定
		prtDetail(targetMonth, poi);
		if (printcnt > 0) {
			// 総合計印刷
			prtTotalg(poi);         
			prtEnding(poi);
		}				
		return poi;
	}

	/**
	 * タイトルデータ取得
	 * @param kcode 社員コード
	 * @throws Exception
	 */
	private void getTitleList(String kcode) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 検索
		AttendanceTableDao dao = new AttendanceTableDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		titleList = new ArrayList<AttendanceTableDto>();
		titleList = dao.findForCondition(kcode);
	}

	/**
	 * タイトル印刷メソッド
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void prtTitle(Date targetMonth, PoiUtility poi) throws Exception{
		// 改ページ
		pageno += 1;
		// タイトル印刷位置算出
		r = (pageno - 1) * endpagel + (titlel - 1);
		// タイトル,日付
		r += 0;
		// 年月日
		poi.prtItem( r,  7, MospUtility.getYear (targetMonth));
		poi.prtItem( r, 12, MospUtility.getMonth(targetMonth));
		// 氏名
		Iterator<AttendanceTableDto> it = titleList.iterator();
		while(it.hasNext()){
			AttendanceTableDto dto = it.next();
			poi.prtItem( r, 24, dto.getSimei());
			// 所属
			poi.prtItem( r, 43, dto.getSName());
			r += 2;
			// 明細印刷位置算出
			r = (pageno - 1) * endpagel + (firstl - 1 - gyol);
		}
	}

	/**
	 * 明細印刷メソッド
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void prtDetail(Date targetMonth, PoiUtility poi) throws Exception{
		// 改頁確認
		chkNewPage(targetMonth, poi);   
		// 上段項目設定
		for (int i = 0; i < aryAttendance.length; i++) {
			// セルの結合
			poi.addMergedRegion(r,  8, r,12);
			poi.addMergedRegion(r, 13, r,17);
			poi.addMergedRegion(r, 18, r,22);
			poi.addMergedRegion(r, 23, r,27);
			poi.addMergedRegion(r, 28, r,32);
			poi.addMergedRegion(r, 33, r,38);
			poi.addMergedRegion(r, 39, r,42);
			poi.addMergedRegion(r, 43, r,46);
			poi.addMergedRegion(r, 47, r,50);
			poi.addMergedRegion(r, 51, r,54);
			poi.addMergedRegion(r, 55, r,60);
			poi.addMergedRegion(r, 61, r,67);

			poi.addMergedRegion(r+1,  8, r+1,12);
			poi.addMergedRegion(r+1, 13, r+1,17);
			poi.addMergedRegion(r+1, 18, r+1,22);
			poi.addMergedRegion(r+1, 23, r+1,27);
			poi.addMergedRegion(r+1, 28, r+1,32);
			poi.addMergedRegion(r+1, 33, r+1,38);
			poi.addMergedRegion(r+1, 39, r+1,42);
			poi.addMergedRegion(r+1, 43, r+1,46);
			poi.addMergedRegion(r+1, 47, r+1,50);
			poi.addMergedRegion(r+1, 51, r+1,54);
			poi.addMergedRegion(r+1, 55, r+1,60);
			poi.addMergedRegion(r+1, 61, r+1,67);

			// 上段
			poi.prtItem( r, cc[0], aryAttendance[i][1]);
			poi.prtItem( r, cc[1], aryAttendance[i][2]);
			poi.prtItem( r, cc[2], aryAttendance[i][3]);
			poi.prtItem( r, cc[3], aryAttendance[i][4]);
			if(!aryAttendance[i][4].equals("")){
				poi.prtItem( r, cc[4], aryAttendance[i][5]);
				poi.prtItem( r, cc[5], aryAttendance[i][6]);

				poi.prtItem( r, cc[6], aryAttendance[i][7]);
				poi.prtItem( r, cc[7], aryAttendance[i][8]);
				poi.prtItem( r, cc[8], aryAttendance[i][9]);

				poi.prtItem( r, cc[9],  aryAttendance[i][10]);
				poi.prtItem( r, cc[10], aryAttendance[i][11]);
				poi.prtItem( r, cc[11], aryAttendance[i][12]);

				poi.prtItem( r, cc[12], aryAttendance[i][13]);
				poi.prtItem( r, cc[13], aryAttendance[i][14]);
				poi.prtItem( r, cc[14], aryAttendance[i][15]);

				// 下段
				poi.prtItem( r+1, cc[3], aryAttendance[i][16]);
				poi.prtItem( r+1, cc[4], aryAttendance[i][17]);
				poi.prtItem( r+1, cc[5], aryAttendance[i][18]);

				poi.prtItem( r+1, cc[7], aryAttendance[i][19]);
				poi.prtItem( r+1, cc[8], aryAttendance[i][20]);

				poi.prtItem( r+1, cc[9],  aryAttendance[i][21]);
				poi.prtItem( r+1, cc[10], aryAttendance[i][22]);
				poi.prtItem( r+1, cc[11], aryAttendance[i][23]);

				poi.prtItem( r+1, cc[12], aryAttendance[i][24]);
				poi.prtItem( r+1, cc[13], aryAttendance[i][25]);
			}
			r++;
			r++;		
			// 明細印刷件数
			printcnt += 1;
		}
	}

	/**
	 * 総合計印刷メソッド
	 * @param poi
	 * @throws Exception
	 */
	private void prtTotalg(PoiUtility poi) throws Exception{	
		// 合計印刷位置算出
		r = (pageno - 1) * endpagel + (totall - 1);

		poi.addMergedRegion(r,  8, r,12);
		poi.addMergedRegion(r, 13, r,17);
		poi.addMergedRegion(r, 18, r,22);
		poi.addMergedRegion(r, 23, r,27);
		poi.addMergedRegion(r, 28, r,32);
		poi.addMergedRegion(r, 33, r,38);
		poi.addMergedRegion(r, 39, r,42);
		poi.addMergedRegion(r, 43, r,46);
		poi.addMergedRegion(r, 47, r,50);
		poi.addMergedRegion(r, 51, r,54);
		poi.addMergedRegion(r, 55, r,60);
		poi.addMergedRegion(r, 61, r,67);

		poi.addMergedRegion(r+1,  8, r+1,12);
		poi.addMergedRegion(r+1, 13, r+1,17);
		poi.addMergedRegion(r+1, 18, r+1,22);
		poi.addMergedRegion(r+1, 23, r+1,27);
		poi.addMergedRegion(r+1, 28, r+1,32);
		poi.addMergedRegion(r+1, 33, r+1,38);
		poi.addMergedRegion(r+1, 39, r+1,42);
		poi.addMergedRegion(r+1, 43, r+1,46);
		poi.addMergedRegion(r+1, 47, r+1,50);
		poi.addMergedRegion(r+1, 51, r+1,54);
		poi.addMergedRegion(r+1, 55, r+1,60);
		poi.addMergedRegion(r+1, 61, r+1,67);

		// 上段項目
		poi.prtItem( r, cc[4], getHourString(util.convIntegerTimeToDoubleTime(total[4])));
		poi.prtItem( r, cc[5], getHourString(util.convIntegerTimeToDoubleTime(total[5])));
		poi.prtItem( r, cc[6], getHourString(util.convIntegerTimeToDoubleTime(total[6])));
		poi.prtItem( r, cc[7], getHourString(util.convIntegerTimeToDoubleTime(total[7])));

		poi.prtItem( r, cc[9], total[9]);
		poi.prtItem( r, cc[10], total[10]);
		poi.prtItem( r, cc[11], total[11]);

		poi.prtItem( r, cc[13], getHourString(util.convIntegerTimeToDoubleTime(total[13])));

		// 下段項目
		poi.prtItem( r+1, cc[4], getHourString(util.convIntegerTimeToDoubleTime(total[19])));
		poi.prtItem( r+1, cc[5], getHourString(util.convIntegerTimeToDoubleTime(total[20])));

		poi.prtItem( r+1, cc[7], getHourString(util.convIntegerTimeToDoubleTime(total[22])));

		poi.prtItem( r+1, cc[9], total[24]);
		poi.prtItem( r+1, cc[10], total[25]);
		poi.prtItem( r+1, cc[11], total[26]);

		// 明細印刷件数
		printcnt += 1;
	}

	/**
	 * 新しい頁作成メソッド
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void chkNewPage(
			Date targetMonth,
			PoiUtility poi
	) throws Exception{
		// オープン
		if (pageno == 0) {
			// Pageを再生成
			crtNewDoc(poi);
			// タイトル印刷			
			prtTitle(targetMonth, poi);
		}
		if (r >= ((pageno - 1) * endpagel + (lastl - gyol))) {
			// オーバーフロー又は最初の印刷の時、タイトル印刷
			prtTitle(targetMonth, poi);
		}
		// 改行
		r += gyol;
	}

	/**
	 * 新しい頁作成メソッド
	 * @param poi
	 * @throws Exception
	 */
	private void crtNewDoc(PoiUtility poi) throws Exception{
		poi.crtNewDocR(0, file1);
		// 最終行取得
		endl  = poi.getLastRow();
	}

	/**
	 * 日集計データ配列作成
	 * @param poi
	 * @throws Exception
	 */
	private void makePoiAttendance(PoiUtility poi) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// データ数取得
		Calendar cal = Calendar.getInstance();
		cal.setTime(MospUtility.getDate(startDate));
		int count = 0;
		while (MospUtility.getDate(endDate).compareTo(cal.getTime()) >= 0) {
			cal.add(Calendar.DAY_OF_MONTH, 1);
			count++;
		}
		// 配列初期化
		aryAttendance = new String[count][40];
		for (int i = 0; i < aryAttendance.length; i++) {
			for (int j = 0; j < aryAttendance[i].length; j++) {
				aryAttendance[i][j] = "";
			}
		}
		// 日付設定
		cal.setTime(MospUtility.getDate(startDate));
		for (int i = 0; i < aryAttendance.length; i++) {
			// 日付（検索用）
			aryAttendance[i][0] = MospUtility.getDateString(cal.getTime(), CommonConst.FORMAT_DATE);
			// 日付
			aryAttendance[i][1] = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
			// 曜日
			aryAttendance[i][2] = getDayOfWeek(cal.get(Calendar.DAY_OF_WEEK));

			cal.add(Calendar.DAY_OF_MONTH, 1);
		}
		// データの設定
		Iterator<MSyukkinboDto> it = attendanceList.iterator();
		while (it.hasNext()) {
			cal.setTime(MospUtility.getDate(startDate));
			MSyukkinboDto dto = it.next();
			Date attendanceDate = MospUtility.getDate(dto.getHizuke());
			for (int i = 0; i < aryAttendance.length; i++) {
				if (attendanceDate.compareTo(cal.getTime()) == 0) {
					// 勤務形態
					if (isAvailableWorkType(dto)) {
						aryAttendance[i][4 ] = dto.getSyJikoku();
						aryAttendance[i][5 ] = getHourString(util.convIntegerTimeToDoubleTime(dto.getKinmuJi()));
						aryAttendance[i][6 ] = getHourString(util.convIntegerTimeToDoubleTime(dto.getZaJikan()));
						aryAttendance[i][7 ] = getHourString(util.convIntegerTimeToDoubleTime(dto.getSnJikan()));
						aryAttendance[i][8 ] = getHourString(util.convIntegerTimeToDoubleTime(dto.getTiJikan()));
						aryAttendance[i][9 ] = util.getCodeName(dto.getTiRiyuu(), getMosPCodeArray(CommonConst.TID_LATE_REASON));
						aryAttendance[i][10] = String.valueOf(dto.getSyokuji());
						aryAttendance[i][11] = String.valueOf(dto.getCyoku2());
						aryAttendance[i][12] = String.valueOf(dto.getHoka1());
						aryAttendance[i][13] = dto.getSHankyuKb();
						aryAttendance[i][14] = getHourString(util.convIntegerTimeToDoubleTime(dto.getKKJikan()));
						aryAttendance[i][15] = dto.getKKRiyuu();
						aryAttendance[i][16] = dto.getTaJikoku();
						aryAttendance[i][17] = getHourString(util.convIntegerTimeToDoubleTime(dto.getKyukeiJi()));
						aryAttendance[i][18] = getHourString(util.convIntegerTimeToDoubleTime(dto.getKsJikan()));
						aryAttendance[i][19] = getHourString(util.convIntegerTimeToDoubleTime(dto.getSoJikan()));
						aryAttendance[i][20] = util.getCodeName(dto.getSoRiyuu(), getMosPCodeArray(CommonConst.TID_LEAVE_EARLY_REASON));
						aryAttendance[i][21] = String.valueOf(dto.getCyoku1());
						aryAttendance[i][22] = String.valueOf(dto.getCyoku3());
						aryAttendance[i][23] = String.valueOf(dto.getHoka2());
						aryAttendance[i][24] = dto.getTHankyuKb();
						aryAttendance[i][25] = dto.getDaiKyuJyu();

						total[4] 	+=  dto.getKinmuJi();
						total[5] 	+=  dto.getZaJikan();
						total[6] 	+=  dto.getZaJikan();
						total[7] 	+=  dto.getTiJikan();
						total[9] 	+=  dto.getSyokuji();
						total[10] 	+=  dto.getCyoku2();
						total[11] 	+=  dto.getHoka1();
						total[13] 	+=  dto.getKKJikan();
						total[19] 	+=  dto.getKyukeiJi();
						total[20] 	+=  dto.getKsJikan();
						total[22] 	+=  dto.getSoJikan();
						total[24] 	+=  dto.getCyoku1();
						total[25] 	+=  dto.getCyoku3();						
						total[26] 	+=  dto.getHoka2();

						// 日付手当
						if (aryAttendance[i][31].equals("")) {
							poi.prtItem(i + 6, 30, "");
						} else {
							poi.prtItem(i + 6, 30, Integer.parseInt(aryAttendance[i][31]));
						}
					}
					aryAttendance[i][3 ] = util.getCodeName(dto.getKinmu() , getWorkTypeArrayAllWithWeekHoliday());
					break;
				}
				cal.add(Calendar.DAY_OF_MONTH, 1);
			}
		}
	}

	/**
	 * 帳票終了
	 * @param poi
	 * @throws Exception
	 */
	private void prtEnding(PoiUtility poi) throws Exception{
		// 印刷ｙ座標
		// 終了後の最初の行
		r = pageno * endpagel;
		String syori =  "delete";
		// 残り行を削除する
		for (; r <= endl; r += 1) {
			if (syori.equals("delete")) {
				poi.dltRow(r);
			}
		}
	}

}