/**
 * CLIENT
 */

var CLIENT = new Object();

if (navigator.userAgent.match(/windows/i)) {
	CLIENT.os = 'WIN';
} else if (navigator.userAgent.match(/Mac/i)) {
	CLIENT.os = 'MAC';
} else {
	CLIENT.os = false;
}

if (navigator.userAgent.match(/IE/i)) {
	CLIENT.browser = 'IE';
} else if (navigator.userAgent.match(/Safari/i)) {
	CLIENT.browser = 'SF';
} else if (navigator.userAgent.match(/Opera/i)) {
	CLIENT.browser = 'OP';
} else if (navigator.userAgent.match(/Netscape/i)) {
	CLIENT.browser = 'NS';
} else {
	CLIENT.browser = false;
}

/**
 * ELEMENT
 */

// 要素を取得
function fwElm(id)
{
	var elm;
	if (typeof(id) == 'object') {
		elm = id;
	} else if (typeof(id) == 'string' && document.getElementById) {
		elm = document.getElementById(id);
	} else {
		elm = false;
	}
	return elm;
}

// 要素の絶対位置を取得
function fwElmGetPos(elm)
{
	elm = fwElm(elm);
	var pos = new Object();
	
	if (elm) {
		pos.x = elm.offsetLeft;
		pos.y = elm.offsetTop;
		
		while(elm.offsetParent) {
			elm = elm.offsetParent;
			pos.x += elm.offsetLeft;
			pos.y += elm.offsetTop;
		}
	}
	return pos;
}

// 要素にクラスを追加
function fwElmAddClassName(elm, cn)
{
	elm = fwElm(elm);
	var flag = false;
	
	if (elm) {
		if (elm.className) {
			cn = ' ' + cn;
		}
		elm.className += cn;
		flag = true;
	}
	return flag;
}

// クラス指定チェック
function fwElmExistsClassName(elm, cn)
{
	elm = fwElm(elm);
	var flag = false;
	var cn, cns;
	var i, icount;
	
	if (elm && elm.className) {
		cns = elm.className.split(' ');
		icount = cns.length;
		for (i=0; i<icount; i++) {
			if (cns[i] == cn) {
				flag = true;
				break;
			}
		}
	}
	return flag;
}

// クラスを入替
function fwElmReplaceClassName(elm, from_cn, to_cn)
{
	elm = fwElm(elm);
	var flag = false;
	var cn, cns;
	var i, icount;
	
	if (elm && elm.className) {
		cns = elm.className.split(' ');
		cn = '';
		icount = cns.length;
		for (i=0; i<icount; i++) {
			if (i > 0) {
				cn += ' ';
			}
			if (cns[i] == from_cn) {
				cn += to_cn;
				flag = true;
			} else {
				cn += cns[i];
			}
		}
		elm.className = cn;
	}
	return flag;
}

// 要素の透明度を設定
function fwElmStyleOpacity(elm, opacity)
{
	elm = fwElm(elm);
	var opacity_ratio = opacity / 100;
	
	// Internet Explorer
	elm.style.filter = 'alpha(opacity=' + opacity + ')';
	// FireFox
	elm.style.mozOpacity = opacity_ratio;
	// Safari
	elm.style.opacity = opacity_ratio;
}

/**
 * WINDOW
 */

// スクロール座標を取得
function fwWindowScrollPos(e)
{
	var scroll;

	if (CLIENT.browser == 'IE') {
		scroll.x = document.body.scrollLeft;
		scroll.y = document.body.scrollTop;
	} else {
		scroll.x = window.pageXOffset;
		scroll.y = window.pageYOffset;
	}
	return scroll;
}

/**
 * FORM
 */

// フォームの値を取得
function fwFormGetValue(elm)
{
	elm = fwElm(elm);
	var val;

	if (!elm) {
		return false;
	}
	
	if( elm.tagName == "SELECT" ){
		var icount = elm.length;
		for( var i=0; i<icount; i++ ){
			if( elm.options[i].selected ){
				val = elm.options[i].value;
				break;
			}
		}

	}else if( elm.tagName == "TEXTAREA" ){
		val = elm.value;

	}else if( elm.tagName == "INPUT" ){
		switch( elm.type ){
			case "radio":
				if (elm.selected) {
					val = elm.value;
				} else {
					val = '';
				}
				break;

			case "checkbox":
				if (elm.checked) {
					val = elm.value;
				} else {
					val = '';
				}
				break;

			default:
				val = elm.value;
				break;
		}
		
	} else {
		val = null;
	}
	return val;
}

