/************************************************************************
 *		lscomstring.js - 文字列判定・操作関数
 *
 *			Copyright	1999	Shanghai LionSoft & Co., Ltd.
 ***********************************************************************/

/*----------------------------------*/
/*		関数一覧									 */
/*------------------------------------
isLowerCase		- 英小文字か
isUpperCase		- 英大文字か
isLetter				- 英文字か
isDigit				- 数字か
isSpaceChar		- スペース文字か
isAlphabetic		- 英字から成る文字列か
isNumeric			- 数字から成る文字列か
isAlphanumeric	- 英数字から成る文字列か
isInteger			- 整数を表す文字列か
isFloat				- 小数点数を表す文字列か
isDate				- 日付を表す文字列か
isYear				- 年を表す文字列か
isMonth				- 月を表す文字列か
isDay					- 日を表す文字列か
isLeapYear			- うるう年か
isStringInList		- 文字列がリスト中にあるか
trim					- 先行・後続ブランクの除去
stripChars			- 指定文字の除去
formatNumber		- 数値の整形
------------------------------------*/

/************************************************************************
[名前]
		isLowerCase - 英小文字か

[形式]
		function isLowerCase(ch)
		ch		判定する文字

[機能説明]
		文字が英小文字(a-z)かどうか判定する。

[戻り値]
		true / false
************************************************************************/
function isLowerCase(ch)
{
	return ((ch >= "a") && (ch <= "z"));
}

/************************************************************************
[名前]
		isUpperCase - 英大文字か

[形式]
		function isUpperCase(ch)
		ch		判定する文字

[機能説明]
		文字が英大文字(A-Z)かどうか判定する。

[戻り値]
		true / false
************************************************************************/
function isUpperCase(ch)
{
	return ((ch >= "A") && (ch <= "Z"));
}

/************************************************************************
[名前]
		isLetter - 英文字か

[形式]
		function isLetter(ch)
		ch		判定する文字

[機能説明]
		文字が英文字かどうか判定する。

[戻り値]
		true / false
************************************************************************/
function isLetter(ch)
{
	return (isLowerCase(ch) || isUpperCase(ch));
}

/************************************************************************
[名前]
		isDigit - 数字か

[形式]
		function isDigit(ch)
		ch		判定する文字

[機能説明]
		文字が数字(0-9)かどうか判定する。

[戻り値]
		true / false
************************************************************************/
function isDigit(ch)
{
	return ((ch >= "0") && (ch <= "9"));
}

/************************************************************************
[名前]
		isSpaceChar - スペース文字か

[形式]
		function isSpaceChar(ch)
		ch		判定する文字

[機能説明]
		文字がスペース文字(' ', TAB, CR, LF)かどうか判定する。

[戻り値]
		true / false
************************************************************************/
function isSpaceChar(ch)
{
	return (" \t\n\r".indexOf(ch) > -1);
}

/************************************************************************
[名前]
		isAlphabetic - 英字から成る文字列か

[形式]
		function isAlphabetic(strThis)
		strThis		判定する文字列

[機能説明]
		文字列が英字のみで構成されているかどうか、判定する。

[戻り値]
		true / false
************************************************************************/
function isAlphabetic(strThis)
{
	var	ch;

	if (strThis.length == 0)			// 空文字列
		return false;

	for (i = 0; i < strThis.length; i++) {
		ch = strThis.charAt(i);
		if (!isLetter(ch)) {			// 英字でない
			return false;
		}
	}

	return true;
}

/************************************************************************
[名前]
		isNumeric - 数字から成る文字列か

[形式]
		function isNumeric(strThis)
		strThis		判定する文字列

[機能説明]
		文字列が数字のみで構成されているかどうか、判定する。

[戻り値]
		true / false
************************************************************************/
function isNumeric(strThis)
{
	var	ch;

	if (strThis.length == 0)			// 空文字列
		return false;

	for (i = 0; i < strThis.length; i++) {
		ch = strThis.charAt(i);
		if (!isDigit(ch)) {			// 数字でない
			return false;
		}
	}

	return true;
}

/************************************************************************
[名前]
		isAlphanumeric - 英数字から成る文字列か

[形式]
		function isAlphanumeric(strThis)
		strThis		判定する文字列

[機能説明]
		文字列が英数字のみで構成されているかどうか、判定する。

[戻り値]
		true / false
************************************************************************/
function isAlphanumeric(strThis)
{
	var	ch;

	if (strThis.length == 0)			// 空文字列
		return false;

	for (i = 0; i < strThis.length; i++) {
		ch = strThis.charAt(i);
		if (!isLetter(ch) && !isDigit(ch)) {	// 英数字でない
			return false;
		}
	}

	return true;
}

