/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：プロジェクト共通
*   モジュール名    ：JTUBatStringUtil
*   ソースファイル名：JTUStringUtil.java
*   作成者          ：富士通
*   日付            ：2011年05月19日
*＜機能概要＞
*   文字列編集部品
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v3.00.00    2011/05/19   FJ) 北村    新規作成
*	v4.00.00    2012/08/03   FJ) 北村	【TAI-2012-0000094】JBSbatSQLAccessを複数回実行回避対応
*	v5.00.00    2013/09/10   FJ) 高橋	【OM-2013-0001899】
*	v6.00.00    2013/12/11   FJ) 黒田	【ANK-1760-00-00】
*	v6.00.00    2014/03/05   FJ) 阪口	【OM-2014-0000897】
**********************************************************************/
package eo.business.common;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import eo.business.util.table.JBSbatZM_M_KYOKU_NO;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;

/**
 * 電話手続システム用文字列編集を提供する。<p>
 * ジョブで実装します。
 * <BR>
 * @author 富士通
 */
public class JTUBatStringUtil extends JCCBatCommon
{
	
	/** SQL定義キー(TU_SELECT_001)*/
	private static final String KYOKU_NO_SELECT_001 = "TU_SELECT_001";
	
	/** 
	 * 全角数字、全角英字、全角カナ、全角記号の文字列対応表 
	 */
	private static final String[] ZENKAKU = {
		"０", "１", "２", "３", "４", "５", "６", "７", "８", "９", 
		"Ａ", "Ｂ", "Ｃ", "Ｄ", "Ｅ", "Ｆ", "Ｇ", "Ｈ", "Ｉ", "Ｊ", "Ｋ", "Ｌ", "Ｍ", 
		"Ｎ", "Ｏ", "Ｐ", "Ｑ", "Ｒ", "Ｓ", "Ｔ", "Ｕ", "Ｖ", "Ｗ", "Ｘ", "Ｙ", "Ｚ", 
		"ａ", "ｂ", "ｃ", "ｄ", "ｅ", "ｆ", "ｇ", "ｈ", "ｉ", "ｊ", "ｋ", "ｌ", "ｍ", 
		"ｎ", "ｏ", "ｐ", "ｑ", "ｒ", "ｓ", "ｔ", "ｕ", "ｖ", "ｗ", "ｘ", "ｙ", "ｚ", 
		"ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", 
		"セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", 
		"ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", 
		"リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン",
		"ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ー",
		"！", "＃", "＄", "％", "＆", "’", "（", "）", "＊", "＋", "−", "．", "／", 
		"：", "；", "＜", "＝", "＞", "？", "＠", "［", "￥", "］", "＾", "＿", "‘", 
		"｛", "｜", "｝", "〜", "。", "「", "」", "、", "・","　"
	};
	
	/** 
	 * 半角数字と全角数字の文字列対応表 
	 */
	private static final String[] HANKAKU = {
		"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 
		"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", 
		"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", 
		"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 
		"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
		"ｱ", "ｲ", "ｳ", "ｴ", "ｵ", "ｶ", "ｷ", "ｸ", "ｹ", "ｺ", "ｻ", "ｼ", "ｽ", 
		"ｾ", "ｿ", "ﾀ", "ﾁ", "ﾂ", "ﾃ", "ﾄ", "ﾅ", "ﾆ", "ﾇ", "ﾈ", "ﾉ", "ﾊ", 
		"ﾋ", "ﾌ", "ﾍ", "ﾎ", "ﾏ", "ﾐ", "ﾑ", "ﾒ", "ﾓ", "ﾔ", "ﾕ", "ﾖ", "ﾗ", 
		"ﾘ", "ﾙ", "ﾚ", "ﾛ", "ﾜ", "ｦ", "ﾝ", 
		"ｧ", "ｨ", "ｩ", "ｪ", "ｫ", "ｬ", "ｭ", "ｮ", "ｯ", "ｰ",
		"!", "#", "$", "%", "&", "'", "(", ")", "*", "+", "-", ".", "/", 
		":", ";", "<", "=", ">", "?", "@", "[", "\\", "]", "^", "_", "`", 
		"{", "|", "}", "~", "｡", "｢", "｣", "､", "･"," "
	};
	
	/** 
	 * 全角カナの文字列対応表(2byte文字変換用)
	 */
	private static final String[] ZENKAKU2byte = {
		"ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", 
		"デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "ヴ", "パ", "ピ", "プ", "ペ", "ポ"
	};
	