// 優先順位を指定してフォーカス
function fwFormAutoFocus()
{
	var args   = fwFormAutoFocus.arguments;
	var icount = args.length;
	var elm, flag, i, n, val;
	
	if (!document.getElementById) {
		return false;
	}
	
	for (i=0; i<icount; i++) {
		n = i + 1;
		elm = fwElm(args[i]);
		flag = false;
		if (elm) {
			val = fwFormGetValue(elm);
			if (val == null || val == '') {
				flag = true;
			}
			if (flag || icount == n) {
				flag = elm.focus();
				break;
			}
		}
	}
	return flag;
}

// 全てのチェックボックスのON/OFF
function fwFormCheckAll(name, checked)
{
	var flag = false;
	var elms = document.getElementsByName(name);
	var i, icount;
	
	if (elms) {
		icount = elms.length;
		for (i=0; i<icount; i++) {
			if (elms[i] && elms[i].tagName == 'INPUT' && elms[i].type == 'checkbox') {
				elms[i].checked = checked;
			}
		}
		flag = true;
	}
	return flag;
}

// 全てのセレクトオプションのON/OFF
function fwFormSelectAll(elm, selected)
{
	elm = fwElm(elm);
	var option;
	var i, icount;
	var flag = false;
	
	if (elm && elm.tagName == 'SELECT') {
		icount = elm.length;
		for (i=0; i < icount; i++) {
			option = elm.options[i];
			option.selected = selected;
		}
		flag = true;
	}
	return flag;
}

// 選択中のセレクトオプションの移動/削除
function fwFormSelectMove(elm_from, elm_to)
{
	elm_from = fwElm(elm_from);
	if (elm_to) {
		elm_to = fwElm(elm_to);
	}
	var from_option;
	var to_option;
	var i, icount;
	var flag = false;
	
	if (elm_from && elm_from.tagName == 'SELECT') {
		icount = elm_from.length;
		for (i=0; i<icount; i++) {
			from_option = elm_from.options[i];
			if (from_option.selected == true) {
				if (elm_to) {
					to_option = document.createElement('option');
					to_option.text  = from_option.text;
					to_option.value = from_option.value;
					elm_to.appendChild(to_option);
				}
				elm_from.removeChild(elm_from.options[i]);
				i--;
				icount--;
			}
		}
		flag = true;
	}
	return flag;
}

// 全てのセレクトオプションの削除
function fwFormSelectRemove(elm)
{
	elm = fwElm(elm);
	var i;
	var flag = false;
	
	if (elm && elm.tagName == 'SELECT') {
		elm = elm.childNodes;
		i = elm.length - 1;
		for (i=i; i>=0; i--) {
			elm[i].parentNode.removeChild(elm[i]);
		}
		flag = true;
	}
	return flag;
}

// フォームの全送信オブジェクトのNAMEとVALUEを取得
function fwFormSendObj(elm_form)
{
	var elm, elms;
	var item;
	var items = new Array();
	var icount, jcount;
	
	this.getItem = function(name, value)
	{
		var item = new Object();
		item.name  = name;
		item.value = value;
		return item;
	}
	
	if (elm_form && elm_form.tagName == 'FORM') {
	
		elms = elm_form.elements;
		icount = elms.length;
		
		for (i=0; i<icount; i++) {
			elm = elms[i];
			if (elm.tagName == 'INPUT') {
				if (elm.type == 'text' || elm.type == 'password') {
					item = this.getItem(elm.name, elm.value);
					items.push(item);
				} else if (elm.type == 'checkbox' && elm.checked == true) {
					item = this.getItem(elm.name, elm.value);
					items.push(item);
				} else if (elm.type == 'radio' && elm.selected == true) {
					item = this.getItem(elm.name, elm.value);
					items.push(item);
				}
				
			} else if (elm.tagName == 'SELECT') {
				jcount = elm.options;
				for (j=0; j<jcount; j++) {
					if (elm.options[j].selected == true) {
						item = this.getItem(elm.name, elm.options[j].value);
						items.push(item);
					}
				}
				
			} else if (elm.tagName == 'TEXTAREA') {
				item = this.getItem(elm.name, elm.value);
				items.push(item);
			}
		}
	}
	return items;
}

