/*
 * 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.payroll.payment.vo;

import java.util.Date;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import jp.mosp.common.common.MospException;
import jp.mosp.payroll.base.Employee;
import jp.mosp.payroll.base.Payment;
import jp.mosp.payroll.base.PayrollConst;
import jp.mosp.payroll.base.PayrollVo;

public class PaymentCardVo extends PayrollVo {
	
	private static final long	serialVersionUID	= 8936284323960296222L;
	
	// フィールド
	private String				lblKName;
	private String				lblSection;
	private String				lblCalcMonth;
	
	private String				kCode;
	private Date				calcMonth;
	
	// 画面モード
	private int					mode;
	
	private String[][]			aryTime;
	private String[][]			aryAllowance;
	private String[][]			aryDeduction;
	private String[][]			aryBreakdown;
	private String[][]			arySum;
	
	// 文字列長
	public static final int		LEN_MONEY			= PayrollConst.LEN_MONEY;
	public static final int		LEN_TIME_INT		= PayrollConst.LEN_TIME_INT;
	public static final int		LEN_TIME_DEC		= PayrollConst.LEN_TIME_DEC;
	

	/**
	 * {@link PayrollVo#PayrollVo()}を実行する。
	 */
	public PaymentCardVo() {
		super();
		
	}
	
	/* (non-Javadoc)
	 * @see jp.mosp.payroll.base.PayrollVo#setSubTitle()
	 */
	@Override
	protected void setSubTitle() {
		super.setSubTitle();
		subTitle = getName("P_PAYMENT") + getName("P_DETAIL");
		addAryMenu("P1001", getName("P_PAYMENT") + getName("P_CALCULATE") + getName("C_MENU") + getName("C_TO"));
	}
	
	/**
	 * リクエストからパラメータを取得、設定する。
	 * @param request リクエスト
	 */
	public void setParams(HttpServletRequest request) {
		for (Enumeration<?> en = request.getParameterNames(); en.hasMoreElements();) {
			String detailCode = (String)en.nextElement();
			setDetailAmount(detailCode, request.getParameter(detailCode));
		}
	}
	
	/**
	 * フィールドを設定する。
	 * @param employee 社員
	 * @param payment  給与明細
	 */
	public void setFields(Employee employee, Payment payment) {
		// 人事情報設定
		lblKName = employee.getKName();
		lblSection = employee.getSectionName();
		lblCalcMonth = payment.getCalcMonthStr();
		kCode = payment.getKCode();
		calcMonth = payment.getCalcMonth();
		// 給与情報設定
		aryTime = payment.getTimeArray(false);
		aryAllowance = payment.getAllowanceArray(false);
		aryDeduction = payment.getDeductionArray(false);
		aryBreakdown = payment.getBreakdownArray(false);
		arySum = payment.getSumArray(false);
	}
	
	/**
	 * フィールドの妥当性確認
	 * @throws MospException
	 */
	public void validate() throws MospException {
		// 妥当性確認開始時処理
		startValidation();
		// 文字タイプ確認
		/*
		checkNumber (txtPresence          , namPresence          , PRM_TXT_PRESENCE            );
		checkNumber (txtWorkOnHoliday     , namWorkOnHoliday     , PRM_TXT_WORK_ON_HOLIDAY     );
		checkNumber (txtParticularHoliday , namParticularHoliday , PRM_TXT_PARTICULAR_HOLIDAY  );
		checkNumber (txtPaidHoliday       , namPaidHoliday       , PRM_TXT_PAID_HOLIDAY        );
		checkNumber (txtAbsence           , namAbsence           , PRM_TXT_ABSENCE             );
		checkNumber (txtPaidHolidayRest   , namPaidHolidayRest   , PRM_TXT_PAID_HOLIDAY_REST   );
		checkDecimal(txtPaymentHours      , LEN_TIME_INT, LEN_TIME_DEC, namPaymentHours, PRM_TXT_PAYMENT_HOURS, false, 0);
		checkNumber (txtArriveLate        , namArriveLate        , PRM_TXT_ARRIVE_LATE         );
		checkDecimal(txtEffortTime        , LEN_TIME_INT, LEN_TIME_DEC, namEffortTime  , PRM_TXT_EFFORT_TIME  , false, 0);
		checkNumber (txtEffortAllowance   , namEffortAllowance   , PRM_TXT_EFFORT_ALLOWANCE    );
		checkDecimal(txtLateNight         , LEN_TIME_INT, LEN_TIME_DEC, namLateNight   , PRM_TXT_LATE_NIGHT   , false, 0);
		checkNumber (txtLateNightAllowance, namLateNightAllowance, PRM_TXT_LATE_NIGHT_ALLOWANCE);
		checkDecimal(txtOverLate          , LEN_TIME_INT, LEN_TIME_DEC, namOverLate    , PRM_TXT_OVER_LATE    , false, 0);
		checkNumber (txtOverLateAllowance , namOverLateAllowance , PRM_TXT_OVER_LATE_ALLOWANCE);
		checkDecimal(txtHolidayTime       , LEN_TIME_INT, LEN_TIME_DEC, namHolidayTime , PRM_TXT_HOLIDAY_TIME , false, 0);
		checkNumber (txtHolidayAllowance  , namHolidayAllowance  , PRM_TXT_HOLIDAY_ALLOWANCE   );
		checkNumber (txtAttendance_13     , namAttendance_13     , PRM_TXT_ATTENDANCE_13       );
		checkNumber (txtAttendance_14     , namAttendance_14     , PRM_TXT_ATTENDANCE_14       );
		checkNumber (txtBasicSalary       , namBasicSalary       , PRM_TXT_BASIC_SALARY        );
		checkNumber (txtAbility1Allowance , namAbility1Allowance , PRM_TXT_ABILITY1_ALLOWANCE  );
		checkNumber (txtAbility2Allowance , namAbility2Allowance , PRM_TXT_ABILITY2_ALLOWANCE  );
		checkNumber (txtFamilyAllowance   , namFamilyAllowance   , PRM_TXT_FAMILY_ALLOWANCE    );
		checkNumber (txtAllowance_05      , namAllowance_05      , PRM_TXT_ALLOWANCE_05        );
		checkNumber (txtAllowance_06      , namAllowance_06      , PRM_TXT_ALLOWANCE_06        );
		checkNumber (txtCutForMissing     , namCutForMissing     , PRM_TXT_CUT_FOR_MISSING     );
		checkNumber (txtCutForShort       , namCutForShort       , PRM_TXT_CUT_FOR_SHORT       );
		checkNumber (txtAllowance_09      , namAllowance_09      , PRM_TXT_ALLOWANCE_09        );
		checkNumber (txtAllowance_10      , namAllowance_10      , PRM_TXT_ALLOWANCE_10        );
		checkNumber (txtAllowance_11      , namAllowance_11      , PRM_TXT_ALLOWANCE_11        );
		checkNumber (txtAllowance_12      , namAllowance_12      , PRM_TXT_ALLOWANCE_12        );
		checkNumber (txtAllowance_13      , namAllowance_13      , PRM_TXT_ALLOWANCE_13        );
		checkNumber (txtDateAllowance     , namDateAllowance     , PRM_TXT_DATE_ALLOWANCE      );
		checkNumber (txtAllowance_15      , namAllowance_15      , PRM_TXT_ALLOWANCE_15        );
		checkNumber (txtAllowance_16      , namAllowance_16      , PRM_TXT_ALLOWANCE_16        );
		checkNumber (txtAllowance_17      , namAllowance_17      , PRM_TXT_ALLOWANCE_17        );
		checkNumber (txtCommutation       , namCommutation       , PRM_TXT_COMMUTATION         );
		checkNumber (txtOvertimeAllowance , namOvertimeAllowance , PRM_TXT_OVERTIME_ALLOWANCE  );
		checkNumber (txtCutFromBasic      , namCutFromBasic      , PRM_TXT_CUT_FROM_BASIC      );
		checkNumber (txtHealthInsurance   , namHealthInsurance   , PRM_TXT_HEALTH_INSURANCE    );
		checkNumber (txtPensionInsurance  , namPensionInsurance  , PRM_TXT_PENSION_INSURANCE   );
		checkNumber (txtPensionFund       , namPensionFund       , PRM_TXT_PENSION_FUND        );
		checkNumber (txtEmployeeInsurance , namEmployeeInsurance , PRM_TXT_EMPLOYEE_INSURANCE  );
		checkNumber (txtIncomeTax         , namIncomeTax         , PRM_TXT_INCOME_TAX          );
		checkNumber (txtResidenceTax      , namResidenceTax      , PRM_TXT_RESIDENCE_TAX       );
		checkNumber (txtNursingInsurance  , namNursingInsurance  , PRM_TXT_NURSING_INSURANCE   );
		checkNumber (txtDeduction_08      , namDeduction_08      , PRM_TXT_DEDUCTION_08        );
		checkNumber (txtDeduction_09      , namDeduction_09      , PRM_TXT_DEDUCTION_09        );
		checkNumber (txtDeduction_10      , namDeduction_10      , PRM_TXT_DEDUCTION_10        );
		checkNumber (txtDeduction_11      , namDeduction_11      , PRM_TXT_DEDUCTION_11        );
		checkNumber (txtDeduction_12      , namDeduction_12      , PRM_TXT_DEDUCTION_12        );
		checkNumber (txtDeduction_13      , namDeduction_13      , PRM_TXT_DEDUCTION_13        );
		checkNumber (txtDeduction_14      , namDeduction_14      , PRM_TXT_DEDUCTION_14        );
		checkNumber (txtDeduction_15      , namDeduction_15      , PRM_TXT_DEDUCTION_15        );
		checkNumber (txtDeduction_16      , namDeduction_16      , PRM_TXT_DEDUCTION_16        );
		checkNumber (txtDeduction_17      , namDeduction_17      , PRM_TXT_DEDUCTION_17        );
		checkNumber (txtDeduction_18      , namDeduction_18      , PRM_TXT_DEDUCTION_18        );
		checkNumber (txtDeduction_19      , namDeduction_19      , PRM_TXT_DEDUCTION_19        );
		checkNumber (txtDeduction_20      , namDeduction_20      , PRM_TXT_DEDUCTION_20        );
		checkNumber (lblAllowanceTotal    , namAllowanceTotal    , PRM_LBL_ALLOWANCE_TOTAL     );
		checkNumber (lblDeductionTotal    , namDeductionTotal    , PRM_LBL_DEDUCTION_TOTAL     );
		checkNumber (lblPaymentTotal      , namPaymentTotal      , PRM_LBL_PAYMENT_TOTAL       );
		checkNumber (lblBank1PayAmount    , namBank1PayAmount    , PRM_LBL_BANK1_PAY_AMOUNT    );
		checkNumber (lblBank2PayAmount    , namBank2PayAmount    , PRM_LBL_BANK2_PAY_AMOUNT    );
		checkNumber (lblCashPayAmount     , namCashPayAmount     , PRM_LBL_CASH_PAY_AMOUNT     );
		*/
		// 妥当性確認終了時処理
		endValidation();
	}
	
	/**
	 * フィールドを設定する(DTOに対するVO情報のセット)。
	 * @param payment 給与明細
	 */
	public void setDtoFields(Payment payment) {
		payment.setDetails(aryTime, aryAllowance, aryDeduction, aryBreakdown);
	}
	
	/* (non-Javadoc)
	 * @see jp.mosp.payroll.base.PayrollVo#getDirectJs(Class)
	 */
	@Override
	public String getDirectJs(Class<?> cls) throws IllegalAccessException {
		StringBuffer sb = new StringBuffer();
		sb.append(super.getDirectJs(cls));
		sb.append("var MODE = " + mode + ";");
		// 勤怠項目パラメータリスト作成
		sb.append("var ARY_TIME = new Array(");
		for (String[] element : aryTime) {
			sb.append("\"" + element[0] + "\", ");
		}
		if (aryTime.length > 0) {
			sb.delete(sb.length() - 2, sb.length());
		}
		sb.append(");");
		// 支給項目パラメータリスト作成
		sb.append("var ARY_ALLOWANCE = new Array(");
		for (String[] element : aryAllowance) {
			sb.append("\"" + element[0] + "\", ");
		}
		if (aryAllowance.length > 0) {
			sb.delete(sb.length() - 2, sb.length());
		}
		sb.append(");");
		// 控除項目パラメータリスト作成
		sb.append("var ARY_DEDUCTION = new Array(");
		for (String[] element : aryDeduction) {
			sb.append("\"" + element[0] + "\", ");
		}
		if (aryDeduction.length > 0) {
			sb.delete(sb.length() - 2, sb.length());
		}
		sb.append(");");
		// 内訳項目パラメータリスト作成
		sb.append("var ARY_BREAKDOWN = new Array(");
		for (String[] element : aryBreakdown) {
			sb.append("\"" + element[0] + "\", ");
		}
		if (aryBreakdown.length > 0) {
			sb.delete(sb.length() - 2, sb.length());
		}
		sb.append(");");
		// 合計項目パラメータリスト作成
		sb.append("var ARY_SUM = new Array(");
		for (String[] element : arySum) {
			sb.append("\"" + element[0] + "\", ");
		}
		if (arySum.length > 0) {
			sb.delete(sb.length() - 2, sb.length());
		}
		sb.append(");");
		return sb.toString();
	}
	
	/**
	 * 勤怠明細件数を取得する。<br>
	 * @return 勤怠明細値
	 */
	public int getTimeCount() {
		return aryTime.length;
	}
	
	/**
	 * 支給明細件数を取得する。<br>
	 * @return 支給明細値
	 */
	public int getAllowanceCount() {
		return aryAllowance.length;
	}
	
	/**
	 * 控除明細件数を取得する。<br>
	 * @return 控除明細値
	 */
	public int getDeductionCount() {
		return aryDeduction.length;
	}
	
	/**
	 * 内訳明細件数を取得する。<br>
	 * @return 内訳明細値
	 */
	public int getBreakdownCount() {
		return aryBreakdown.length;
	}
	
	/**
	 * 合計明細件数を取得する。<br>
	 * @return 合計明細値
	 */
	public int getSumCount() {
		return arySum.length;
	}
	
	/**
	 * 勤怠明細値を取得する。<br>
	 * @param idx インデックス
	 * @return 勤怠明細値
	 */
	public String getTimeAmount(int idx) {
		return aryTime[idx][2];
	}
	
	/**
	 * 支給明細値を取得する。<br>
	 * @param idx インデックス
	 * @return 支給明細値
	 */
	public String getAllowanceAmount(int idx) {
		return aryAllowance[idx][2];
	}
	
	/**
	 * 控除明細値を取得する。<br>
	 * @param idx インデックス
	 * @return 控除明細値
	 */
	public String getDeductionAmount(int idx) {
		return aryDeduction[idx][2];
	}
	
	/**
	 * 内訳明細値を取得する。<br>
	 * @param idx インデックス
	 * @return 内訳明細値
	 */
	public String getBreakdownAmount(int idx) {
		return aryBreakdown[idx][2];
	}
	
	/**
	 * 控除明細値を取得する。<br>
	 * @param idx インデックス
	 * @return 控除明細値
	 */
	public String getSumAmount(int idx) {
		return arySum[idx][2];
	}
	
	/**
	 * 勤怠明細コードを取得する。<br>
	 * @param idx インデックス
	 * @return 勤怠明細コード
	 */
	public String getTimeCode(int idx) {
		return aryTime[idx][0];
	}
	
	/**
	 * 支給明細コードを取得する。<br>
	 * @param idx インデックス
	 * @return 支給明細コード
	 */
	public String getAllowanceCode(int idx) {
		return aryAllowance[idx][0];
	}
	
	/**
	 * 控除明細コードを取得する。<br>
	 * @param idx インデックス
	 * @return 控除明細コード
	 */
	public String getDeductionCode(int idx) {
		return aryDeduction[idx][0];
	}
	
	/**
	 * 内訳明細コードを取得する。<br>
	 * @param idx インデックス
	 * @return 内訳明細コード
	 */
	public String getBreakdownCode(int idx) {
		return aryBreakdown[idx][0];
	}
	
	/**
	 * 合計明細コードを取得する。<br>
	 * @param idx インデックス
	 * @return 合計明細コード
	 */
	public String getSumCode(int idx) {
		return arySum[idx][0];
	}
	
	/**
	 * 勤怠明細名称を取得する。<br>
	 * @param idx インデックス
	 * @return 勤怠明細名称
	 */
	public String getTimeName(int idx) {
		return escapeHTML(aryTime[idx][1]);
	}
	
	/**
	 * 支給明細名称を取得する。<br>
	 * @param idx インデックス
	 * @return 支給明細名称
	 */
	public String getAllowanceName(int idx) {
		return escapeHTML(aryAllowance[idx][1]);
	}
	
	/**
	 * 控除明細名称を取得する。<br>
	 * @param idx インデックス
	 * @return 控除明細名称
	 */
	public String getDeductionName(int idx) {
		return escapeHTML(aryDeduction[idx][1]);
	}
	
	/**
	 * 内訳明細名称を取得する。<br>
	 * @param idx インデックス
	 * @return 内訳明細名称
	 */
	public String getBreakdownName(int idx) {
		return escapeHTML(aryBreakdown[idx][1]);
	}
	
	/**
	 * 合計明細名称を取得する。<br>
	 * @param idx インデックス
	 * @return 合計明細名称
	 */
	public String getSumName(int idx) {
		return escapeHTML(arySum[idx][1]);
	}
	
	/**
	 * 計算年月を取得する。
	 * @return 計算年月
	 */
	public Date getCalcMonth() {
		return getDateField(calcMonth);
	}
	
	/**
	 * 計算年月を設定する。
	 * @param calcMonth 設定する計算年月
	 */
	public void setCalcMonth(Date calcMonth) {
		this.calcMonth = getDateField(calcMonth);
	}
	
	/**
	 * 計算年月を取得する。
	 * @return 計算年月
	 */
	public String getEscLblCalcMonth() {
		return escapeHTML(lblCalcMonth);
	}
	
	/**
	 * 計算年月を設定する。
	 * @param lblCalcMonth 設定する計算年月
	 */
	public void setLblCalcMonth(String lblCalcMonth) {
		this.lblCalcMonth = lblCalcMonth;
	}
	
	/**
	 * 社員コードを取得する。
	 * @return 社員コード
	 */
	public String getKCode() {
		return kCode;
	}
	
	/**
	 * 社員コードを取得する。
	 * @return 社員コード
	 */
	public String getEscKCode() {
		return escapeHTML(kCode);
	}
	
	/**
	 * 社員コードを設定する。
	 * @param lblKCode 設定する社員コード
	 */
	public void setKCode(String lblKCode) {
		kCode = lblKCode;
	}
	
	/**
	 * 社員名を取得する。
	 * @return 社員名
	 */
	public String getLblKName() {
		return lblKName;
	}
	
	/**
	 * 社員名を取得する。
	 * @return 社員名
	 */
	public String getEscLblKName() {
		return escapeHTML(lblKName);
	}
	
	/**
	 * 社員名を設定する。
	 * @param lblKName 設定する社員名
	 */
	public void setLblKName(String lblKName) {
		this.lblKName = lblKName;
	}
	
	/**
	 * 所属を取得する。
	 * @return 所属
	 */
	public String getEscLblSection() {
		return escapeHTML(lblSection);
	}
	
	/**
	 * 所属を設定する。
	 * @param lblSection 設定する所属
	 */
	public void setLblSection(String lblSection) {
		this.lblSection = lblSection;
	}
	
	/**
	 * 明細値を設定する。<br>
	 * @param aryDetail  明細配列
	 * @param detailCode 明細コード
	 * @param amount     明細値
	 */
	private void setDetailAmount(String detailCode, String amount) {
		for (int i = 0; i < aryTime.length; i++) {
			if (aryTime[i][0].equals(detailCode)) {
				aryTime[i][2] = amount;
				return;
			}
		}
		for (int i = 0; i < aryAllowance.length; i++) {
			if (aryAllowance[i][0].equals(detailCode)) {
				aryAllowance[i][2] = amount;
				return;
			}
		}
		for (int i = 0; i < aryDeduction.length; i++) {
			if (aryDeduction[i][0].equals(detailCode)) {
				aryDeduction[i][2] = amount;
				return;
			}
		}
		for (int i = 0; i < aryBreakdown.length; i++) {
			if (aryBreakdown[i][0].equals(detailCode)) {
				aryBreakdown[i][2] = amount;
				return;
			}
		}
		for (int i = 0; i < arySum.length; i++) {
			if (arySum[i][0].equals(detailCode)) {
				arySum[i][2] = amount;
				return;
			}
		}
	}
	
	/**
	 * 画面モードを設定する。<br><br>
	 * 0:登録可、1：登録不可
	 * @param mode 設定する画面モード
	 */
	public void setMode(int mode) {
		this.mode = mode;
	}
	
}
