/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JPCConvertString
*	ソースファイル名：JPCConvertString.java
*	作成者			：富士通
*	日付			：2011年02月16日
*＜機能概要＞
*	文字列変換を行う共通機能を提供する。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/02/16	富士通		新規作成
*   v1.01.00	2012/07/12	富士通)坂原	文字定義(ヴ)を追加
*
**********************************************************************/
package eo.common.util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;


/**
 * 文字列編集を行う共通処理を行うクラスです。<p>
 * <br>
 * @author 富士通
 */
public class JPCConvertString extends JPCCommonUtil 
{
	/** 
	 * カンマ 
	 */
	private static final String CONMA = ",";

	/** 
	 * エスケープ文字 (") 
	 */
	private static final String SINGLE = "\"";

	/** 
	 * エスケープ文字 ("") 
	 */
	private static final String DOUBLE = "\"\"";

	/** 
	 * 改行コード <CR> 
	 */
	private static final String CR = "\r";

	/** 
	 * 改行コード <LF> 
	 */
	private static final String LF = "\n";

	/** 
	 * 改行コード <CR><LF> 
	 */
	private static final String CRLF = "\r\n";

	/** 
	 * 半角カタカナ用の文字列対応表 
	 */
	private static final String[] HANKAKU_KATAKANA = {
		"ｦ", "ｧ", "ｨ", "ｩ", "ｪ", "ｫ", "ｬ", "ｭ", "ｮ", "ｯ", "-", "ｱ", "ｲ",
		"ｳ", "ｴ", "ｵ", "ｶ", "ｷ", "ｸ", "ｹ", "ｺ", "ｻ", "ｼ", "ｽ", "ｾ", "ｿ",
		"ﾀ", "ﾁ", "ﾂ", "ﾃ", "ﾄ", "ﾅ", "ﾆ", "ﾇ", "ﾈ", "ﾉ", "ﾊ", "ﾋ", "ﾌ",
		"ﾍ", "ﾎ", "ﾏ", "ﾐ", "ﾑ", "ﾒ", "ﾓ", "ﾔ", "ﾕ", "ﾖ", "ﾗ", "ﾘ", "ﾙ",
		"ﾚ", "ﾛ", "ﾜ", "ｦ", "ﾝ", "ｶﾞ", "ｷﾞ", "ｸﾞ", "ｹﾞ", "ｺﾞ", "ｻﾞ",
		"ｼﾞ", "ｽﾞ", "ｾﾞ", "ｿﾞ","ﾀﾞ", "ﾁﾞ", "ﾂﾞ", "ﾃﾞ", "ﾄﾞ", "ﾊﾞ", "ﾋﾞ",
		"ﾌﾞ", "ﾍﾞ", "ﾎﾞ","ﾊﾟ", "ﾋﾟ", "ﾌﾟ", "ﾍﾟ", "ﾎﾟ", "ｳﾞ"
	};

	/** 
	 * 半角カタカナ用の文字列対応表 
	 */
	private static final String[] HANKAKU_KATAKANA2 = {
		"ｶ", "ｷ", "ｸ", "ｹ", "ｺ", "ｻ", "ｼ", "ｽ", "ｾ", "ｿ","ﾀ",
		"ﾁ", "ﾂ", "ﾃ", "ﾄ", "ﾊ", "ﾋ", "ﾌ", "ﾍ", "ﾎ", "ｳ"
		
	};
	
	/** 
	 * 全角カナ用の文字列対応表 
	 */
	private static final char[] ZENKAKU_KATAKANA = {
		'ヲ', 'ァ', 'ィ', 'ゥ', 'ェ', 'ォ', 'ャ', 'ュ', 'ョ', 'ッ', '‐', 'ア', 'イ',
		'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ', 'シ', 'ス', 'セ', 'ソ',
		'タ', 'チ', 'ツ', 'テ', 'ト', 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ' ,'ハ', 'ヒ', 'フ',
		'ヘ', 'ホ', 'マ', 'ミ', 'ム', 'メ', 'モ', 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', 'ル',
		'レ' ,'ロ', 'ワ', 'ヲ', 'ン', 'ガ', 'ギ', 'グ', 'ゲ', 'ゴ', 'ザ', 'ジ', 'ズ',
		'ゼ', 'ゾ', 'ダ', 'ヂ', 'ヅ', 'デ', 'ド', 'バ', 'ビ', 'ブ', 'ベ', 'ボ', 'パ',
		'ピ', 'プ', 'ペ', 'ポ', 'ヴ'
	};