/************************************************************************
[名前]
		isInteger - 整数を表す文字列か

[形式]
		function isInteger(strThis [,fAllowSign])
		strThis		判定する文字列
		fAllowSign	符号文字を許すか(省略時、true)

[機能説明]
		文字列が整数を表すかどうか、判定する。
		先頭の符号文字(+-)と数字のみで構成されている文字列をOKとする。

[戻り値]
		true / false

[例]
		isInteger("1234")			// true
		isInteger("-1234")			// true
		isInteger("-1234", false)	// false
		isInteger("1,234")			// false
************************************************************************/
function isInteger(strThis, fAllowSign)
{
	var	nPosStart	= 0;

	if (fAllowSign == null)				// 引数が省略された
		fAllowSign = true;
	if (fAllowSign) {
		if ((strThis.charAt(0) == "-") || (strThis.charAt(0) == "+"))	// 先頭の符号
			nPosStart = 1;
	}

	return (isNumeric(strThis.substring(nPosStart, strThis.length)));
}

/************************************************************************
[名前]
		isFloat	- 小数点数を表す文字列か

[形式]
		function isFloat(strThis [,fAllowSign])
		strThis		判定する文字列
		fAllowSign	符号文字を許すか(省略時、true)

[機能説明]
		文字列が小数点数を表すかどうか、判定する。
		先頭の符号文字(+-)と数字、単一ピリオドのみで構成されている文字列を
		OKとする。

[戻り値]
		true / false

[例]
		isFloat("1234.0")	// true
		isFloat("-1234")	// true
		isFloat("1,234.0")	// false
************************************************************************/
function isFloat(strThis, fAllowSign)
{
	var	ch;
	var	nCountDigit	= 0;			// 数字桁の数
	var	nCountDot	= 0;			// ピリオドの数
	var	nPosStart	= 0;

	if (fAllowSign == null)				// 引数が省略された
		fAllowSign = true;
	if (fAllowSign) {
		if ((strThis.charAt(0) == "-") || (strThis.charAt(0) == "+"))	// 先頭の符号
			nPosStart = 1;
	}

	for (i = nPosStart; i < strThis.length; i++) {
		ch = strThis.charAt(i);
		if (ch == "." && nCountDot <= 0)		// 最初のピリオド
			nCountDot++;
		else {
			if (isDigit(ch))
				nCountDigit++;
			else				// 数字でない
				return false;
		}
	}
	if (nCountDigit <= 0)				// 数字がなかった
		return false;

	return true;
}

/************************************************************************
[名前]
		isDate - 日付を表す文字列か

[形式]
		function isDate(strThis)
		strThis		判定する文字列

[機能説明]
		YYYYMMDDの形式であり、かつ年・月・日がそれぞれ正当な値であること。
		月ごとの日数、うるう年の判定も行う。

[戻り値]
		true / false

[例]
		isDate("19971112")		// true
		isDate("19971131")		// false
		isDate("20000229")		// true

[改訂履歴]
		97/11/18	parseInt()で基数に10を指定するように変更。
************************************************************************/
function isDate(strThis)
{
	var	strYear, strMonth, strDay;
	var	nYear, nMonth, nDay;

	if (strThis.length != 8 || !isNumeric(strThis))
		return false;

	strYear  = strThis.substring(0, 4);	// 年
	strMonth = strThis.substring(4, 6);	// 月
	strDay   = strThis.substring(6, 8);	// 日

	if (isYear(strYear) && isMonth(strMonth) && isDay(strDay))
		;				// 単体はOK
	else
		return false;

	nYear  = parseInt(strYear, 10);		// 整数に変換
	nMonth = parseInt(strMonth, 10);
	nDay   = parseInt(strDay, 10);

	if (nMonth == 2) {				// 日の関連チェック
		if (nDay > ((isLeapYear(nYear))? 29:28))
			return false;
	}
	else {
		if (nMonth == 4 || nMonth == 6 || nMonth == 9 || nMonth == 11) {
			if (nDay > 30)
				return false;
		}
	}

	return true;
}

/************************************************************************
[名前]
		isYear - 年を表す文字列か

[形式]
		function isYear(strThis)
		strThis		判定する文字列

[機能説明]
		4桁の数字ならOKとする。

[戻り値]
		true / false
************************************************************************/
function isYear(strThis)
{
	return (isInteger(strThis, false) && strThis.length == 4);
}

