/***************************
* @author		Yoshizaki Taiko
* @copyright	Copyright(c) 2009 Yoshizaki Taiko
* @version		0.0.1, Rev.2009-02-06
****************************/

var mf;
if( !mf ) mf = {};

//デバック用ノード一覧作成
mf.list_nodes = function(obj_s,n)
{
	if( !n ) n = 0;
	if( n>10 ) return;
	
	var str_data = "";
	for(var i=0; i<n; i++){
		str_data += "\t"
	}
	
	switch( obj_s.nodeType ){
	case 1: //ELEMENT_NODE
		str_data += "ELEMENT_NODE ";
		break;
	case 3: //TEXT_NODE
		str_data += "TEXT_NODE ";
		break;
	case 4: //CDATA_SECTION_NODE
		str_data += "CDATA_SECTION_NODE ";
		break;
	case 9: //DOCUMENT_NODE
		str_data += "DOCUMENT_NODE ";
		break;
	case 8: //
		str_data += "COMMENT_NODE ";
		break;
	case 8: //DOCUMENT_FRAGMENT_NODE
		str_data += "DOCUMENT_FRAGMENT_NODE ";
		break;
	case 2: //ATTRIBUTE_NODE
		str_data += "ATTRIBUTE_NODE ";
		break;
	default:
		str_data += obj_s.nodeType+"_NODE ";
	}
	
	if( obj_s.tagName ){
		str_data += "tagName:"+obj_s.tagName+" ";
	}
	
	if( obj_s.id ){
		str_data += "id:"+obj_s.id+" ";
	}
	
	if( obj_s.data ){
		str_data += "data:"+obj_s.data+" ";
	}

	str_data += "childNodes.length:"+obj_s.childNodes.length+"\n";
	
	var emt_c = obj_s.childNodes;
	for(var i=0; i<emt_c.length; i++){
		str_data += list_nodes(emt_c[i],n+1);
	}
	
	return str_data;
}

mf.str_menu_org = "";

//指定オブジェクトのテキストを変更
mf.chg_text = function(obj_li,str_chg)
{
//	alert(list_nodes(obj_li));
	
	var obj_a = obj_li;
	for(var i=0; i<obj_li.childNodes.length; i++){
		var emt_c = obj_li.childNodes;
		if( emt_c[i].tagName && emt_c[i].tagName.toLowerCase() == "a" ){
			obj_a = emt_c[i];
			break;
		}
	}
	
//	alert(obj_a.firstChild.data);
	//テキストデータの保存
	mf.str_menu_org = obj_a.innerHTML;
	//テキストデータの変更
	obj_a.firstChild.data = str_chg;

	//mouseoutイベントの登録
	var restor_text = function(e) {
//		alert("restor_text:"+e.currentTarget.childNodes.length);
		var emt_c = e.currentTarget.childNodes;
		var obj_a = e.currentTarget;
		for(var i=0; i<emt_c.length; i++){
			if( emt_c[i].tagName && emt_c[i].tagName.toLowerCase() == "a" ){
				obj_a = emt_c[i];
				break;
			}
		}
		if( mf.str_menu_org!="" ){
			obj_a.innerHTML = mf.str_menu_org;
		}
		mf.Handler.remove(e.currentTarget, "mouseout", restor_text );

	}
	mf.Handler.add(obj_li, "mouseout", restor_text );
}

mf.obj_menu = new Array();

//サブメニューの表示
mf.show_submanu = function(no,obj_li,str_pos)
{
	if( !mf.obj_menu[no] ){
		mf.obj_menu[no] = new mf.subMenu(obj_li,str_pos);
	}
	mf.obj_menu[no].show();
}

/***************************
* 日付操作モジュール
****************************/
mf.getNowStr = function(str_format, obj_date) {
	if( obj_date==undefined ){
		obj_date = new Date();
	}
	var str_rtn = "";

	for(var i=0; i<str_format.length; i++ ){
		switch( str_format.charAt(i) ){
		case "Y":
			str_rtn += obj_date.getFullYear().toString();
			break;
		case "m": //月0をつける
		case "n":
			var str_m = obj_date.getMonth()+1;
			if( str_format.charAt(i)=="m" && str_m.toString().length==1 ){
				str_m = "0"+str_m;
			}
			str_rtn += str_m;
			break;
		case "d": //日0をつける
		case "j":
			var str_d = obj_date.getDate().toString();
			if( str_format.charAt(i)=="d" && str_d.length==1 ){
				str_d = "0"+str_d;
			}
			str_rtn += str_d;
			break;
		default:
			str_rtn += str_format.charAt(i);
		}
	}
	return str_rtn;
}