	/** 
	 * 全角カナ用の文字列対応表 
	 */
	private static final String[] ZENKAKU_KATAKANA2 = {
		"ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ",
		"デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "ヴ"
	};

	/** 
	 * 全角カナ用の文字列対応表 
	 */
	private static final String[] ZENKAKU_KATAKANA3 = {
		"ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ",
		"デ", "ド", "パ", "ピ", "プ", "ペ", "ポ", "ヴ"
	};
	
	/** 
	 * ひらがなの文字コード 'ぁ' 
	 */
	private static final char HIRAGANACODE_1 = 'ぁ';

	/** 
	 * ひらがなの文字コード 'ん' 
	 */
	private static final char HIRAGANACODE_2 = 'ん';
	
	/** 
	 * 全角カタカナの文字コード 'ァ' 
	 */
	private static final char KATAKANA_1 = 'ァ';

	/** 
	 * 全角カタカナの文字コード 'ン' 
	 */
	private static final char KATAKANA_2 = 'ン';

	/**
	 * ひらがな（全角）→カタカナ（全角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	public static String convFullHiraToFullKata(String arg0) 
	{
		if(JPCConvertString.isNull(arg0)) 
		{
			return arg0;
		}

		// ひらがなを全角カタカナへ変換する
		return convertFullKataFromHira(arg0);
	}
	
	/**
	 * カタカナ（全角）→ひらがな（全角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	public static String convFullKataToFullHira(String arg0) 
	{
		if(JPCConvertString.isNull(arg0)) 
		{
			return arg0;
		}

		// 全角カタカナをひらがなへ変換する
		return convertHiragana(arg0);
	}
	
	/**
	 * ひらがな（全角）→カタカナ（半角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	public static String convFullHiraToHalfKata(String arg0) 
	{
		if(JPCConvertString.isNull(arg0)) 
		{
			return arg0;
		}
		
		String zenkakuKana = null;
		
		// ひらがなを全角カタカナ、全角カタカナをひらがなへ変換
		zenkakuKana = convertToFullKataAndFullHira(arg0);

		// 全角カタカナを半角カタカナへ変換
		zenkakuKana = convertHalfKata(zenkakuKana);

		// ひらがなを全角カタカナへ戻す
		return convertFullKataFromHira(zenkakuKana);
	}
	
	/**
	 * カタカナ（半角）→ひらがな（全角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	public static String convHalfKataToFullHira(String arg0) 
	{
		if(JPCConvertString.isNull(arg0)) 
		{
			return arg0;
		}

		String zenkakuKana = null;

		// 半角カタカナを全角カタカナ、全角カタカナを半角カタカナへ変換
		zenkakuKana = convertToFullKataAndHalfKata(arg0);

		// 全角カタカナをひらがなへ変換
		zenkakuKana = convertHiragana(zenkakuKana);

		// 半角カタカナを全角カタカナへ戻す
		return convertFullKataFromKata(zenkakuKana);
	}
		
	/**
	 * カタカナ（全角）→カタカナ（半角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	public static String convFullToHalfByKata(String arg0) 
	{
		if(JPCConvertString.isNull(arg0)){
			return arg0;
		}

		// 全角カタカナから半角カタカナへ変換
		return convertHalfKata(arg0);
	}

	/**
	 * カタカナ（半角）→カタカナ（全角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	public static String convHalfToFullByKata(String arg0) 
	{
		// 変換する文字列の必須チェック
		if(isNull(arg0)) 
		{
			// NULLまたは、空文字の場合、変換する文字列をそのまま返却する
			return arg0;
		}

		// 半角カタカナから全角カタカナへ変換
		return convertFullKataFromKata(arg0);
	}

	/**
	 * カタカナ（全角）をひらがな（全角）に変換した結果を
	 * 「変換された文字列」として、返却します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	private static String convertHiragana(String arg0) 
	{
		StringBuffer strBuf = new StringBuffer();

		for(int i = 0; i < arg0.length(); i++) 
		{
			char code = arg0.charAt(i);

			if((code >= KATAKANA_1) && (KATAKANA_2 >= code)) 
			{
				strBuf.append((char)(code - KATAKANA_1 + HIRAGANACODE_1));
			}
			else 
			{
				strBuf.append((char)(code));
			}
		}

		return strBuf.toString();
	}

	/**
	 * ひらがな（全角）をカタカナ（全角）に変換した結果を
	 * 「変換された文字列」として、返却します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	private static String convertFullKataFromHira(String arg0) 
	{
		StringBuffer strBuf = new StringBuffer();

		for(int i = 0; i < arg0.length(); i++) 
		{
			char code = arg0.charAt(i);

			if((code >= HIRAGANACODE_1) && (HIRAGANACODE_2 >= code)) 
			{
				strBuf.append((char)(code - HIRAGANACODE_1 + KATAKANA_1));
			}
			else 
			{
				strBuf.append((char)(code));
			}
		}

		return strBuf.toString();
	}

	/**
	 * カタカナ（全角）をカタカナ（半角）に変換した結果を
	 * 「変換された文字列」として、返却します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	private static String convertHalfKata(String arg0) 
	{
		StringBuffer strBuf = new StringBuffer();

		boolean conFlg = false;

		// 変換した文字列を1文字ずつ取り出して半角カナへ変換する
		for(int i = 0; i < arg0.length(); i++) 
		{
			char code = arg0.charAt(i);

			for(int j = 0; j < ZENKAKU_KATAKANA.length; j++) 
			{
				if(code == ZENKAKU_KATAKANA[j]) 
				{
					strBuf.append(HANKAKU_KATAKANA[j]);

					conFlg = true;

					break;
				}
			}

			// 半角カナ対応表に一致しない文字列が存在した場合、編集前の文字をそのまま設定する
			if(!conFlg) 
			{
				strBuf.append((char)(code));
			}

			conFlg = false;
		}

		return strBuf.toString();
	}
	
	/**
	 * カタカナ（半角）をカタカナ（全角）に変換した結果を
	 * 「変換された文字列」として、返却します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	private static String convertFullKataFromKata(String arg0) 
	{
		StringBuffer sbZenkakuKata = new StringBuffer();

		boolean setFlg = false;

		for(int i=0; i<arg0.length(); i++) 
		{
			String str = arg0.substring(i, i+1);

			for(int k=0; k<HANKAKU_KATAKANA2.length; k++) 
			{
				if(str.equals(HANKAKU_KATAKANA2[k]) && i+2<=arg0.length()) 
				{
					String str2 = arg0.substring(i+1, i+2);

					if("ﾞ".equals(str2)) 
					{
						sbZenkakuKata.append(ZENKAKU_KATAKANA2[k]);

						i = i + 1;

						setFlg = true;
					}
					else if("ﾟ".equals(str2)) 
					{
						sbZenkakuKata.append(ZENKAKU_KATAKANA3[k]);

						i = i + 1;

						setFlg = true;
					}

					break;
				}
			}

			if(!setFlg) 
			{
				for(int j=0; j<HANKAKU_KATAKANA.length; j++) 
				{
					if(str.equals(HANKAKU_KATAKANA[j])) 
					{
						sbZenkakuKata.append(ZENKAKU_KATAKANA[j]);

						setFlg = true;

						break;
					}
				}
			}

			if(!setFlg) 
			{
				sbZenkakuKata.append(str);
			}

			setFlg = false;
		}

		return sbZenkakuKata.toString();
	}

	/**
	 * ひらがな（全角）をカタカナ（全角）、カタカナ（全角）をひらがな（全角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	private static String convertToFullKataAndFullHira(String arg0) 
	{
		StringBuffer strBuf = new StringBuffer(arg0);

		for(int i = 0; i < strBuf.length(); i++) 
		{
			char code = strBuf.charAt(i);

			if((code >= HIRAGANACODE_1) && (HIRAGANACODE_2 >= code)) 
			{
				strBuf.setCharAt(i, (char)(code - HIRAGANACODE_1 + KATAKANA_1));

			}
			else if((code >= KATAKANA_1) && (KATAKANA_2 >= code)) 
			{
				strBuf.setCharAt(i, (char)(code - KATAKANA_1 + HIRAGANACODE_1));
			}
			else 
			{
				strBuf.setCharAt(i, (char)(code));
			}
		}

		return strBuf.toString();
	}

	/**
	 * カタカナ（半角）をカタカナ（全角）、カタカナ（全角）をカタカナ（半角）に変換します。
	 * <br>
	 * @param arg0 変換する文字列
	 * @return String 変換された文字列
	 */
	private static String convertToFullKataAndHalfKata(String arg0) 
	{
		StringBuffer strBuff = new StringBuffer();

		boolean setFlg = false;

		for(int i=0; i<arg0.length(); i++) 
		{
			String str = arg0.substring(i, i+1);

			for(int k=0; k<HANKAKU_KATAKANA2.length; k++) 
			{
				if(str.equals(HANKAKU_KATAKANA2[k]) && i+2<=arg0.length()) 
				{
					String str2 = arg0.substring(i+1, i+2);

					if("ﾞ".equals(str2)) 
					{
						strBuff.append(ZENKAKU_KATAKANA2[k]);

						i = i + 1;

						setFlg = true;
					}
					else if("ﾟ".equals(str2)) 
					{
						strBuff.append(ZENKAKU_KATAKANA3[k]);

						i = i + 1;

						setFlg = true;
					}

					break;
				}
			}

			if(!setFlg) 
			{
				for(int j=0; j<HANKAKU_KATAKANA.length; j++) 
				{
					if(str.equals(HANKAKU_KATAKANA[j])) 
					{
						strBuff.append(ZENKAKU_KATAKANA[j]);

						setFlg = true;

						break;
					}
				}
			}

			if(!setFlg) 
			{
				for(int j = 0; j < ZENKAKU_KATAKANA.length; j++) 
				{

					str.charAt(0);

					if(str.charAt(0) == ZENKAKU_KATAKANA[j]) 
					{
						strBuff.append(HANKAKU_KATAKANA[j]);

						setFlg = true;

						break;
					}
				}
			}

			if(!setFlg) 
			{
				strBuff.append(str);
			}

			setFlg = false;
		}

		return strBuff.toString();
	}

