// JavaScript Document

/*
 * Script: StringExtend.js
 *		String拡張
 *
 * Property:
 *	getByteLength	- 文字列バイト長取得
 *	isInput			- 入力されているかのチェック
 *	isNumStr		- 数字かどうかのチェック
 *	isHanKana		- 半角カナかどうかのチェック
 *	isZen			- 全角かどうかのチェック
 *	isZenKana		- 全角カナかどうかのチェック
 *	isDate			- 日付かどうかのチェック
 *	isTelFormat		- 電話番号かどうかのチェック
 *	isMobileFormat	- 携帯電話番号かどうかのチェック
 *	isZipFormat		- 郵便番号かどうかのチェック
 *	isMailFormat	- メールアドレスかどうかのチェック
 *	trim			- 文字列前後のスペースを詰める
 *	clean			- 文字列中の2文字以上のスペースを1文字のスペースへ変換し
 *					  文字列前後のスペースを詰める
 *	addZero			- Zero補完
 *	cnvComma		- カンマ編集
 *	s2Num			- 文字列→数値 変換
 *	z2hAscii		- 全角→半角 ASCII変換
 *	h2zAscii		- 半角→全角 ASCII変換
 *	z2hKana			- 全角→半角 カタカナ変換
 *	h2zKana			- 半角→全角 カタカナ変換
 *	z2h				- 全角→半角 変換
 *	h2z				- 半角→全角 変換
 *	cnvNormal		- 標準変換(半角→全角 カタカナ変換／全角→半角 ASCII変換)
 *
 */

