/**
 * Magic3標準JavaScriptライブラリ
 *
 * JavaScript 1.5
 *
 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
 *
 * @package    Magic3 Framework
 * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
 * @copyright  Copyright 2006-2008 Magic3 Project.
 * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
 * @version    SVN: $Id: m3std.js 698 2008-06-06 13:04:43Z fishbone $
 * @link       http://www.magic3.org
 */
/**
 * 数値入力判断
 *   テキストフィールドを数値のみ入力可能にするために使用(onkeypressイベントに設定)
 * @param event  e			イベント
 * @param bool   isFloat	小数点入力可否
 * @return bool             true=入力可能、false=入力不可
 */
function m3_numericKey(e, isFloat)
{
	if (document.all){	// IE
		code = event.keyCode;
	} else {		// IE以外
		if (e.which == 0x00)
		{
			if (e.keyCode == 0x08) return true;	// バックスペース
			if (e.keyCode == 0x09) return true;	// タブ
			if (e.keyCode == 0x25) return true;	// 左
			if (e.keyCode == 0x27) return true;	// 右
			if (e.keyCode == 0x2e) return true;	// デリート
			return false;
		}
		
		if (e.which == 0x08) return true;
		
		code = e.which;
	}
	
	if (isFloat){	// 小数点入力可能のとき
		if (code == '.'.charCodeAt(0)) return true;
	}
	
	if (code < '0'.charCodeAt(0)) return false;
	if (code > '9'.charCodeAt(0)) return false;
	
	return true;
}
/**
 * 配列のソート
 *
 * @param array 	dataArray		ソート対象配列データ
 * @param int 		fieldIndex		何番目の要素でソートするか(0～)
 * @param int 		order         		ソート方向(0=昇順、1=降順)
 * @return array 				ソート後のデータ
 */
function m3_sortArray(dataArray, fieldIndex, order)
{
	if (!dataArray) return;
	if (order == null || order == 0){	// 昇順
		dataArray.sort(function(a,b){return a[fieldIndex] - b[fieldIndex];});
	} else {	// 降順
		dataArray.sort(function(a,b){return b[fieldIndex] - a[fieldIndex];});
	}
	return dataArray;
}
/**
 * URLからパラメータの連想配列を取得
 *
 * @param string  url			url
 * @return array 				解析後データ
 */
function m3_getUrlParam(url)
{
	var queryParam = new Object;
	var splitUrl = url.split("?", 2);
	var params = splitUrl[1].split('&');
	for(var i = 0; i < params.length; i++){
		var keyValue = params[i].split("=", 2);
		queryParam[keyValue[0]] = keyValue[1];
	}
	return queryParam;
}
/**
 * HTMLタグ属性文字列の解析
 *
 * @param string  str			url
 * @return array 				解析後データ
 */
function m3_splitAttr(str)
{
	var queryParam = new Object;
	if (!str) return queryParam;
	var params = str.split(";");
	for(var i = 0; i < params.length; i++){
		var keyValue = params[i].split(":", 2);
		if (keyValue[0] && keyValue[1]){
			var key = keyValue[0].trim();
			var value = keyValue[1].trim();
			queryParam[key] = value;
		}
	}
	return queryParam;
}
/**
 * テーブルに縦のスクロールバー付加
 *
 *  テーブルの表示領域を指定行数に制限し、テーブルに縦のスクロールバー付加する
 *
 * @param object  object			テーブルオブジェクトまたはテーブルID文字列
 * @param int     viewLineCount 	表示行数(-1のときはスクロールバーなし)
 * @param int     viewTopLineNo 	先頭に表示する行番号(0～)
 * @return なし
 */