	/**
	 * 「"」を「""」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String escpTrnToDbl(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		return arg0.replace(SINGLE, DOUBLE);
	}

	/**
	 * 「,」を「",」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String escpTrnToSnglComma(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		return arg0.replace(CONMA, SINGLE + CONMA);
	}

	/**
	 * 「改行コード」を「"改行コード」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String escpTrnToDblKaiCode(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		if(arg0.indexOf(CRLF) > 0) 
		{
			return arg0.replace(CRLF, SINGLE + CRLF);
		}
		else if(arg0.indexOf(CR) > 0) 
		{
			return arg0.replace(CR, SINGLE + CR);
		}
		else 
		{
			return arg0.replace(LF, SINGLE + LF);
		}
	}

	/**
	 * 「"」「,」「改行コード」を「"（対象）」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String escpTrnToDblTrgt(String arg0) 
	{
		String strConv = arg0;

		strConv = escpTrnToDbl(arg0);

		strConv = escpTrnToSnglComma(strConv);

		strConv = escpTrnToDblKaiCode(strConv);

		return strConv;
	}

	/**
	 * 「""」を「"」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String reEscpTrnToSngl(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		return arg0.replace(DOUBLE, SINGLE);
	}

	/**
	 * 「",」を「,」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String reEscpTrnToComma(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		return arg0.replace(SINGLE + CONMA, CONMA);
	}

	/**
	 * 「"改行コード」を「改行コード」に置換します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String reEscpTrnToKaiCode(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		if(arg0.indexOf(CRLF) > 0) 
		{
			return arg0.replace(SINGLE + CRLF, CRLF);
		}
		else if(arg0.indexOf(CR) > 0) 
		{
			return arg0.replace(SINGLE + CR, CR);
		}
		else 
		{
			return arg0.replace(SINGLE + LF, LF);
		}
	}

	/**
	 * 「""」「",」「"改行コード」を「"」を削除します。
	 * <br>
	 * @param arg0 編集する文字列
	 * @return String 編集された文字列
	 */
	public static String reEscpTrnDelSngl(String arg0) 
	{
		if(isNull(arg0)) 
		{
			return arg0;
		}

		String strConv = arg0;

		strConv = reEscpTrnToSngl(strConv);

		strConv = reEscpTrnToComma(strConv);

		strConv = reEscpTrnToKaiCode(strConv);

		return strConv;
	}