mf.addDate = function(obj_opt, obj_date) {
	if( obj_date==undefined ){
		obj_date = new Date();
	}
	if( !obj_opt.year ){
		obj_opt.year = 0;
	}
	if( !obj_opt.month ){
		obj_opt.month = 0;
	}
	if( !obj_opt.date ){
		obj_opt.date = 0;
	}

	var rtn_date = new Date(obj_date.getFullYear()+obj_opt.year,
							obj_date.getMonth()+obj_opt.month,
							obj_date.getDate()+obj_opt.date);
	return rtn_date;
}

/***************************
* 配列操作モジュール
****************************/

mf.searchAry = function(ary_src,data) {
	for(var i=0; i<ary_src.length; i++){
		if( ary_src[i]==data ){
			return i;
		}
	}
	return false;
}

/***************************
* イベントハンドラ操作モジュール
****************************/
mf.Handler = {};

if( document.addEventListener ){
	//DOM準拠のブラウザ
	mf.Handler.add = function(element, eventType, handler) {
		element.addEventListener(eventType, handler, false);
	};

	mf.Handler.remove = function(element, eventType, handler) {
		element.removeEventListener(eventType, handler, false);
	};
} else if( document.attachEvent ){
	//IE5以降
	mf.Handler.add = function(element, eventType, handler) {
		//二重登録禁止
		if( mf.Handler._find(element, eventType, handler) != -1 ) return;

		//ハンドラ関数の代わりに登録する、入れ子型関数
		var wrpHandler = function(e) {
			if( !e ) e = window.event;
			
			//DOMっぽいイベントオブジェクト
			var event = {
				_event: e,			//IEのEventオブジェクト
				type: e.type,		//イベントタイプ
				target: e.srcElement,	//イベントが発生した場所
				currentTarget: element,	//処理を行っている場所
				relatedTarget: e.fromElement? e.fromElement:e.toElement,
				eventPhase: (e.srcElement==element)? 2:3,
				//マウス座標
				clientX: e.clientX, clientY: e.clientY,
				screenX: e.screenX, screenY: e.screenY,
				//キーの状態
				altKey: e.altKey, ctrlKey: e.ctrlKey,
				shiftKey: e.shiftKey, charCode: e.keycode,
				//イベント管理関数
				stopPropagation: function() {this._event.cancelBubble = true;},
				preventDefault: function() {this._event.returnValue = false;}
			}
			//ハンドラ関数を要素のメソッドとして呼び出す
			if( Function.prototype.call ){
				//Function.call()が使える
				handler.call(element, event);
			} else {
				//Function.call()が使えない
				element._currentHandler = handler;
				element._currentHandler(event);
				element._currentHandler = null;
			}
		};
	
		//入れ子型関数を登録
		element.attachEvent("on"+eventType, wrpHandler);
	
		//ハンドラの情報を格納するオブジェクト
		var h = {
			element: element,
			eventType: eventType,
			handler: handler,
			wrpHandler: wrpHandler
		};
	
		//Documentオブジェクトを取得。documentプロパティを持っていなければ
		//elementはDocumentオブジェクト自身
		var d = element.document || element;
		//関連するウインドウ
		var w = d.parentWindow;
	
		//ハンドラとウインドウを関連付ける
		var id = mf.Handler._uid(); //プロパティ名を生成
		if( !w._allHandlers ) w._allHandlers = {};
		w._allHandlers[id] = h;
	
		//ハンドラ情報hを登録したidを要素に関連付ける
		if( !element._handlers ) element._handlers = [];
		element._handlers.push(id);
	
		//ウインドウにonunloadハンドラを登録
		if( !w._onunloadHandlerRegistered ){
			w._onunloadHandlerRegistered = true;
			w.attachEvent("onunload", mf.Handler._removeAllHandlers);
		}
	};

	mf.Handler.remove = function(element, eventType, handler){
		// このハンドラをelement._handlers配列から探す
		var i = mf.Handler._find(element, eventType, handler);
		if( i==-1 ) return; //登録されていなかった
	
		//関連するウインドウを取得
		var d = element.document || element;
		var w = d.parentWindow;

		//このハンドラのid
		var handlerId = element._handlers[i];
		//ハンドラ情報を検索
		var h = w._allHandlers[handlerId];
		//ハンドラの削除
		element.detachEvent("on"+eventType, h.wrpHandler);
		element._handlers.splice(i, 1);
		delete w._allHandlers[handlerId];
	};

	//element._handlers配列を検索してハンドラのインデックスを返す
	mf.Handler._find = function(element, eventType, handler){
		var handlers = element._handlers;
		if( !handlers ) return -1; //登録されていなかった
	
		//関連するウインドウを取得
		var d = element.document || element;
		var w = d.parentWindow;
	
		for(var i=handlers.length-1; i>=0; i--){
			var handlerId = handlers[i];
			var h = w._allHandlers[handlerId];
			//イベントタイプとハンドラ関数が一致すればOK
			if( h.eventType==eventType && h.handler==handler ){
				return i;
			}
		}
		return -1;
	};

	mf.Handler._removeAllHandlers = function(){
		//ウインドウに登録してあるので、thisはイベントが発生したウインドウ
		var w = this;
		//登録した全てのハンドラを削除
		for(id in w._allHandlers){
			var h = w._allHandlers[id];
			h.element.detachEvent("on"+h.eventType, h.wrpHandler);
			delete w._allHandlers[id];
		}
	}

	mf.Handler._counter = 0;
	mf.Handler._uid = function(){ return "h" + mf.Handler._counter++; };
}
/***************************
* 要素のドキュメント座標取得モジュール
****************************/
mf.getAbsoluteX = function(obj_e) {
	var x = 0;
	for(var e=obj_e; e; e=e.offsetParent){
		x += e.offsetLeft;
	}
	for(e=obj_e.parentNode; e && e!=document.body; e=e.parentNode){
		if( e.scrollLeft ) x -= e.scrollLeft;
	}
	return x;
}

