// ----------------
// いわゆる trim 関数
// ----------------

String.prototype.trim = function(){
	return this.replace(/^\s+|\s+$/g, '');
}
// ----------------
// いわゆる htmlspecialchars 関数
// ----------------

String.prototype.escapeHTML = function(){
	return this.replace(/[&"<>']/g, function(c) {
		return {
			'&'  : '&amp;',
			'"'  : '&quot;',
			'<'  : '&lt;',
			'>'  : '&gt;',
			'\'' : '&#039;'
		}[c];
	});
}

// ----------------
// URL エンコード時に問題が発生しそうな文字列のみを対象としたエンコード
// ----------------

String.prototype.partEncode = function(){
	return this.replace(/[/&\+#\\]/g, function(c) {
		return {
			'/'  : '%2F',
			'&'  : '%26',
			'+'  : '%2B',
			'#'  : '%23',
			'\\' : '%5C'
		}[c];
	});
}

// ----------------
// 子要素のみを対象とした getElementsByTagName
// TODO 各ブラウザでの検証が少ない
// ----------------

function getChildrenByTagName(element, tagName){

	var index    = 0;
	var children = new Array();

	var tagName = tagName.toUpperCase();
	var forMax  = element.childNodes.length

	for(var i = 0; i < forMax; i++){

		if(element.childNodes[i].tagName == tagName){
			children[index++] = element.childNodes[i];
		}

	}

	return children;

}

// ----------------
// 要素のみを対象とした childNodes
// ----------------

function getChildTag(obj, getIndex){

	var tagIndex = 0;
	var forMax   = obj.childNodes.length;

	for(var i = 0; i < forMax; i++){

		if(obj.childNodes[i].nodeType == 1){
			if(tagIndex == getIndex){
				return obj.childNodes[i];
			}
			tagIndex++;
		}

	}

	return false;

}

// ----------------
// 要素のみを対象とした childNodes.length
// ----------------

function getChildTagLength(obj){

	var length = 0;
	var forMax = obj.childNodes.length

	for(var i = 0; i < forMax; i++){

		if(obj.childNodes[i].nodeType == 1){
			length++;
		}

	}

	return length;

}

// ----------------
// HTML → javascript への引数を取得する
// キー、イコール、値、改行という、以下のような構造であることが条件
// キー内にイコールを含めることは出来ないが、値内にイコールを含めることは可能
// IE が改行を半角スペースに認識してしまうため、処理を分岐しています
//
// <div id="args">
//     key1=value1
//     key2=value2
// </div>
// ----------------

function readArgs(key){

	var couple = $('args').innerHTML;

	startIndex = couple.indexOf(key);

	if(Prototype.Browser.IE){
		endIndex = couple.indexOf(' ', startIndex);
	}else{
		endIndex = couple.indexOf('\n', startIndex);
	}

	var item = couple.substring(startIndex, endIndex).trim();		// "key=value" の文字列。Opera では、文字列の最後に改行が含まれるため、それを削除する

	var itemSpl       = item.split('=');
	var itemSplLength = itemSpl.length;

	var value = itemSpl[1];

	for(var i = 2; i < itemSplLength; i++){
		value += '=' + itemSpl[i];
	}

	return value;

}

// ----------------
// クッキーからデータを読み込む
// ----------------

function readCookie(key){

	key += '=';

	var value     = '';
	var cookieStr = document.cookie + ';';

	var ofsSt = cookieStr.indexOf(key);

	if (ofsSt != -1){

		var ofsEd = cookieStr.indexOf(';', ofsSt);

		value = unescape(cookieStr.substring(ofsSt + key.length, ofsEd));

	}

	return value;

}

// ----------------
// クッキーへデータを書き込む
// ----------------

function writeCookie(key, value, days, path){

	var expireDays;

	if(days == -1){

		expireDays = 'Thu, 1-Jan-2030 00:00:00 GMT';

	}else{

		expireDays = new Date();

		if(days == null){
			days = 30;
		}

		expireDays.setTime(expireDays.getTime() + (days * 1000 * 60 * 60 * 24));

		expireDays = expireDays.toGMTString();

	}

	var pathStr = '';

	if(path != null){
		pathStr = ';path=' + path;
	}

	document.cookie = key + '=' + escape(value) + ';expires=' + expireDays + pathStr;

}

// ----------------
// impKey1=impValue1&impKey2=impValue2&impKey3=impValue3 のような形式の COOKIE 文字列を受け取り、
// 指定された impKey に対応する impValue を返却する
//
// delimit1 : 上記例の & に対応
// delimit2 : 上記例の = に対応
// ----------------

function readCookieImpValue(key, impKey, delimit1, delimit2){
	return getCookieImpValue(readCookie(key), impKey, delimit1, delimit2);
}

