/*
 * 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.common.part;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jp.mosp.common.CommonConst;
import jp.mosp.common.MosPMenuConst;
import jp.mosp.common.dto.CmAuthorityDto;
import jp.mosp.common.dto.CmComponentDto;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.common.utils.VariousUtil;

/**
 * メニューに関するPartクラス
 * @author yoshida
 *	@version		0.0.1
 */
public class MosPMenuPart extends BasePart {
	
	/**
	 * コンストラクタ
	 */
	public MosPMenuPart() {
		super();
	}
	
	/**
	 * コンストラクタ
	 * @param partInfo Partを利用する際に必要な情報
	 */
	public MosPMenuPart(PartInfo partInfo) {
		super(partInfo);
	}
	
	/**
	 * デフォルトメニュー権限リスト作成(Authority)
	 * @return map
	 */
	public static Map<String, CmAuthorityDto> getDefaultAuthMap() {
		Map<String, CmAuthorityDto> map = new HashMap<String, CmAuthorityDto>();
		String[][] aryDefault = getDefaultAuthArray();
		for (String[] element : aryDefault) {
			CmAuthorityDto dto = new CmAuthorityDto();
			dto.setAuthCode(element[0]);
			dto.setAuthName(element[1]);
			dto.setEmployee(element[2]);
			dto.setManager(element[3]);
			dto.setPayroll(element[4]);
			dto.setHuman(element[5]);
			map.put(dto.getAuthCode(), dto);
		}
		return map;
	}
	
	/**
	 * デフォルトDTO作成（CmComponent）
	 * <p>メニュー番号</p>
	 * 勤怠入力…{@link CommonConst#AUTH_EMPLOYEE_MENU}<br>
	 * 勤怠管理…{@link CommonConst#AUTH_MANAGER_MENU}<br>
	 * 人事管理…{@link CommonConst#AUTH_HUMAN_MENU}<br>
	 * 給与管理…{@link CommonConst#AUTH_PAYROLL_MENU}<br>
	 * 計算権限…{@link CommonConst#AUTH_CALCULATE_MENU}<br>
	 * @param menuNo		メニュー番号
	 * @return 対象メニューデフォルトDTO
	 */
	public static CmComponentDto getDefaultCompoDto(int menuNo) {
		CmComponentDto dto = new CmComponentDto();
		String[] aryDefault = getDefaultCompArray()[menuNo];
		dto.setDivision(aryDefault[0]);
		dto.setCompCode(aryDefault[0]);
		dto.setCompName(aryDefault[1]);
		dto.setManage(Integer.parseInt(aryDefault[2]));
		dto.setComponent(aryDefault[3]);
		return dto;
	}
	
	/**
	 * 各デフォルト基本権限の配列作成 {division/code,name,manage,component}
	 * @return array
	 */
	public static String[][] getDefaultCompArray() {
		return new String[][]{
			{ CommonConst.CONF_ID_EMPLOYEE, CommonConst.NAM_AUTH_EMPLOYEE, CommonConst.NUM_BELONGING_SECTION,
				convAryToComponent(MosPMenuConst.getCmdEmployeeArray()) },
			{ CommonConst.CONF_ID_MANAGER, CommonConst.NAM_AUTH_MANAGER, CommonConst.NUM_SELECT_SECTION,
				convAryToComponent(MosPMenuConst.getCmdManagerArray()) },
			{ CommonConst.CONF_ID_HUMAN, CommonConst.NAM_AUTH_HUMAN, CommonConst.NUM_ALL_SECTION,
				convAryToComponent(MosPMenuConst.getCmdHumanArray()) },
			{ CommonConst.CONF_ID_PAYROLL, CommonConst.NAM_AUTH_PAYROLL, CommonConst.NUM_ALL_SECTION,
				convAryToComponent(MosPMenuConst.getPayrollRestrictCalcArray()) },
			{ CommonConst.CONF_ID_CALCULATE, CommonConst.NAM_AUTH_CALCULATE, CommonConst.NUM_ALL_SECTION,
				convAryToComponent(MosPMenuConst.getCmdPayrollArray()) }, };
	}
	