/************************************************************************
[名前]
		isMonth - 月を表す文字列か

[形式]
		function isMonth(strThis)
		strThis		判定する文字列

[機能説明]
		1から12までの数字であればOKとする。

[戻り値]
		true / false

[改訂履歴]
		97/11/18	parseInt()で基数に10を指定するように変更。
************************************************************************/
function isMonth(strThis)
{
	var	nValue;

	if (!isInteger(strThis, false))			// 整数でない
		return false;

	nValue = parseInt(strThis, 10);		// 数値に変換
	return ((nValue >= 1) && (nValue <= 12));
}

/************************************************************************
[名前]
		isDay - 日を表す文字列か

[形式]
		function isDay(strThis)
		strThis		判定する文字列

[機能説明]
		1から31までの数字であればOKとする。

[戻り値]
		true / false

[改訂履歴]
		97/11/18	parseInt()で基数に10を指定するように変更。
************************************************************************/
function isDay(strThis)
{
	var	nValue;

	if (!isInteger(strThis, false))			// 整数でない
		return false;

	nValue = parseInt(strThis, 10);		// 数値に変換
	return ((nValue >= 1) && (nValue <= 31));
}

/************************************************************************
[名前]
		isLeapYear - うるう年か

[形式]
		function isLeapYear(nYear)
		nYear		年

[機能説明]
		うるう年かどうか判定する。

[戻り値]
		true / false
************************************************************************/
function isLeapYear(nYear)
{
	return ((nYear % 4 == 0) && ((nYear % 100 != 0) || (nYear % 400 == 0)));
}

/************************************************************************
[名前]
		isStringInList - 文字列がリスト中にあるか

[形式]
		function isStringInList(strThis, strList)
		strThis		判定する文字列
		strList		リスト(;で区切って記述)

[機能説明]
		指定の文字列がリスト中にあるかどうか、判定する。

[戻り値]
		true / false

[例]
		isStringInList("JP", "JP;UK;US")	// true
		isStringInList("CH", "JP;UK;US")	// false
************************************************************************/
function isStringInList(strThis, strList)
{
	return ((';' + strList + ';').indexOf(';' + strThis + ';') >= 0);
}

/************************************************************************
[名前]
		trim - 先行・後続ブランクの除去

[形式]
		function trim(strThis)
		strThis		対象文字列

[機能説明]
		先行および後続のスペース文字を除去する。

[戻り値]
		除去後の文字列
************************************************************************/
function trim(strThis)
{
	var	nPosHead, nPosTail;		// 先頭、末尾ポインタ

	nPosHead = nPosTail = -1;
	for (i = 0; i < strThis.length; i++) {		// 先頭から
		if (!isSpaceChar(strThis.charAt(i))) {	// スペースでない
			nPosHead = i;		// 先頭ポインタを記録
			break;
		}
	}
	if (nPosHead < 0)				// スペースのみだった
		return "";

	for (i = strThis.length - 1; i >= nPosHead; i--) {	// 末尾から
		if (!isSpaceChar(strThis.charAt(i))) {	// スペースでない
			nPosTail = i;		// 末尾ポインタを記録
			break;
		}
	}

	return strThis.substring(nPosHead, nPosTail + 1);	// 部分文字列を返す
}

/************************************************************************
[名前]
		stripChars - 指定文字の除去

[形式]
		function stripChars(strThis, strStrip)
		strThis		対象文字列
		strStrip	除去する文字

[機能説明]
		文字列から、指定の文字(複数指定可)をすべて取り除く。

[戻り値]
		除去後の文字列

[例]
		strBar = stripChars(strFoo, ",+");	// +とカンマを除去
************************************************************************/
function stripChars(strThis, strStrip)
{
	var	ch;
	var	strResult	= "";

	for (i = 0; i < strThis.length; i++) {
		ch = strThis.charAt(i);		// 1文字ずつ処理
		if (strStrip.indexOf(ch) < 0)		// 除去する文字に含まれていない
			strResult += ch;		// 結果に連結
	}

	return strResult;
}