function getCookieImpValue(cookieImp, impKey, delimit1, delimit2){

	var cookieSpl    = cookieImp.split(delimit1);
	var cookieSplLen = cookieSpl.length;

	for(var i = 0; i < cookieSplLen; i++){
		if(cookieSpl[i].indexOf(impKey + delimit2) == 0){
			return cookieSpl[i].split(delimit2)[1];
		}
	}

	return false;

}

// ----------------
// impKey1=impValue1&impKey2=impValue2&impKey3=impValue3 のような形式の COOKIE 文字列を受け取り、
// 指定通りに impKey と impValue を書き換える or 追加する
// impValue が空の場合、impKey と impValue ごと削除される
//
// delimit1 : 上記例の & に対応
// delimit2 : 上記例の = に対応
// headFlag : 書き換えた or 追加した impKey と impValue のペアを先頭に配置するフラグ
// ----------------

function writeCookieImpValue(key, impKey, impValue, headFlag, delimit1, delimit2, days, path){
	writeCookie(key, setCookieImpValue(readCookie(key), impKey, impValue, headFlag, delimit1, delimit2), days, path);
}

function setCookieImpValue(cookieImp, impKey, impValue, headFlag, delimit1, delimit2){

	var cookieSpl    = cookieImp.split(delimit1);
	var cookieSplLen = cookieSpl.length;

	var rtnCookieImp = '';

	var newFlag = true;

	if(cookieImp != ''){
		for(var i = 0; i < cookieSplLen; i++){
			if(cookieSpl[i].indexOf(impKey + delimit2) == 0){
				if(impValue != ''){
					if(headFlag){
						rtnCookieImp = impKey + delimit2 + impValue + rtnCookieImp;
					}else{
						rtnCookieImp = rtnCookieImp + delimit1 + impKey + delimit2 + impValue;
					}
				}
				newFlag = false;
			}else{
				rtnCookieImp += delimit1 + cookieSpl[i];
			}
		}
	}

	if(newFlag){
		if(impValue != ''){
			if(headFlag){
				rtnCookieImp = impKey + delimit2 + impValue + rtnCookieImp;
			}else{
				rtnCookieImp = rtnCookieImp + delimit1 + impKey + delimit2 + impValue;
			}
		}
	}

	if(rtnCookieImp.indexOf(delimit1) == 0){
		rtnCookieImp = rtnCookieImp.substr(1);
	}

	return rtnCookieImp;

}

// ----------------
// 一次元配列を返却する
// ----------------

function returnArray1(sizeX){

	var array = new Array(sizeX);

	return array;

}

function returnArray1(sizeX, initValue){

	var x;

	var array = new Array(sizeX);

	for(x = 0; x < sizeX; x++){
		array[x] = initValue;
	}

	return array;

}

// ----------------
// 二次元配列を返却する
// ----------------

function returnArray2(sizeX, sizeY){

	var x;

	var array = returnArray1(sizeX);

	for(x = 0; x < sizeX; x++){
		array[x] = returnArray1(sizeY);
	}

	return array;

}

function returnArray2(sizeX, sizeY, initValue){

	var x;
	var y;

	var array = returnArray1(sizeX);

	for(x = 0; x < sizeX; x++){

		array[x] = returnArray1(sizeY);

		for(y = 0; y < sizeY; y++){
			array[x][y] = initValue;
		}

	}

	return array;

}

// ----------------
// 受け取った二次元配列のコピーを返却する
// ----------------

function cloneArray2(array){

	var x;
	var y;

	var clone = returnArray1(array.length);

	for(x = 0; x < array.length; x++){

		clone[x] = returnArray1(array[x].length);

		for(y = 0; y < array[x].length; y++){
			clone[x][y] = array[x][y];
		}

	}

	return clone;

}

// ----------------
// 二次元配列同士の足し算
// ----------------

function addArray2(arrayA, arrayB){

	for(y = 0; y < arrayA[0].length; y++){
		for(x = 0; x < arrayA.length; x++){
			arrayA[x][y] += arrayB[x][y];
		}
	}

	return arrayA;

}

// ----------------
// 一次元配列要素全ての足し算
// ----------------

function sumArray1(array){

	var sum = 0;

	for(x = 0; x < array.length; x++){
		sum += array[x];
	}

	return sum;

}

// ----------------
// 二次元配列要素全ての足し算
// ----------------

function sumArray2(array){

	var sum = 0;

	for(y = 0; y < array[0].length; y++){
		for(x = 0; x < array.length; x++){
			sum += array[x][y];
		}
	}

	return sum;

}

// ----------------
// min 以上、max 未満のランダム値を発生させる
// ----------------

function randomInt(min, max){

	return Math.floor(Math.random() * (max - min) + min);

}

function randomFloat(min, max){

	return Math.random() * (max - min) + min;

}