function StringExtend() {

	function ConvMap() {
		this.map1 = {};
		this.map2 = {};
	}

	ConvMap.prototype = {
		add : function(s1, s2) {
			if(!this.map1[s1]) { this.map1[s1] = s2; }
			if(!this.map2[s2]) { this.map2[s2] = s1; }
		},

		convert : function(s, reverse) {

			var map 		= !reverse? this.map1 : this.map2;
			var converted	= "";

			for(var i = 0;i < s.length;i++) {
				if(i + 1 < s.length) {
					var c = map[s.substring(i, i + 2)];
					if(c) {
						converted += c;
						i++;
						continue;
					}
				}

				var c = map[s.substring(i, i + 1)];
				if(c) {
					converted += c;
					continue;
				}
				// 変換テーブルに該当無し
				converted += s.substring(i, i + 1);
			}
			return converted;
		},

		test : function(s,reverse) {
			var map 		= !reverse? this.map1 : this.map2;

			for(var i = 0;i < s.length; i++) {
				if(i + 1 < s.length) {
					var c = map[s.substring(i, i + 2)];
					if(c) {
						i++;
						continue;
					}
				}

				var c = map[s.substring(i, i + 1)];
				if(c) {
					continue;
				}
				// 変換テーブルに該当無し
				return false;
			}
			return true;
		}
	};

	/*** 全角-半角 マッピング *****************************/
	/*
	 * ASCII
	 */
	var _asciiMap = new ConvMap();

	_asciiMap.add(" ", "　");
	_asciiMap.add("!", "！");

	// 2重引用符
	//_asciiMap.add("\"", "＂");
	_asciiMap.add("\"", "“");
	_asciiMap.add("\"", "”");

	_asciiMap.add("#", "＃");
	_asciiMap.add("$", "＄");
	_asciiMap.add("%", "％");
	_asciiMap.add("&", "＆");
	_asciiMap.add("'", "’");
	_asciiMap.add("(", "（");
	_asciiMap.add(")", "）");
	_asciiMap.add("*", "＊");
	_asciiMap.add("+", "＋");
	_asciiMap.add(",", "，");
	_asciiMap.add("-", "－");
	_asciiMap.add(".", "．");
	_asciiMap.add("/", "／");
	_asciiMap.add("0", "０");
	_asciiMap.add("1", "１");
	_asciiMap.add("2", "２");
	_asciiMap.add("3", "３");
	_asciiMap.add("4", "４");
	_asciiMap.add("5", "５");
	_asciiMap.add("6", "６");
	_asciiMap.add("7", "７");
	_asciiMap.add("8", "８");
	_asciiMap.add("9", "９");
	_asciiMap.add(":", "：");
	_asciiMap.add(";", "；");
	_asciiMap.add("<", "＜");
	_asciiMap.add("=", "＝");
	_asciiMap.add(">", "＞");
	_asciiMap.add("?", "？");
	_asciiMap.add("@", "＠");
	_asciiMap.add("A", "Ａ");
	_asciiMap.add("B", "Ｂ");
	_asciiMap.add("C", "Ｃ");
	_asciiMap.add("D", "Ｄ");
	_asciiMap.add("E", "Ｅ");
	_asciiMap.add("F", "Ｆ");
	_asciiMap.add("G", "Ｇ");
	_asciiMap.add("H", "Ｈ");
	_asciiMap.add("I", "Ｉ");
	_asciiMap.add("J", "Ｊ");
	_asciiMap.add("K", "Ｋ");
	_asciiMap.add("L", "Ｌ");
	_asciiMap.add("M", "Ｍ");
	_asciiMap.add("N", "Ｎ");
	_asciiMap.add("O", "Ｏ");
	_asciiMap.add("P", "Ｐ");
	_asciiMap.add("Q", "Ｑ");
	_asciiMap.add("R", "Ｒ");
	_asciiMap.add("S", "Ｓ");
	_asciiMap.add("T", "Ｔ");
	_asciiMap.add("U", "Ｕ");
	_asciiMap.add("V", "Ｖ");
	_asciiMap.add("W", "Ｗ");
	_asciiMap.add("X", "Ｘ");
	_asciiMap.add("Y", "Ｙ");
	_asciiMap.add("Z", "Ｚ");
	_asciiMap.add("[", "［");

	// 円記号
	//_asciiMap.add("\\", "＼");
	_asciiMap.add("\\", "￥");

	_asciiMap.add("]", "］");
	_asciiMap.add("^", "＾");
	_asciiMap.add("_", "＿");

	// 単一引用符
	//_asciiMap.add("`", "＇");
	_asciiMap.add("`", "‘");
	_asciiMap.add("`", "’");

	_asciiMap.add("a", "ａ");
	_asciiMap.add("b", "ｂ");
	_asciiMap.add("c", "ｃ");
	_asciiMap.add("d", "ｄ");
	_asciiMap.add("e", "ｅ");
	_asciiMap.add("f", "ｆ");
	_asciiMap.add("g", "ｇ");
	_asciiMap.add("h", "ｈ");
	_asciiMap.add("i", "ｉ");
	_asciiMap.add("j", "ｊ");
	_asciiMap.add("k", "ｋ");
	_asciiMap.add("l", "ｌ");
	_asciiMap.add("m", "ｍ");
	_asciiMap.add("n", "ｎ");
	_asciiMap.add("o", "ｏ");
	_asciiMap.add("p", "ｐ");
	_asciiMap.add("q", "ｑ");
	_asciiMap.add("r", "ｒ");
	_asciiMap.add("s", "ｓ");
	_asciiMap.add("t", "ｔ");
	_asciiMap.add("u", "ｕ");
	_asciiMap.add("v", "ｖ");
	_asciiMap.add("w", "ｗ");
	_asciiMap.add("x", "ｘ");
	_asciiMap.add("y", "ｙ");
	_asciiMap.add("z", "ｚ");
	_asciiMap.add("{", "｛");
	_asciiMap.add("|", "｜");
	_asciiMap.add("}", "｝");
	_asciiMap.add("~", "～");

	/*
	 * カタカナ
	 */
    var _kanaMap = new ConvMap();

	_kanaMap.add("。", "｡");
	_kanaMap.add("「", "｢");
	_kanaMap.add("」", "｣");
	_kanaMap.add("、", "､");
	_kanaMap.add("・", "･");
	_kanaMap.add("ヲ", "ｦ");

	_kanaMap.add("ァ", "ｧ");
	_kanaMap.add("ィ", "ｨ");
	_kanaMap.add("ゥ", "ｩ");
	_kanaMap.add("ェ", "ｪ");
	_kanaMap.add("ォ", "ｫ");

	_kanaMap.add("ャ", "ｬ");
	_kanaMap.add("ュ", "ｭ");
	_kanaMap.add("ョ", "ｮ");

	_kanaMap.add("ッ", "ｯ");

	_kanaMap.add("ー", "ｰ");

	_kanaMap.add("ア", "ｱ");
	_kanaMap.add("イ", "ｲ");
	_kanaMap.add("ウ", "ｳ");
	_kanaMap.add("エ", "ｴ");
	_kanaMap.add("オ", "ｵ");

	_kanaMap.add("カ", "ｶ");
	_kanaMap.add("キ", "ｷ");
	_kanaMap.add("ク", "ｸ");
	_kanaMap.add("ケ", "ｹ");
	_kanaMap.add("コ", "ｺ");

	_kanaMap.add("ガ", "ｶﾞ");
	_kanaMap.add("ギ", "ｷﾞ");
	_kanaMap.add("グ", "ｸﾞ");
	_kanaMap.add("ゲ", "ｹﾞ");
	_kanaMap.add("ゴ", "ｺﾞ");

	_kanaMap.add("サ", "ｻ");
	_kanaMap.add("シ", "ｼ");
	_kanaMap.add("ス", "ｽ");
	_kanaMap.add("セ", "ｾ");
	_kanaMap.add("ソ", "ｿ");

	_kanaMap.add("ザ", "ｻﾞ");
	_kanaMap.add("ジ", "ｼﾞ");
	_kanaMap.add("ズ", "ｽﾞ");
	_kanaMap.add("ゼ", "ｾﾞ");
	_kanaMap.add("ゾ", "ｿﾞ");

	_kanaMap.add("タ", "ﾀ");
	_kanaMap.add("チ", "ﾁ");
	_kanaMap.add("ツ", "ﾂ");
	_kanaMap.add("テ", "ﾃ");
	_kanaMap.add("ト", "ﾄ");

	_kanaMap.add("ダ", "ﾀﾞ");
	_kanaMap.add("ヂ", "ﾁﾞ");
	_kanaMap.add("ヅ", "ﾂﾞ");
	_kanaMap.add("デ", "ﾃﾞ");
	_kanaMap.add("ド", "ﾄﾞ");

	_kanaMap.add("ナ", "ﾅ");
	_kanaMap.add("ニ", "ﾆ");
	_kanaMap.add("ヌ", "ﾇ");
	_kanaMap.add("ネ", "ﾈ");
	_kanaMap.add("ノ", "ﾉ");

	_kanaMap.add("ハ", "ﾊ");
	_kanaMap.add("ヒ", "ﾋ");
	_kanaMap.add("フ", "ﾌ");
	_kanaMap.add("ヘ", "ﾍ");
	_kanaMap.add("ホ", "ﾎ");

	_kanaMap.add("バ", "ﾊﾞ");
	_kanaMap.add("ビ", "ﾋﾞ");
	_kanaMap.add("ブ", "ﾌﾞ");
	_kanaMap.add("ベ", "ﾍﾞ");
	_kanaMap.add("ボ", "ﾎﾞ");

	_kanaMap.add("パ", "ﾊﾟ");
	_kanaMap.add("ピ", "ﾋﾟ");
	_kanaMap.add("プ", "ﾌﾟ");
	_kanaMap.add("ペ", "ﾍﾟ");
	_kanaMap.add("ポ", "ﾎﾟ");

	_kanaMap.add("マ", "ﾏ");
	_kanaMap.add("ミ", "ﾐ");
	_kanaMap.add("ム", "ﾑ");
	_kanaMap.add("メ", "ﾒ");
	_kanaMap.add("モ", "ﾓ");

	_kanaMap.add("ヤ", "ﾔ");
	_kanaMap.add("ユ", "ﾕ");
	_kanaMap.add("ヨ", "ﾖ");

	_kanaMap.add("ラ", "ﾗ");
	_kanaMap.add("リ", "ﾘ");
	_kanaMap.add("ル", "ﾙ");
	_kanaMap.add("レ", "ﾚ");
	_kanaMap.add("ロ", "ﾛ");

	_kanaMap.add("ワ", "ﾜ");
	_kanaMap.add("ン", "ﾝ");

	_kanaMap.add("ヴ", "ｳﾞ");

	_kanaMap.add("゛", "ﾞ");
	_kanaMap.add("゜", "ﾟ");

	_kanaMap.add("ヰ", "ｲ");
	_kanaMap.add("ヱ", "ｴ");
	_kanaMap.add("ヮ", "ﾜ");
	_kanaMap.add("ヵ", "ｶ");
	_kanaMap.add("ヶ", "ｹ");


	/*
	 * 文字列バイト長取得
	 */
    String.prototype.getByteLength = function() {
		var cnt = 0;
		for(var i = 0; i < this.length; i++) {
			if(escape(this.charAt(i)).length >= 4) {
				if(this.charAt(i).match(/[｡-ﾟ]/))
					cnt++;
				else
					cnt+=2;
			} else {
				cnt++;
			}
		}
		return cnt;
	}

	/*** チェック関連 *************************************/
	/*
	 * 入力されているかのチェック
	 */
    String.prototype.isInput = function() {
		 return (this.length > 0)
	}

	/*
	 * 数字かどうかのチェック
	 */
    String.prototype.isNumStr = function() {
		return this.match(/[^0-9]/g);
	}

	/*
	 * 半角カナかどうかのチェック
	 */
    String.prototype.isHanKana = function() {
		return this.match(/[｡-ﾟ]/);
	}

	/*
	 * 全角かどうかのチェック
	 */
    String.prototype.isZen = function() {
		var wk = this;

		for(var i = 0; i < wk.length; i++) {
		    // 1文字ずつ文字コードをエスケープし、
			// その長さが4文字以上なら全角
		    var len = escape(wk.charAt(i)).length;
		    if(len >= 4) {
			} else {
				return false;
			}
		}
		return true;
	}

	/*
	 * 全角カナかどうかのチェック
	 */
    String.prototype.isZenKana = function() {
		return _kanaMap.test(this, false);
	}

	/*
	 * 日付かどうかのチェック
	 */
    String.prototype.isDate = function() {

	    // 正規表現による書式チェック 
    	if(!this.match(/^\d{4}\/\d{2}\/\d{2}$/)){
        	return false; 
	    }
	    var vYear = this.substr(0, 4) - 0;
	    var vMonth = this.substr(5, 2) - 1; // Javascriptは、0-11で表現
	    var vDay = this.substr(8, 2) - 0;

    	// 月,日の妥当性チェック 
	    if(vMonth >= 0 && vMonth <= 11 && vDay >= 1 && vDay <= 31) {
	        var vDt = new Date(vYear, vMonth, vDay);
	        if(isNaN(vDt)) {
	            return false;
    	    } else if(vDt.getFullYear() == vYear && vDt.getMonth() == vMonth && vDt.getDate() == vDay) {
	            return true;
    	    }else{ 
        	    return false;
	        } 
    	}else { 
        	return false;
	    }
	}

	/*
	 * 電話番号かどうかのチェック
	 *	ex. 999-9999-9999 or 99-9999-9999
	 */
    String.prototype.isTelFormat = function() {
		return this.match(/^\d{2,3}-\d{3,4}-\d{4}$/);
	}

	/*
	 * 携帯電話番号かどうかのチェック
	 *	ex. 999-9999-9999
	 */
    String.prototype.isMobileFormat = function() {
		return this.match(/^\d{3}-\d{4}-\d{4}$/);
	}

	/*
	 * 郵便番号かどうかのチェック
	 *	ex. 999-9999
	 */
    String.prototype.isZipFormat = function() {
		return this.match(/^\d{3}-\d{4}$/);
	}

	/*
	 * メールアドレスかどうかのチェック
	 */
    String.prototype.isMailFormat = function() {
		return this.match(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/);
	}

	/*** 変換関連 *****************************************/
	/*
	 * 文字列前後のスペースを詰める
	 */
    String.prototype.trim = function() {
//		return this.replace(/^\s+|\s+$/g, '');
		return this.replace(/^[ 　]*/gim, '').replace(/[ 　]*$/gim, '');


	}

	/*
	 * 文字列中の2文字以上のスペースを1文字のスペースへ変換し
	 * 文字列前後のスペースを詰める
	 */
    String.prototype.clean = function() {

		return this.replace(/\s{2,}/g, ' ').trim();
	}

	/*
	 * Zero補完
	 */
    String.prototype.addZero = function(length) {
		var wk			= this;
		var byteLength	= this.getByteLength();
		if(byteLength <= 0) return "";
		for(var i=0; i<length - byteLength; i++)
			wk = "0" + wk;
		return wk;
	}

	/*
	 * カンマ編集
	 */
    String.prototype.cnvComma = function() {
		if(!this.isInput())	return this;
		if(isNaN(this))	return this;

		var re		= new RegExp('([0-9]+)([0-9]+[0-9]+[0-9]+)');
		var aryNum	= this.split('.');

		while(re.test(aryNum[0])) {
			aryNum[0] = aryNum[0].replace(re,'$1,$2');
		}
		if(aryNum.length > 0) {
			return aryNum.join('.');
		} else {
			return aryNum[0];
		}
	}

	/*
	 * 文字列→数値 変換
	 */
	String.prototype.s2Num = function() {
		var val = parseFloat(this.replace(/,/g, ""));
		if(isNaN(val)) return 0;
		return val;
	}

	/*
	 * 全角→半角 ASCII変換
	 */
	String.prototype.z2hAscii = function() {
		return _asciiMap.convert(this, true);
    }

	/*
	 * 半角→全角 ASCII変換
	 */
	String.prototype.h2zAscii = function() {
		return _asciiMap.convert(this, false);
    }

	/*
	 * 全角→半角 カタカナ変換
	 */
	String.prototype.z2hKana = function() {
		return _kanaMap.convert(this, false);
    }

	/*
	 * 半角→全角 カタカナ変換
	 */
	String.prototype.h2zKana = function() {
		return _kanaMap.convert(this, true);
    }

	/*
	 * 全角→半角 変換
	 */
	String.prototype.z2h = function() {
		return this.z2hKana().z2hAscii();
    }

	/*
	 * 半角→全角 変換
	 */
	String.prototype.h2z = function() {
		return this.h2zKana().h2zAscii();
    }

	/*
	 * 標準変換
	 * 半角→全角 カタカナ変換／全角→半角 ASCII変換
	 */
	String.prototype.cnvNormal = function() {
		return this.h2zKana().z2hAscii();
    }
}

StringExtend();