function m3_tableWithScrollbar(object, viewLineCount, viewTopLineNo)
{
	var tHeight;		// 表示高さ
	var srcTable;		// テーブルオブジェクト
	
	if(!document.createElement) return;
	if(navigator.userAgent.match('Opera')) return;

	// テーブルのオブジェクトを取得
	if (typeof object == "string"){
		srcTable = document.getElementById(object);
	} else {
		srcTable = object;
	}
	if (!srcTable) return;
	var hasHead = (srcTable.tHead == null) ? false : true;		// ヘッダがあるかどうか
	var hasFoot = (srcTable.tFoot == null) ? false : true;		// フッタがあるかどうか
	
	// データ行数が表示行数よりも少ないときは終了
	var bodyRowCount = srcTable.tBodies[0].rows.length;	// データ行数
	if (viewLineCount < 0 || bodyRowCount <= viewLineCount){
		// テーブルのカラー設定
		m3_tableWithCololor(srcTable);
		return;
	}
	
	// カラム数のエラーチェック
	if (srcTable.tHead.rows[0].cells.length != srcTable.tBodies[0].rows[0].cells.length){
		alert('カラム数にエラーがあります\nヘッダカラム数=' + srcTable.tHead.rows[0].cells.length +
			 ',ボディカラム数=' + srcTable.tBodies[0].rows[0].cells.length);
		return;
	}
	if (hasFoot){
		if (srcTable.tFoot.rows[0].cells.length != srcTable.tBodies[0].rows[0].cells.length){
			alert('カラム数にエラーがあります\nフッタカラム数=' + srcTable.tFoot.rows[0].cells.length +
				 ',ボディカラム数=' + srcTable.tBodies[0].rows[0].cells.length);
			return;
		}
	}
	// カラムの幅をヘッダのカラム幅に合わせる
	for(var i = 0; i < srcTable.tHead.rows[0].cells.length; i++) {
		srcTable.tHead.rows[0].cells[i].style.width = 
		srcTable.tBodies[0].rows[0].cells[i].style.width = 
			(srcTable.tHead.rows[0].cells[i].clientWidth - srcTable.cellPadding * 2)+ 'px';
		if (hasFoot) srcTable.tFoot.rows[0].cells[i].style.width = srcTable.tHead.rows[0].cells[i].style.width;
	}

	// ヘッダ部、フッタ部の高さを退避
	var thHeight = srcTable.tHead.offsetHeight;
	if (hasFoot) var tfHeight = srcTable.tFoot.offsetHeight;

	srcTable.style.width = srcTable.offsetWidth + 'px';
	var tWidth = srcTable.offsetWidth;	// ヘッダ、フッタ、データ領域の幅

	// テーブルを複製、tbodyの中身を削除
	var destTableHead = srcTable.cloneNode(true);
	while (destTableHead.tBodies[0].rows.length) {
		destTableHead.tBodies[0].deleteRow(0);
	}

	// 新規DIV - ヘッダ部用を作成
	var newDivHead = document.createElement('div');
	newDivHead.style.width = tWidth+'px';
	newDivHead.style.height = thHeight+'px';
	newDivHead.style.overflow = 'hidden';
	newDivHead.style.position = 'relative';
	destTableHead.style.position = 'absolute';
	destTableHead.style.left = '0';
	destTableHead.style.top = '0';
	newDivHead.appendChild(destTableHead);
	srcTable.parentNode.insertBefore(newDivHead, srcTable);
	
	// テーブルの複製を作成　ヘッダ部を削除
	var destTableBody = srcTable.cloneNode(true);
	destTableBody.deleteTHead();
	if (hasFoot) destTableBody.deleteTFoot();	// フッタ削除

	// 新規DIV - ボディ部用を作成
	var newDivBody = document.createElement('div');
	newDivBody.style.width = (tWidth+18)+'px';
	newDivBody.style.overflow = 'auto';
	newDivBody.appendChild(destTableBody);
	srcTable.parentNode.insertBefore(newDivBody, srcTable);
	
	// データ表示領域のサイズ設定
	var rowHeight = destTableBody.clientHeight / bodyRowCount;	// データ行の高さ
	tHeight = rowHeight * viewLineCount;
	newDivBody.style.height = tHeight + 'px';
	newDivBody.scrollTop = rowHeight * viewTopLineNo;		// 表示領域の先頭行を設定

	// 新規DIV - フッタ部用を作成
	if (hasFoot){
		// テーブルの複製
		var destTableFoot = srcTable.cloneNode(true);
		while (destTableFoot.tHead.rows.length) {
			destTableFoot.tHead.deleteRow(0);
		}
		while (destTableFoot.tBodies[0].rows.length) {
			destTableFoot.tBodies[0].deleteRow(0);
		}
		
		var newDivFoot = document.createElement('div');
		newDivFoot.style.width = tWidth+'px';
		newDivFoot.style.height = tfHeight+'px';
		newDivFoot.style.overflow = 'hidden';
		newDivFoot.style.position = 'relative';
		destTableFoot.style.position = 'absolute';
		destTableFoot.style.left = '0';
		destTableFoot.style.top = '0';
		newDivFoot.appendChild(destTableFoot);
		srcTable.parentNode.insertBefore(newDivFoot, srcTable);
	}
	
	// 元テーブルを削除
	srcTable.parentNode.removeChild(srcTable);
	
	// テーブルのカラー設定
	m3_tableWithCololor(destTableBody);
}
/**
 * テーブル行のカラー設定
 *
 *  テーブル行の行ごとに色分け、カレント行の色分けのためのクラス設定を行う
 *
 * @param object  object			テーブルオブジェクトまたはテーブルID文字列
 * @return なし
 */