	/**
	 * デフォルト権限コードの配列作成 {code,name,Employee,Manager,Payroll,Human}
	 * @return array
	 */
	public static String[][] getDefaultAuthArray() {
		return new String[][]{
			{ CommonConst.AUTH_DEFAULT_USER, CommonConst.NAM_AUTH_EMPLOYEE, CommonConst.CONF_ID_EMPLOYEE, "", "", "" },
			{ CommonConst.AUTHORITY_MANAGER, CommonConst.NAM_AUTH_MANAGER, CommonConst.CONF_ID_EMPLOYEE,
				CommonConst.CONF_ID_MANAGER, "", "" },
			{ CommonConst.AUTHORITY_PAYROLL, CommonConst.NAM_AUTH_PAYROLL, CommonConst.CONF_ID_EMPLOYEE, "",
				CommonConst.CONF_ID_PAYROLL, "" },
			{ CommonConst.AUTHORITY_HUMAN, CommonConst.NAM_AUTH_HUMAN, CommonConst.CONF_ID_EMPLOYEE, "", "",
				CommonConst.CONF_ID_HUMAN },
			{ CommonConst.AUTHORITY_CALCULATE, CommonConst.NAM_AUTH_CALCULATE, CommonConst.CONF_ID_EMPLOYEE, "",
				CommonConst.CONF_ID_CALCULATE, "" },
			{ CommonConst.AUTHORITY_SENIORS, CommonConst.NAM_AUTH_SENIORS, CommonConst.CONF_ID_EMPLOYEE,
				CommonConst.CONF_ID_MANAGER, CommonConst.CONF_ID_PAYROLL, CommonConst.CONF_ID_HUMAN }, };
	}
	
	/**
	 * 二次配列データ取り出しメソッド
	 * @param array		対象配列
	 * @return	string	結合文字列
	 */
	public static String convAryToComponent(String[][] array) {
		StringBuffer sb = new StringBuffer();
		for (String[] element : array) {
			sb.append(element[0]);
			sb.append(CommonConst.STR_UNDER_SEPARATOR);
		}
		return sb.toString();
	}
	
	/**
	 * フィールド用配列設定
	 * @param component コマンド設定
	 * @return フィールド用配列
	 * <p>
	 * [0]…コマンドNo配列、[1]…名称配列
	 * </p>
	 */
	public static List<String[]> getMenuList(String component) {
		String[] aryCommand = StringUtil.divideByComma(component);
		String[] aryMenu = new String[aryCommand.length];
		String[][] aryAllCommand = StringUtil.combineArray(getAllCmdArrayList());
		for (int i = 0; i < aryCommand.length; i++) {
			aryMenu[i] = "";
			String cmdNo = aryCommand[i];
			String cmdName = StringUtil.getCodeName(cmdNo, aryAllCommand);
			if (!cmdNo.equals(cmdName)) {
				aryMenu[i] = cmdName;
			}
		}
		List<String[]> list = new ArrayList<String[]>();
		list.add(aryCommand);
		list.add(aryMenu);
		return list;
	}
	
	/**
	 * 勤怠計算ボタン表示メソッド
	 * @param dto	対象DTO
	 * @return	結合文字列
	 */
	public static String getCalcButton(CmComponentDto dto) {
		StringBuffer sb = new StringBuffer();
		if (VariousUtil.isNotNull(dto)) {
			String[] aryCommand = StringUtil.divideByComma(dto.getComponent());
			int count = 0;
			String[] aryCalcCmd = MosPMenuConst.getCmdCalcArray();
			for (int i = 0; i < aryCommand.length; i++) {
				for (String element : aryCalcCmd) {
					if (aryCommand[i].equals(element)) {
						count++;
						aryCommand[i] = CommonConst.NAM_COMMON_STRING_INITIAL_VALUE;
					}
				}
			}
			if (count > 0) {
				sb.append(aryCalcCmd[0]);
				sb.append(CommonConst.STR_UNDER_SEPARATOR);
			}
			for (String element : aryCommand) {
				if (StringUtil.isNotNull(element)) {
					sb.append(element);
					sb.append(CommonConst.STR_UNDER_SEPARATOR);
				}
			}
		}
		return sb.toString();
	}
	