mf.getAbsoluteY = function(obj_e) {
	var y = 0;
	for(var e=obj_e; e; e=e.offsetParent){
		y += e.offsetTop;
	}
	for(e=obj_e.parentNode; e && e!=document.body; e=e.parentNode){
		if( e.scrollTop ) y -= e.scrollTop;
	}
	return y;
}
/***************************
* ウインドウの位置情報取得モジュール
****************************/
mf.win = {};

if( window.screenLeft ){ //IEなど
	//スクリーン上でのウインドウの位置
	mf.win.getWindowX = function() { return window.screenLeft; }
	mf.win.getWindowY = function() { return window.screenTop; }
} else if( window.screenX ){ //Firefoxなど
	mf.win.getWindowX = function() { return window.screenX; }
	mf.win.getWindowY = function() { return window.screenY; }
}

if( window.innerWidth ){ //IE以外
	//ブラウザの表示領域
	mf.win.getViewportWidth = function() { return window.innerWidth; }
	mf.win.getViewportHeight = function() { return window.innerheight; }
	//スクロールバーの位置
	mf.win.getHorizontalScroll = function() { return window.pageXOffset; }
	mf.win.getVerticalScroll = function() { return window.pageYOffset; }
}
else if(document.documentElement && document.documentElement.clientWidth) {
	//DOCTYPEを指定したIE6
	mf.win.getViewportWidth = function() { return document.documentElement.clientWidth; }
	mf.win.getViewportHeight = function() { return document.documentElement.clientHeight; }
	mf.win.getHorizontalScroll = function() { return document.documentElement.scrollLeft; }
	mf.win.getVerticalScroll = function() { return document.documentElement.scrollTop; }
}
else if(document.body.clientWidth) {
	//DOCTYPEを指定しないIE4,5,6
	mf.win.getViewportWidth = function() { return document.body.clientWidth; }
	mf.win.getViewportHeight = function() { return document.body.clientHeight; }
	mf.win.getHorizontalScroll = function() { return document.body.scrollLeft; }
	mf.win.getVerticalScroll = function() { return document.body.scrollTop; }
}