function m3_tableWithCololor(object)
{
	var tableObj;		// テーブルオブジェクト
	
	if (typeof object == "string"){
		tableObj = document.getElementById(object);
	} else {
		tableObj = object;
	}
	// テーブル行のカラー設定
	var tbodies = tableObj.getElementsByTagName("tbody");
	for (var h = 0; h < tbodies.length; h++) {
		var even = false;
		var trs = tbodies[h].getElementsByTagName("tr");
		for (var i = 0; i < trs.length; i++) {
			trs[i].onmouseover=function(){
				this.className += " ruled"; return false
			}
			trs[i].onmouseout=function(){
				this.className = this.className.replace("ruled", ""); return false
			}
			if(even) trs[i].className += " even";
			even = !even;
		}
	}
}
/**
 * カスケードメニューの作成
 *
 *  リストタグ(ul,li)からカスケードメニューを生成する
 *  サブメニューのある項目には、「hassubmenu」クラス名が設定される
 *
 * @param object  obj	トップのulタグのIDまたはオブジェクト自身
 * @return なし
 */
function m3_cascadeMenu(obj)
{
	if (typeof(obj) != "object") obj = document.getElementById(obj);

	var ultags = obj.getElementsByTagName("ul");
	for (var t = 0; t < ultags.length; t++){
		ultags[t].parentNode.getElementsByTagName("a")[0].className = "hassubmenu";
		if (ultags[t].parentNode.parentNode == obj){ //if this is a first level submenu
			ultags[t].style.left = ultags[t].parentNode.offsetWidth+"px"; //dynamically position first level submenus to be width of main menu item
		} else {//else if this is a sub level submenu (ul)
			ultags[t].style.left = ultags[t-1].getElementsByTagName("a")[0].offsetWidth + "px"; //position menu to the right of menu item that activated it
		}
		ultags[t].parentNode.onmouseover = function(){
			this.getElementsByTagName("ul")[0].style.display = "block";
		}
		ultags[t].parentNode.onmouseout = function(){
			this.getElementsByTagName("ul")[0].style.display = "none";
		}
	}
	for (var t = ultags.length -1; t > -1; t--){ //loop through all sub menus again, and use "display:none" to hide menus (to prevent possible page scrollbars
		ultags[t].style.visibility = "visible";
		ultags[t].style.display = "none";
	}
}
/**
 * ソート可能なボックス
 *
 * @param object  object			テーブルオブジェクトまたはテーブルID文字列
 * @param string  childTag			ソート項目のタグ種別
 * @return なし
 */
function m3_sortableBox(object, childTag)
{
	var sortitemhead = 'sortableitem_';		// 項目のid作成用
	var obj;		// 対象オブジェクト
	var tags = ["dl", "div", "li", "span"];
	var children;
	
	if (typeof object == "string"){
		obj = document.getElementById(object);
	} else {
		obj = object;
	}
	if (!obj){
		alert("null object.");
		return;
	}
	// クラスの設定
	obj.className += " sortable-box";
	
	if (childTag){
		children = obj.getElementsByTagName(childTag);
	} else {
		for (var i = 0; i < tags.length; i++){
			children = obj.getElementsByTagName(tags[i]);
			if (children.length > 0) break;
		}
	}
	for (var i = 0; i < children.length; i++){
		children[i].className += " sortable-box-item";
		children[i].id = sortitemhead + i;
	}
}
/**
 * ソート可能ボックスの項目の並び順を取得
 *
 * @param object  object			テーブルオブジェクトまたはテーブルID文字列
 * @param string  childTag			ソート項目のタグ種別
 * @return string					項目の並び順
 */