/**
 * TABLE
 */

// TRオブジェクトを取得
function fwTableGetTr(elm)
{
	var elms = new Array;
	var elm_child;
	var i, icount;
	
	icount = elm.childNodes.length;
	for (i=0; i<icount; i++) {
		elm_child = elm.childNodes[i];
		if (elm_child.tagName == 'TR') {
			elms.push(elm_child);
		} else if (elm_child.tagName == 'TBODY') {
			elms = elms.concat(fwTableGetTr(elm_child));
		}
	}
	return elms;
}

/**
 * COOKIE
 */

// 名前からクッキーを読込
function fwCookieRead(name)
{
	var arg  = name + '=';
	var alen = arg.length;
	var str  = document.cookie;
	var slen = str.length;
	var i = 0;
	var j = 0;
	var len, val;

	while (i < slen) {
		j = i + alen;
		if (str.substring(i, j) == arg) {
			len = str.indexOf(";", j);
			if (len == -1) {
				len = str.length;
			}
			val = str.substring(j, len);
			return unescape(val);
		}
		i = str.indexOf(' ', i) + 1;
		if (i == 0) {
			break;
		}
	}
	return false;
}

// クッキーの値を保存
function fwCookieWrite(name, val, expires, path, domain, secure)
{
	var data = name + '=' + escape(val);
	if (expires) {
		expires = '; expires=' + expires;
	} else {
		expires = '';
	}
	if (path) {
		path = '; path=' + path;
	} else {
		path = '';
	}
	if (domain) {
		domain = '; domain=' + domain;
	} else {
		domain = '';
	}
	if (secure) {
		secure = '; domain=' + secure;
	} else {
		secure = '';
	}
	document.cookie = data + expires + path + domain + secure;
	
	return true;
}

// 有効期限からクッキーを削除
function fwCookieRemove(name, path, domain)
{
	var flag = false;
	
	if (fwCookieRead(name)) {
		flag = fwCookieWrite(name, '', fwCookieExpires(-1), path, domain);
	}
	return flag;
}

// クッキー有効期限を取得
function fwCookieExpires(day, hour, minute)
{
	var date = new Date();
	
	if (typeof(hour) == 'undefined') {
		hour = 0;
	}
	if (typeof(minute) == 'undefined') {
		minute = 0;
	}

	date.setDate(date.getDate() + parseInt(day));
	date.setHours(date.getHours() + parseInt(hour));
	date.setMinutes(date.getMinutes() + parseInt(minute));
	
	return date.toGMTString();
}

/**
 * DATE
 */

// 指定された日付の正当性をチェックする
function fwDateCheck(month, day, year)
{
	var date       = new Date(year, month, day);
	var unixtime   = date.getTime();
	var check_date = new Date();
	var flag       = true;
	
	check_date.setTime(unixtime);
	
	if (year != check_date.getFullYear() || month != check_date.getMonth() || day != check_date.getDate()) {
		flag = false;
	}
	return flag;
}

// 指定年月の最終日を取得
function fwDateLastDay(year, month)
{
	var last_day = 31;

	while (!fwDateCheck(month, last_day, year)) {
		last_day--;
	}
	return last_day;
}

// 指定年月の先月を取得
function fwDatePrevMonth(year, month)
{
	var date = new Object;

	if (month == 0) {
		year--;
		month = 11;
	} else {
		month--;
	}
	date.year  = year;
	date.month = month;
	
	return date;
}

// 指定年月の翌月を取得
function fwDateNextMonth(year, month)
{
	var date = new Object;

	if (month == 11) {
		year++;
		month = 0;
	} else {
		month++;
	}
	date.year  = year;
	date.month = month;
	
	return date;
}