	/** 
	 * 半角カナ(2byte文字)の文字列対応表
	 */
	private static final String[] HANKAKU2byte = {
		"ｶﾞ", "ｷﾞ", "ｸﾞ", "ｹﾞ", "ｺﾞ", "ｻﾞ", "ｼﾞ", "ｽﾞ", "ｾﾞ", "ｿﾞ", "ﾀﾞ", 
		"ﾁﾞ", "ﾂﾞ", "ﾃﾞ", "ﾄﾞ", "ﾊﾞ", "ﾋﾞ", "ﾌﾞ", "ﾍﾞ", "ﾎﾞ", "ｳﾞ", 
		"ﾊﾟ", "ﾋﾟ", "ﾌﾟ", "ﾍﾟ", "ﾎﾟ"
	};
	
	/** 
	 * 2byte文字検索用
	 */
	private static final String[] HANKAKU2byteSEARCH = {
		"ｶ", "ｷ", "ｸ", "ｹ", "ｺ", "ｻ", "ｼ", "ｽ", "ｾ", "ｿ", "ﾀ", "ﾁ", "ﾂ", 
		"ﾃ", "ﾄ", "ﾊ", "ﾋ", "ﾌ", "ﾍ", "ﾎ", "ｳ"
	};
	
	/**
	 * 値がNullの場合、指定した値を設定する。
	 * <br>
	 * @param checkValue 調整する文字列
	 * @param setValue 設定する値
	 * @return String 空白充填後の文字列
	 */
	public static String changeNullValue(Object checkValue, String setValue) 
	{
		if (!isNotNull(checkValue)) 
		{
			return setValue;
		}
		return checkValue.toString();
	}
	
	/**
	 * 日付記号("/",":"," ")削除処理
	 * <br>
	 * @param dateValue 日付書式に変換された文字列
	 * @return String 日付記号を削除した文字列
	 */
	public static String toFormatDateCutSymbl(String dateValue) 
	{
		if (!isNotNull(dateValue)) 
		{
			return dateValue;
		}
		return trim(dateValue.replace("/", "").replace(" ", "").replace(":", ""));
	}
	
	/**
	 * 電話番号を市外局番、市内局番、加入者番号に分割する。
	 * 
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @param tln 電話番号。数字だけで構成された9桁以上の文字列。
	 * @param dbKyokuNo テーブルアクセスクラス
	 * @return 分割した番号を格納した配列。
	 * @throws Exception      業務サービス内で発生した例外全般。
	 */
	public String[] splitTln(JBSbatCommonItem commonItem, String tln, JBSbatSQLAccess dbKyokuNo) throws Exception 
	{
		if (!isNotNull(tln)) 
		{
			return null;
		}
		if (!isTel2(tln)) 
		{
			throw new Exception("正しい電話番号を設定してください。");
		}
		
		if (tln.length() == 11) 
		{
			// 電話番号が11桁の場合
			// XXX-XXXX-XXXXに編集する。
			return formatTelNoAdd2(tln).split("-");
		}
		else
		{
			// 上記以外の桁数の場合
			// 局番テーブルより市外局番取得
			// 条件を設定
			JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
			// 局番設定
			String kyokuNo = tln.substring(0, 6);
			whereMap.setValue(kyokuNo); 							// 局番
			whereMap.setValue(commonItem.getOpeDate()); 			// 運用日
			
			dbKyokuNo.selectBySqlDefine(whereMap, KYOKU_NO_SELECT_001);
			
			JBSbatCommonDBInterface mapKyokuNo = dbKyokuNo.selectNext();
				
			if(mapKyokuNo == null)
			{
				// データが存在しない場合、エラー
				throw new Exception("局番が存在しません。");
			}
			
			String[] splitedTln = new String[3];
			splitedTln[0] = mapKyokuNo.getString(JBSbatZM_M_KYOKU_NO.AREACD); 								// 市外局番
			splitedTln[1] = kyokuNo.substring(mapKyokuNo.getString(JBSbatZM_M_KYOKU_NO.AREACD).length()); 	// 市内局番
			splitedTln[2] = tln.substring(kyokuNo.length()); 												// 加入者番号
			
			return splitedTln;
		}
	}
	
	/**
	 * 電話番号を市外局番、市内局番、加入者番号に分割し、ハイフン編集を行う。
	 * 
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @param tln 電話番号。数字だけで構成された9桁以上の文字列。
	 * @param dbKyokuNo テーブルアクセスクラス
	 * @return 分割した番号をハイフン編集した文字列。
	 * @throws Exception      業務サービス内で発生した例外全般。
	 */
	public String editTln(JBSbatCommonItem commonItem, String tln, JBSbatSQLAccess dbKyokuNo) throws Exception 
	{
		if (!isNotNull(tln)) 
		{
			return tln;
		}
		String[] splitedTln = splitTln(commonItem, tln, dbKyokuNo);
		return splitedTln[0] + "-" + splitedTln[1] + "-" + splitedTln[2];
	}
	