function m3_getSortableBoxIndex(object, childTag)
{
	var sortitemhead = 'sortableitem_';		// 項目のid作成用
	var obj;		// 対象オブジェクト
	var tags = ["dl", "div", "li", "span"];
	var children;
	var item;
	var items = '';
	var itemno;
	
	if (typeof object == "string"){
		obj = document.getElementById(object);
	} else {
		obj = object;
	}
	if (!obj){
		alert("null object.");
		return;
	}
	if (childTag){
		children = obj.getElementsByTagName(childTag);
	} else {
		for (var i = 0; i < tags.length; i++){
			children = obj.getElementsByTagName(tags[i]);
			if (children.length > 0) break;
		}
	}
	// ヘルパー以外の項目を取得
	for (var i = 0; i < children.length -1; i++){
		item = children[i];
		itemno = item.id.substr(sortitemhead.length);
		items += itemno + ',';
	}
	items = items.substr(0, items.length-1);
	return items;
}
/**
 * 画像サイズのウィンドウを表示
 *
 * @param string  src	画像へのパス
 * @param string  title	ウィンドウタイトル
 * @return なし
 */
function m3_showImagePopup(src, title)
{
	// 画像をロードしてサイズを取得
	var img = new Image();
	img.src = src;

	// 画像のサイズのウィンドウを開く
	var popupWin = window.open(
							"",
							"_blank",
							"width=" + img.width + ",height=" + img.height + ",scrollbars=no,resizable=yes");

	var html = '<html><head>';
	if (title) html += '<title>' + title + '</title>';
	html += '</head>' +
				'<body style="margin:0;pading:0;border:0;">' +
				'<img src="' + img.src + '" width="100%" height="100%" alt="" />' +
			'</body>' +
			'</html>';
	
	// HTML書き出し
 	popupWin.document.open();
 	popupWin.document.write(html);
 	popupWin.document.close();
}
/**
 * 半透明度の設定
 *
 * @param object  elm	半透明化するオブジェクト
 * @param int opacity	半透明度(0～100)
 * @return なし
 */
function m3_setOpacity(elm, opacity){
    if("opacity" in elm.style){
        elm.style.opacity = opacity / 100;
    } else if("MozOpacity" in elm.style) {
        elm.style.MozOpacity = opacity / 100;
    } else if("KHTMLOpacity" in elm.style) {
        elm.style.KHTMLOpacity = opacity / 100;
    } else if("filters" in elm) {
        elm.style.filter = "Alpha(opacity=" + opacity + ")";
    }
}
/**
 * 半透明画像の表示
 *
 * @param event  e			イベント
 * @param string imageUrl	画像URL
 * @return なし
 */
function m3_showImageToolTip(e, imageUrl)
{
	if (document.all) e = event;
	
	var obj = document.getElementById('image_tooltip');
	obj.style.display = 'block';
	obj.style.position = 'absolute';     //positionセット
	var st = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
	if (navigator.userAgent.toLowerCase().indexOf('safari') >= 0) st = 0;
	var leftPos = e.clientX - 100;
	if (leftPos < 0) leftPos = 0;
	obj.style.left = leftPos + 'px';
	obj.style.top = e.clientY - obj.offsetHeight -1 + st + 'px';
	
	var image = document.getElementById('image_tooltip_i');
	image.src = imageUrl;
	
	// 半透明化
	m3_setOpacity(obj, 95);
}
/**
 * 半透明画像を隠す
 *
 * @return なし
 */
function m3_hideImageToolTip()
{
	document.getElementById('image_tooltip').style.display = 'none';
}
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g, "");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/, "");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/, "");
}
String.prototype.startsWith = function(prefix) {
    if (prefix.length > this.length) return false;
    return prefix == this.substring(0, prefix.length);
}
String.prototype.endsWith = function(suffix) {
    if (suffix.length > this.length) return false;
    return suffix == this.slice(~suffix.length + 1);
}