// Dateオブジェクトから正規化オブジェクトを取得
function fwDateGetObj(date)
{
	var obj = new Object;
	var y = date.getFullYear();
	var m = date.getMonth() + 1;
	var d = date.getDate();
	var h = date.getHours();
	var i = date.getMinutes();
	var s = date.getSeconds();
	var w = date.getDay();

	if (y < 2000) {
		y += 1900;
	}
	if (m < 10) {
		m = '0' + m;
	}
	if (d < 10) {
		d = '0' + d;
	}
	if (h < 10) {
		h = '0' + h;
	}
	if (i < 10) {
		i = '0' + i;
	}
	if (s < 10) {
		s = '0' + s;
	}

	obj.year   = y;
	obj.month  = m;
	obj.day    = d;
	obj.hour   = h;
	obj.minute = i;
	obj.second = s;
	obj.wday   = w;

	return obj;
}

/**
 * NUM
 */

// 0から255までの10進数を16進数に変換
function fwNumDec2Hex(dec)
{
	var hex;

	if (isNaN(dec) || dec < 0 || dec > 255) {
		dec = 0;
	}
	hex = dec.toString(16);
	hex = hex.toUpperCase();
	if (hex.length == 1) {
		hex = '0' + hex;
	}
	return hex;
}

// 0から255までの16進数を10進数に変換
function fwNumHex2Dec(hex)
{
	var dec;
	var ch1, ch2;

	if (hex.match(/^[0-9a-fA-F]{1,2}$/)) {
		if (hex.length == 2) {
			ch1 = hex.charAt(0);
			ch2 = hex.charAt(1);
		} else {
			ch1 = hex.charAt(0);
			ch2 = hex.charAt(0);
		}
		ch1 = parseInt(ch1, 16);
		ch2 = parseInt(ch2, 16);
		dec = (ch1 * 16) + ch2;
	} else {
		dec = 0;
	}
	return dec;
}

// 数字の桁を揃えた文字列を取得
function fwNumDigit(num, digit)
{
	var bases = new Array();
	var add = '';
	var i, n, s;

	bases[0] = 1;
	digit--;

	for (i=0; i<digit; i++) {
		n = i + 1;
		bases[n] = bases[i] * 10;
	}
	s = bases.length - 1;

	for (i=s; i>0; i--) {
		if (num < bases[i]) {
			add += '0';
		}
	}
	num = add + num;

	return num;
}

// 四捨五入した数値を取得
function fwNumRound(num, prec)
{
	if (typeof(prec) == 'undefined') {
		prec = 0;
	}
	var int_num, dec_num, last;
	var spos, epos;
	
	if (prec > 0) {
		num = num.toString();
		spos = 0;
		epos = num.indexOf('.');
		
		if (epos != -1) {
			int_num = num.substring(spos, epos);
			spos = epos + 1;
			epos = num.length;
			dec_num = num.substring(spos, epos);
			
			if (dec_num.length > prec) {
				last = dec_num.substring(prec, prec + 1);
				last = parseInt(last);
				dec_num = dec_num.substring(0, prec);
				dec_num = parseInt(dec_num);
				if (last >= 5) {
					dec_num++;
				}
				dec_num = dec_num.toString();
			}
			num = int_num + '.' + dec_num;
			num = Number(num);
		}
	} else {
		num = Math.round(num);
	}
	return num;
}

// 数値の基準値を繰り上げ
function fwNumCeil(num, count, prec)
{
	var i, len, dec;
	var base = 1;
	
	for (i=0; i<count; i++) {
		base *= 10;
	}
	
	num = fwNumRound(num / base, prec);
	num = num.toString();
	
	if (prec > 0) {
		pos = num.indexOf('.');
		if (pos != -1) {
			pos++;
			dec = num.substring(pos, num.length);
			len = dec.length;
		} else {
			num += '.';
			len = 0;
		}
		for (i=len; i<prec; i++) {
			num += '0';
		}
	}
	return num;
}