	/**
	 * 指定された長さを対象に0を充填します。
	 * <br>
	 * @param arg0 調整する文字列
	 * @param arg1 調整する長さ
	 * @return String 充填後の文字列
	 */
	public static String padNumFormString(String arg0, int arg1) 
	{
		String sTarget = arg0;
		if(isNull(sTarget)) 
		{
			return "";
		}

		if (arg1 <= 0) 
		{
			return "";
		}

		if (sTarget.length() < arg1) 
		{
			StringBuffer buf = new StringBuffer(sTarget);

			int insIdx = 0;

			if (sTarget.startsWith("-")) 
			{
				insIdx = 1;
			}

			for (int i = buf.length(); i < arg1; i++) 
			{
				buf.insert(insIdx, "0");
			}

			sTarget = buf.toString();
		}

		return sTarget;
	}

	/**
	 * リストの要素をカンマ区切りの文字列に変換して返却します。
	 * <br>
	 * @param arg0 変換するリスト文字列
	 * @return String 変換された文字列
	 */
	public static String convListToString(ArrayList<String> arg0) 
	{
		StringBuffer buf = new StringBuffer();

		for (int i = 0; i < arg0.size(); i++) 
		{
			if(isNull(arg0.get(i))) 
			{
				return "";
			}

			if (i > 0) 
			{
				buf.append(",");
			}

			buf.append(arg0.get(i));
		}

		return buf.toString();
	}