	/**
	 * 文字列を指定されたサイズ分取得します。
	 * <br>
	 * @param arg0 調整前の文字列
	 * @param arg1 指定サイズ（バイト数）
	 * @param arg2 文字コード（ＯＳ準拠の場合は""（空）を指定）
	 * @return String 調整後の文字列
	 * @throws UnsupportedEncodingException 文字列サイズ調整処理にて、例外が発生した場合
	 */
	public static String cutStrValue(String arg0, int arg1, String arg2) throws UnsupportedEncodingException
	{
		byte[] paraByte = null;
		
		if (arg0 == null) 
		{
			return arg0;
		}

		if (arg1 <= 0) 
		{
			return arg0;
		}
		
		if ("".equals(arg2)) 
		{
			// 文字コードＯＳ準拠
			paraByte = arg0.getBytes();
		}
		else 
		{
			// 文字コード指定
			paraByte = arg0.getBytes(arg2);
		}
		
		// 入力文字列のバイトサイズを取得する
		int paraByteSize = paraByte.length;
		
		if (paraByteSize <= arg1) 
		{
			return arg0;
		}
		else
		{
			int totalunitCharByte = 0;
			StringBuffer cutValue = new StringBuffer();
			for (int i = 0; i < arg0.length(); i++)
			{
				String unitValue = arg0.substring(i, i + 1);
				
				byte[] unitCharByte = null;
				if ("".equals(arg2)) 
				{
					// 文字コードＯＳ準拠
					unitCharByte = unitValue.getBytes();
				}
				else 
				{
					// 文字コード指定
					unitCharByte = unitValue.getBytes(arg2);
				}
				
				totalunitCharByte += unitCharByte.length;
				
				if (totalunitCharByte > arg1) 
				{
					break;
				}
				
				cutValue.append(unitValue);
			}
			
			return cutValue.toString();
		}
		
	}
	
	/**
	 * 日付オブジェクトを指定された形式の文字列に編集します。
	 * <br>
	 * @param arg0 編集する日付オブジェクト
	 * @param arg1 java.util.Date型の日付書式
	 * @param arg2 編集する文字列の日付書式
	 * @return String 指定された形式に編集された文字列
	 */
	public static String toFormatDate(String arg0, String arg1, String arg2) 
	{
		try 
		{
			SimpleDateFormat instance = new SimpleDateFormat(arg1);

			return new SimpleDateFormat(arg2).format(instance.parse(arg0));

		}
		catch (ParseException pe) 
		{
			return arg0;
		}
	}
	
	/**
	 * 半角英数字を全角に変換した結果を
	 * 「変換された文字列」として、返却します。
	 * <br>
	 * @param convStr 変換する文字列
	 * @return String 変換された文字列
	 * @throws UnsupportedEncodingException 
	 */
	public static String convertHalfToZen(String convStr) throws Exception
	{
		
		if(null == convStr || true == "".equals(convStr))
		{
			return convStr;
		}
		
		StringBuffer strBuf = new StringBuffer();
		
		// 文字列変換用
		String code = null;
		String nextCode = null;
		boolean twoByteFlg = false;
		
		// 文字列長を取得する
		int strLen =  convStr.length();
		
		// 文字列のサイズ分繰り返す
		for(int i = 0; i < convStr.length(); i++) 
		{
			// 一文字取り出す
			code = convStr.substring(i, i + 1);
			
			// 2byte文字かどうかの判定を行う
			for(int k = 0; k < HANKAKU2byteSEARCH.length; k++)
			{
				if(code.equals(HANKAKU2byteSEARCH[k]))
				{
					// 現在の文字が変換対象文字列中の最後尾でなく、かつ
					// 次の文字が『ﾞ』または『ﾟ』であった場合、2byte文字と判断
					if(strLen > i + 1)
					{
						nextCode = convStr.substring(i + 1, i + 2);
						
						if ("ﾞ".equals(nextCode) || "ﾟ".equals(nextCode))
						{
							code = code + nextCode;
							for(int m = 0; m < HANKAKU2byte.length; m++) 
							{
								if(code.equals(HANKAKU2byte[m])) 
								{
									code = ZENKAKU2byte[m];
									
									// 次の文字は飛ばす
									i++;
									twoByteFlg = true;
									break;
								}
							}
						}
						else
						{
							// 次の文字が『ﾞ』か『ﾟ』でない場合は2byte文字でないと判断しbreak
							break;
						}
					}
					else
					{
						// 最後尾の文字であった場合はbreak
						break;
					}
				}
			}
			
			// 2byte文字でない場合、通常変換を行う
			if(!twoByteFlg)
			{
				for(int j = 0; j < HANKAKU.length; j++) 
				{
					if(code.equals(HANKAKU[j])) 
					{
						code = ZENKAKU[j];

						break;
					}
				}
			}
			
			// 文字をつなげる
			strBuf.append(code);
			twoByteFlg = false;
		}
		
		return strBuf.toString();
	}
}