// コンマ付数値を取得
function fwNumAddComma(num)
{
	if(typeof(num) == 'number') {
		num = num.toString();
	}
	var re = /(-?\d+)(\d{3})/;
	
	while (re.test(num)) {
		num = num.replace(re, "$1,$2");
	}
	return num;
}

// コンマ付数値から数値を取得
function fwNumStripComma(num)
{
	var re = /,/g;
	num = num.replace(re, '');
	return Number(num);
}

// バイト表記を取得
function fwNumGetByte(num, prec)
{
	if (num >= 1024) {
		num = fwNumRound(num / 1024, prec);
		if (num >= 1024) {
			num = fwNumRound(num / 1024, prec);
			if (num >= 1024) {
				str = num + 'GB';
			} else {
				str = num + 'MB';
			}
		} else {
			str = num + 'KB';
		}
	} else {
		str = num + 'B';
	}
	return str;
}

/**
 * RAND
 */

// 最小値からの最大値までの中から擬似乱数を取得
function fwRand(min, max)
{
	min = parseInt(min, 10);
	max = parseInt(max, 10);
	return Math.floor(Math.random() * (max - min + 1) + min);
}

// ランダムな英数字を取得
function fwRandGetChar(digit)
{
	var str = '';
	var i, num, ch;
	
	for (i=0; i<digit; i++) {
		num = fwRand(0, 61);
		if (num < 10) {
			ch = num;

		} else if (num < 36) {
			ch = 65 + num - 10;
			ch = ch.toString();
			ch = String.fromCharCode(ch);

		} else {
			ch = 97 + num - 36;
			ch = ch.toString();
			ch = String.fromCharCode(ch);
		}
		str += ch;
	}
	return str;
}

/**
 * STR
 */

// HTMLエンコード
function fwStrHtmlEncode(str)
{
	if (typeof(str) != 'string') {
		text = text.toString();
	}
	str = str.replace(/&/g, "&amp;") ;
	str = str.replace(/"/g, "&quot;") ;
	str = str.replace(/</g, "&lt;") ;
	str = str.replace(/>/g, "&gt;") ;
	str = str.replace(/'/g, "&#39;") ;

	return str;
}

// 文字列の最初と最後の空白、改行を削除
function fwStrTrim(data)
{
	var ch;
	var s, e;
	var len = data.length;
	var re  = new RegExp(" \t\r\n");
	
	for (s=0; s<len; s++) {
		ch = data.substring(s, s + 1);
		if (!ch.match(re)) {
			break;
		}
	}
	for (e=len; e>=0; e--) {
		ch = data.substring(e - 1, e);
		if (!ch.match(re)) {
			break;
		}
	}
	return data.substring(s, e);
}

/**
 * EVENT
 */

// イベントのターゲットノードを取得
function fwEventGetTarget(e)
{
	var target;

	if (e.target) {
		target = e.target;
	} else if(e.srcElement) {
		target = e.srcElement;
	}
	if (target.nodeType == 3) {
		target = target.parentNode;
	}
	return target;
}

// バブリングの停止
function fwEventStopPropagation(e)
{
	if (e.stopPropagation) {
		e.stopPropagation();
	}
	if (window.event) {
		window.event.cancelBubble = true;
	}
	return true;
}

// デフォルトイベントアクションの停止
function fwEventStopDefault(e)
{
	if (e.preventDefault) {
		e.preventDefault();
	}
	if (window.event) {
		window.event.returnValue = false;
	}
	return false;
}

// イベントのページ上座標を取得
function fwEventGetPagePos(e)
{
	var pos = new Object;

	if (CLIENT.browser == 'IE') {
		pos.x = e.clientX + document.body.scrollLeft;
		pos.y = e.clientY + document.body.scrollTop;
	} else {
		pos.x = e.pageX;
		pos.y = e.pageY;
	}
	return pos;
}

// イベントのクライアント領域上座標を取得
function fwEventGetClientPos(e)
{
	var pos = new Object;

	if (CLIENT.browser == 'SF') {
		pos.x = e.clientX - window.pageXOffset;
		pos.y = e.clientY - window.pageYOffset;
	} else {
		pos.x = e.clientX;
		pos.y = e.clientY;
	}
	return pos;
}