/************************************************************************
[名前]
		formatNumber - 数値の整形

[形式]
		function formatNumber(strThisNumber, strFormat)
		strNumber	数値文字列
		strFormat	書式指定

[機能説明]
		書式指定にしたがって数値文字列を編集する。
		Z: 先行0はブランクを詰める
		9: 先行0は0を詰める
		,: カンマ区切り
		.: 小数点
		元の数値文字列は、isFloat()がtrueを返す書式であること(カンマは不可)。

[戻り値]
		整形後の文字列

[例]
		formatNumber("1234",    "Z,ZZZ,ZZ9")	// "    1,234"
		formatNumber("-1234",   "Z,ZZZ,ZZ9")	// "   -1,234"
		formatNumber("1234",    "999999999")	// "000001234"
		formatNumber("-1234",   "999999999")	// "-00001234"
		formatNumber("1234.5",  "Z,ZZZ,ZZ9.99")	// "    1,234.50"
		formatNumber("-1234.5", "Z,ZZZ,ZZ9.99")	// "   -1,234.50"
************************************************************************/
function formatNumber(strThisNumber, strFormat)
{
	var	strNumber, nSign;				// 正規化された値と符号
	var	nDecNumber, nDecFormat;			// 小数点の位置
	var	nPosNumber, nPosFormat;			// 文字ポインタ
	var	chResult;
	var	strResult	= "";

	nSign = (strThisNumber.indexOf("-") < 0)? 1:-1;	// 符号の判定
	strNumber = stripChars(strThisNumber, "+-");	// 符号を除去

	nDecNumber = _getDecimalPoint(strNumber);	// 小数点の位置を求める
	nDecFormat = _getDecimalPoint(strFormat);

	for (nPosFormat = nDecFormat - 1, nPosNumber = nDecNumber - 1;
			nPosFormat >= 0;				// 整数部分の処理
			nPosFormat--) {
		chResult = _formatNumberChar(strNumber, nPosNumber, nSign, strFormat, nPosFormat);
		strResult = chResult + strResult;			// 1桁分を処理
		if (chResult != ',')					// カンマ以外なら
			nPosNumber--;				// 桁を進める
	}

	for (nPosFormat = nDecFormat, nPosNumber = nDecNumber;
			nPosFormat < strFormat.length;		// 小数部分の処理
			nPosFormat++) {
		chResult = _formatNumberChar(strNumber, nPosNumber, nSign, strFormat, nPosFormat);
		strResult += chResult;				// 1桁分を処理
		if (chResult != ',')					// カンマ以外なら
			nPosNumber++;				// 桁を進める
	}

	return strResult;
}

/************************************************************************
[名前]
		_formatNumberChar - 数値1桁分の整形

[形式]
		function _formatNumberChar(strNumber, nPosNumber, nSign,
					strFormat, nPosFormat)
		strNumber	数値文字列
		nPosNumber	処理する文字位置
		nSign		数値の符号
		strFormat	書式指定
		nPosFormat	処理する文字位置

[機能説明]
		数値1桁分を整形して返す。

[戻り値]
		整形後の文字
************************************************************************/
function _formatNumberChar(strNumber, nPosNumber, nSign, strFormat, nPosFormat)
{
	var	chNumber, chFormat;
	var	chResult;

	chFormat = strFormat.charAt(nPosFormat);	// 書式文字
	chNumber = strNumber.charAt(nPosNumber);	// 数値文字

	if (chFormat == '9') {			// 数字あるいは0詰め
		if (chNumber.length > 0)
			chResult = chNumber;	// 数字
		else
			chResult = (nSign < 0 && nPosFormat == 0)? '-':'0';	// 0詰め
	}
	else {
		if (chFormat == 'Z') {		// 数字あるいはブランク詰め
			if (chNumber.length > 0)
				chResult = chNumber;			// 数字
			else
				chResult = (nSign < 0 && nPosNumber == -1)? '-':' ';	// ブランク詰め
		}
		else {							// カンマ、ピリオド
			if (nPosNumber >= 0)
				chResult = chFormat;			// カンマ、ピリオド区切り
			else
				chResult = ' ';				// ブランク詰め
		}
	}

	return chResult;
}

/************************************************************************
[名前]
		_getDecimalPoint - 小数点の位置を返す

[形式]
		function _getDecimalPoint(strNumber)
		strNumber	数値文字列

[機能説明]
		小数点の位置を返す。ない時、末尾にあるものと想定する。

[戻り値]
		小数点の文字位置

[例]
		_getDecimalPoint("1234.5")	// 4
		_getDecimalPoint("1234")	// 4
************************************************************************/
function _getDecimalPoint(strNumber)
{
	var	nPosDecimal;

	nPosDecimal = strNumber.indexOf(".");	// 小数点を探す
	if (nPosDecimal < 0)				// なければ
		nPosDecimal = strNumber.length;		// 末尾を想定する

	return nPosDecimal;
}