	/**
	 * 勤怠計算ボタン表示メソッド
	 * @param dto				対象DTO
	 * @param isMenu			初期メニュー可否
	 * @param aryMenuCommand	対象配列
	 * @return	結合文字列
	 */
	public static String getMenuButton(CmComponentDto dto, boolean isMenu, String[] aryMenuCommand) {
		StringBuffer sb = new StringBuffer();
		if (VariousUtil.isNotNull(dto)) {
			String[] aryCommand = StringUtil.divideByComma(dto.getComponent());
			List<String> list = StringUtil.arrayToList(aryCommand);
			List<String> listMenu = StringUtil.arrayToList(aryMenuCommand);
			String menuCmd = aryMenuCommand[0];
			while (list.contains(menuCmd)) {
				list.remove(menuCmd);
			}
			if (isMenu) {
				list.add(menuCmd);
			}
			if (list.containsAll(listMenu) && isMenu) {
				sb.append(menuCmd);
				sb.append(CommonConst.STR_UNDER_SEPARATOR);
			}
			for (String select : list) {
				if (isMenu && !listMenu.contains(select)) {
					sb.append(select);
					sb.append(CommonConst.STR_UNDER_SEPARATOR);
				}
				if (!isMenu && listMenu.contains(select)) {
					sb.append(select);
					sb.append(CommonConst.STR_UNDER_SEPARATOR);
				}
			}
		}
		return sb.toString();
	}
	
	/**
	 * 全コマンドリスト生成
	 * @return	全コマンドリスト
	 */
	public static List<String[][]> getAllCmdArrayList() {
		List<String[][]> list = new ArrayList<String[][]>();
		list.add(MosPMenuConst.getCmdEmployeeArray());
		list.add(MosPMenuConst.getCmdManagerArray());
		list.add(MosPMenuConst.getCmdHumanArray());
		list.add(MosPMenuConst.getCmdPayrollArray());
		list.add(MosPMenuConst.getCmdSystemArray());
		return list;
	}
	
	/**
	 * コマンドNo一覧取得
	 * @param dto	コマンド情報
	 * @return	コマンドNo一覧
	 */
	public static String getComponentValue(CmComponentDto dto) {
		if (VariousUtil.isNotNull(dto)) {
			return dto.getComponent();
		}
		return "";
	}
	
	/**
	 * 従業員コマンド情報取得
	 * @return 従業員コマンド情報
	 * @throws Exception	例外処理が発生した場合
	 */
	public CmComponentDto getEmployeeComponentInfo() throws Exception {
		CmComponentDto componentDto = null;
		CmAuthorityDto dto = part().authority().getUserAuthDto();
		if (VariousUtil.isNotNull(dto)) {
			componentDto = part().component().findForKey(dto.getEmployee());
		}
		// デフォルトコードの設定
		if (VariousUtil.isNull(componentDto)) {
			componentDto = getDefaultCompoDto(CommonConst.AUTH_EMPLOYEE_MENU);
		}
		return componentDto;
	}
	