//ドキュメントの大きさ
if( document.documentElement && document.documentElement.scrollWidth ){ 
	mf.win.getDocumentWidth = function() { return document.documentElement.scrollWidth; }
	mf.win.getDocumentHeight = function() { return document.documentElement.scrollHeight; }
}
else if(document.body.scrollWidth) {
	mf.win.getDocumentWidth = function() { return document.body.scrollWidth; }
	mf.win.getDocumentHeight = function() { return document.body.scrollHeight; }
}

/***************************
* メニュー操作クラス
****************************/
/*****************************************************************************
* コンストラクタ
* 書式：  mf.subMenu(obj_li[, str_pos]);
*****************************************************************************/
mf.subMenu = function(obj_li, str_pos) {
	//親メニュー
	this.menu = obj_li;
	//メニューIDの取得 a_1、m_1、s_1 のようになっている
	var ary_id = obj_li.id.split("_");
	if( ary_id.length<2 ) return; //命名エラー
	this.id = ary_id[ary_id.length-1];
	//サブメニューの表示位置
	if( str_pos==undefined ){
		str_pos = "bottom";
	}
	this.position = str_pos;
}

mf.subMenu.prototype.show = function() {

	//メニューバーに被せるアンカー
	var anchor = document.getElementById("a_"+this.id);
	anchor.style.width = (this.menu.offsetWidth-1) + "px";
	anchor.style.height = (this.menu.offsetHeight-1) + "px";
	anchor.style.left = mf.getAbsoluteX(this.menu) + "px";
	anchor.style.top = mf.getAbsoluteY(this.menu) + "px";
	//サブメニュー本体
	var sub = document.getElementById("s_"+this.id);
	//サブメニューの表示位置
	switch(this.position){
	case "left":
		sub.style.left = (parseInt(this.menu.offsetWidth) + parseInt(anchor.style.left)) + "px";
		sub.style.top = anchor.style.top;
		break;
	case "bottom":
	default:
		sub.style.left = anchor.style.left;
		sub.style.top = (parseInt(this.menu.offsetHeight) + parseInt(anchor.style.top)) + "px";
		break;
	}

	anchor.style.visibility = "visible";
	sub.style.visibility = "visible";
//	anchor.style.background-color = this.menu.style.background-color;

	var a_mouseout = function(e) {
//		if( e.target==e.currentTarget ){
			//マウスの位置
			var m_x = e.clientX + mf.win.getHorizontalScroll();
			var m_y = e.clientY + mf.win.getVerticalScroll();
			//メニューIDの取得
			var ary_id = e.currentTarget.id.split("_");
			if( ary_id.length<2 ) return; //命名エラー
			var id = ary_id[ary_id.length-1];
			//自分の領域
			var left = mf.getAbsoluteX(e.currentTarget);
			var top = mf.getAbsoluteY(e.currentTarget);
			var right = left + e.currentTarget.offsetWidth-1;
			var bottom = top + e.currentTarget.offsetHeight-1;
			//自分の領域の外なら処理
			//注）IEでマウス位置と領域の座標が2ずれる。対策として左と上に2加える
			if( m_x<left+2 || right<m_x || m_y<top+2 || bottom<m_y ){
				//サブメニューの領域
				var obj_c = document.getElementById("s_"+id);
				left = mf.getAbsoluteX(obj_c);
				top = mf.getAbsoluteY(obj_c);
				right = left + obj_c.offsetWidth-1;
				bottom = top + obj_c.offsetHeight-1;
	//		alert("a_mouseout m_x:"+m_x+" left:"+left+",right:"+right+" m_y:"+m_y+" top:"+top+",bottom:"+bottom);
				//サブメニューの領域の外なら処理
				//注）IEでマウス位置と領域の座標が2ずれる。対策として左に2加える
				if( m_x<left+2 || right<m_x || m_y<top || bottom<m_y ){

//					e.currentTarget.style.background-color = "";
					e.currentTarget.style.visibility = "hidden";
					obj_c.style.visibility = "hidden";
					e.stopPropagation();

					mf.Handler.remove(e.currentTarget, "mouseout", a_mouseout );
					mf.Handler.remove(obj_c, "mouseout", m_mouseout );
				}
			}
//		}
	}
	mf.Handler.add(anchor, "mouseout", a_mouseout );

	var m_mouseout = function(e) {
//		if( e.target==e.currentTarget ){
			//マウスの位置
			var m_x = e.clientX + mf.win.getHorizontalScroll();
			var m_y = e.clientY + mf.win.getVerticalScroll();
			//メニューIDの取得
			var ary_id = e.currentTarget.id.split("_");
			if( ary_id.length<2 ) return; //命名エラー
			var id = ary_id[ary_id.length-1];
			//自分の領域
			var left = mf.getAbsoluteX(e.currentTarget);
			var top = mf.getAbsoluteY(e.currentTarget);
			var right = left + e.currentTarget.offsetWidth-1;
			var bottom = top + e.currentTarget.offsetHeight-1;
			//自分の領域の外なら処理
			//注）IEでマウス位置と領域の座標が2ずれる。対策として左と上に2加える
			if( m_x<left+2 || right<m_x || m_y<top+2 || bottom<m_y ){
				//アンカーの領域
				var obj_p = document.getElementById("a_"+id);
				left = mf.getAbsoluteX(obj_p);
				top = mf.getAbsoluteY(obj_p);
				right = left + obj_p.offsetWidth-1;
				bottom = top + obj_p.offsetHeight-1;
				//アンカーの領域の外なら処理
				if( m_x<left+2 || right<m_x || m_y<top+2 || bottom+2<m_y ){

//		alert("m_mouseout m_x:"+m_x+" left:"+left+",right:"+right+" m_y:"+m_y+" top:"+top+",bottom:"+bottom);
//					obj_p.style.background-color = "";
					e.currentTarget.style.visibility = "hidden";
					obj_p.style.visibility = "hidden";
					e.stopPropagation();

					mf.Handler.remove(obj_p, "mouseout", a_mouseout );
					mf.Handler.remove(e.currentTarget, "mouseout", m_mouseout );
				}
			}
//		}
	}
	mf.Handler.add(sub, "mouseout", m_mouseout );
	
}