	/**
	 * HashMapのキー、要素をカンマ区切りの文字列に変換して返却します。
	 * <br>
	 * @param map 変換するマップ文字列
	 * @return String 変換された文字列
	 */
	public static String convMapToString(HashMap map) 
	{
		Iterator iterator = map.keySet().iterator();

		StringBuffer buf = new StringBuffer();

		// カンマを設定するフラグ
		boolean flg = false;

		while (iterator.hasNext()) 
		{
			// 2回目以降	はカンマを設定
			if (flg) 
			{
				buf.append(",");
			}

			// キーの取得
			String key = (String)iterator.next();

			buf.append(key);			// キー

			buf.append("=");			// =

			buf.append(map.get(key));	// 値

			flg = true;
		}

		return buf.toString();
	}
	
	/**
	 * double型からString型へ正確な形式で変換します。
	 * <br>
	 * @param num String型に変換する文字列
	 * @return String String型に変換された文字列
	 */
	public static String convDoubleToString(double num) 
	{
		BigDecimal bigDecimal = new BigDecimal(num); 

		bigDecimal = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_EVEN);

		return bigDecimal.toString();
	}

	/**
	 * BigDecimal型からString型へ正確な形式で変換します。
	 * <br>
	 * @param num String型に変換する文字列
	 * @return String String型に変換された文字列
	 */
	public static String convDoubleToString(BigDecimal num) 
	{
		BigDecimal bigDecimal = num; 

		bigDecimal = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_EVEN);

		return bigDecimal.toString();
	}
}