	/**
	 * 従業員コマンド取得
	 * @return コマンドNo一覧
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getEmployeeComponent() throws Exception {
		return getComponentValue(getEmployeeComponentInfo());
	}
	
	/**
	 * マネージャーコマンド情報取得
	 * @return マネージャーコマンド情報
	 * @throws Exception	例外処理が発生した場合
	 */
	public CmComponentDto getManagerComponentInfo() throws Exception {
		CmComponentDto componentDto = null;
		CmAuthorityDto dto = part().authority().getUserAuthDto();
		if (VariousUtil.isNotNull(dto)) {
			componentDto = part().component().findForKey(dto.getManager());
		}
		// デフォルトコードの設定
		if (VariousUtil.isNull(componentDto)) {
			componentDto = getDefaultCompoDto(CommonConst.AUTH_MANAGER_MENU);
		}
		return componentDto;
	}
	
	/**
	 * マネージャーコマンド取得
	 * @return コマンドNo一覧
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getManagerComponent() throws Exception {
		return getComponentValue(getManagerComponentInfo());
	}
	
	/**
	 * 給与コマンド情報取得
	 * @return	給与コマンド情報
	 * @throws Exception	例外処理が発生した場合
	 */
	public CmComponentDto getPayrollComponentInfo() throws Exception {
		CmComponentDto componentDto = null;
		CmAuthorityDto dto = part().authority().getUserAuthDto();
		if (VariousUtil.isNotNull(dto)) {
			componentDto = part().component().findForKey(dto.getPayroll());
		}
		// デフォルトコードの設定
		if (VariousUtil.isNull(componentDto)) {
			if (AuthorityPart.isCalculateAuth(user.getAuthority())) {
				componentDto = getDefaultCompoDto(CommonConst.AUTH_CALCULATE_MENU);
			} else {
				componentDto = getDefaultCompoDto(CommonConst.AUTH_PAYROLL_MENU);
			}
		}
		return componentDto;
	}
	
	/**
	 * 給与コマンド取得
	 * @return コマンドNo一覧
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getPayrollComponent() throws Exception {
		// 勤怠計算ボタン表示設定
		return getCalcButton(getPayrollComponentInfo());
	}
	
	/**
	 * 人事コマンド情報取得
	 * @return コマンドNo一覧情報
	 * @throws Exception	例外処理が発生した場合
	 */
	public CmComponentDto getHumanComponentInfo() throws Exception {
		CmComponentDto componentDto = null;
		CmAuthorityDto dto = part().authority().getUserAuthDto();
		if (VariousUtil.isNotNull(dto)) {
			componentDto = part().component().findForKey(dto.getHuman());
		}
		// デフォルトコードの設定
		if (VariousUtil.isNull(componentDto)) {
			componentDto = getDefaultCompoDto(CommonConst.AUTH_HUMAN_MENU);
		}
		return componentDto;
	}
	
	/**
	 * 人事コマンド取得
	 * @return コマンドNo一覧
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getHumanComponent() throws Exception {
		return getComponentValue(getHumanComponentInfo());
	}
	
	/**
	 * 権限別DTO取得(デフォルト権限を含む)
	 * @return	権限別DTO
	 * @throws Exception	例外処理が発生した場合
	 */
	public CmAuthorityDto getUserAuthInfo() throws Exception {
		CmAuthorityDto dto = part().authority().getUserAuthDto();
		// デフォルトコードの設定
		if (VariousUtil.isNull(dto)) {
			dto = MosPMenuPart.getDefaultAuthMap().get(user.getAuthority());
		}
		return dto;
	}
	
	/**
	 * 従業員権限判断
	 * @param dto	対象DTO
	 * @return
	 * <p>
	 * 従業員権限のみの場合true、そうでない場合false
	 * </p>
	 */
	public static boolean isEmployeeUser(CmAuthorityDto dto) {
		if (VariousUtil.isNotNull(dto) && StringUtil.isNotNull(dto.getEmployee())) {
			if (StringUtil.isNull(dto.getManager()) && StringUtil.isNull(dto.getPayroll())
					&& StringUtil.isNull(dto.getHuman())) {
				return true;
			}
		}
		return false;
	}
	
}