mf.subMenu.prototype.hide = function() {

	var anchor = document.getElementById("a_"+this.id);
	anchor.style.visibility = "hidden";
	var sub = document.getElementById("s_"+this.id);
	sub.style.visibility = "hidden";

}

/***************************
* HTTPリクエストクラス
****************************/

//XMLHttpRequest生成関数のリスト
mf.Http = {};
mf.Http._factories = [
	function() { return new XMLHttpRequest(); },
	function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
	function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
];
//ファクトリ関数保存用
mf.Http._factory = null;

/*****************************************************************************
* コンストラクタ  XMLHttpRequestオブジェクトの生成
* 書式：  mf.HttpRequest( void );
*
*****************************************************************************/
mf.HttpRequest = function() {
	//既に動作するファクトリ関数があるならそれを返す
	if( mf.Http._factory != null ) return mf.Http._factory();
	//動作するファクトリ関数を探す
	for(var i=0; i<mf.Http._factories.length; i++){
		try{
			var factory = mf.Http._factories[i];
			var request = factory();
			if( request!=null ){
				mf.Http._factory = factory;
				return request;
			}
		}
		catch(e){
			continue;
		}
	}
	//動作するファクトリ関数が無かった
	mf.Http._factory = function() {
		throw new Error("XMLHttpRequest not supported");
	}
	mf.Http._factory();
}

mf.Http.loadXML = function(str_url, callback, errorHandler) {
	
	//XMLHttpRequestの生成
	var request = new mf.HttpRequest();

	//非同期レスポンス通知イベントハンドラ
	request.onreadystatechange = function() {
		if( request.readyState==4 ){ //サーバからの返信を受信完了
			if( request.status==200 ){ //成功
				callback(mf.Http.getXML(request));
			} else {
				if( errorHandler ){
					errorHandler(request.status, request.statusText);
				} else {
//					callback(null);
				}
			}
		}
	}
	//HTTPリクエストの作成
	request.open("GET",str_url);
	request.send(null);
}

mf.Http.getXML = function(request) {
	//レスポンスのコンテントタイプ
//	switch(request.getResponseHeader("Content-Type")){
//	case "text/xml":
//	case "application/xml":
		//DOMにパースしたXMLを返す
		if( typeof DOMParser != "undefined" ){
			//FireFox等のMojilla系用　但しFireFox3.0.5はresponseXMLで大丈夫
			return (new DOMParser()).parseFromString(request.responseText,"application/xml");
		} else {
			return request.responseXML;
		}
//		break;
//	}
}

//テキスト又はCDATAセクションノードがあればその内容を返す
mf.Http._getTextNodeData = function(element) {
//			alert(element.tagName);
	var emt_c = element.childNodes;
	var str_data = "";
	for(var i=0; i<emt_c.length; i++){
		switch( emt_c[i].nodeType ){
		case 3: //TEXT_NODE
		case 4: //CDATA_SECTION_NODE
			str_data += emt_c[i].data;
		}
	}
	return str_data;
}

// //テキストノードがあればその内容を変更する
// mf.Http._setTextNodeData = function(element,str_data) {
// //			alert(element.tagName);
//	var emt_c = element.childNodes;
//	for(var i=0; i<emt_c.length; i++){
//		if( emt_c[i].nodeType==3 ){ //TEXT_NODE
//			emt_c[i].data = str_data;
//			break;
//		}
//	}
// }

/***************************
* スタイルシート操作クラス
****************************/
/*****************************************************************************
* コンストラクタ
* 書式：  mf.Css( mix f );
*
* @param    f		スタイルシートの順番又はファイル名
*****************************************************************************/
mf.Css = function(f) {
	//プロパティ
	this.css = {};	//スタイルシート

	if( typeof f == "number" ){
		this.css = document.styleSheets[f];
	} else {
		for( i=0; i<document.styleSheets.length; i++ ){
			var ary_ele = document.styleSheets[i].href.split("/");
			if( ary_ele[ary_ele.length-1] == f ){
				this.css = document.styleSheets[i];
				break;
			}
		}
	}
};

//ルール配列を返す
mf.Css.prototype.getRules = function() {
	//cssRulesはW3C、rulesはIEのプロパティ
	return this.css.cssRules? this.css.cssRules:this.css.rules;
};

//ルールを返す
mf.Css.prototype.getRule = function(s) {
	var rules = this.getRules();
	if( !rules ) return null;
	//sに数値が指定されていたら、そのインデックスのルールを返す
	if( typeof s == "number" ) return rules[s];
	
	//sはセレクタ
	//ルールを最後から探す
	s = s.toLowerCase();
	for(var i=rules.length-1; i>=0; i--){
		if( rules[i].selectorText.toLowerCase() == s ){
			return rules[i];
		}
	}
	return null;
};

//ルールのCSS2Propertiesオブジェクトを返す
//インデックス番号又はセレクタで指定
mf.Css.prototype.getStyles = function(s) {
	var rule = this.getRule(s);
	if( rule && rule.style ) return rule.style;
	return null;
};

//ルールのスタイルテキストを返す
mf.Css.prototype.getStyleText = function(s) {
	var rule = this.getRule(s);
	if( rule && rule.style && rule.style.cssText ) return rule.style.cssText;
	return "";
};

//ルールをスタイルシートに挿入する
mf.Css.prototype.insertRule = function(selector, styles, n) {
	//追加位置の指定が無ければ、最後に追加
	if( n==undefined ){
		var rules = this.getRules();
		n = rules.length;
	}
	
	if( this.css.insertRule ){
		//W3C API
		this.css.insertRule(selector+"{"+styles+"}", n);
	} else if( this.css.addRule ){
		//IE API
		this.css.addRule(selector, styles, n);
	}
};

//スタイルシートを削除する
mf.Css.prototype.deleteRule = function(s) {
	//sの指定が無ければ、最後をインデックスとする
	if( s==undefined ){
		var rules = this.getRules();
		s = rules.length-1;
	}
	
	//sがセレクタなら、インデックスを探す
	if( typeof s != "number" ){
		s = s.toLowerCase();
		for(var i=rules.length-1; i>=0; i--){
			if( rules[i].selectorText.toLowerCase() == s ){
				s = i;
				break;
			}
		}
		if( i==-1 ) return;
	}
	if( this.css.deleteRule ){
		//W3C API
		this.css.deleteRule(s);
	} else if( this.css.removeRule ){
		//IE API
		this.css.removeRule(s);
	}
};

