// *****************************************************************************
// *******
//			メインの処理
// *******
// *****************************************************************************

// *****************************************************************************
//		定数、グローバル変数の定義
// *****************************************************************************
var gAccessEdit;
var gAccessScroll;
var gAccessBar;
var gAccessBarTop;
var gAccessBarLeft;
var gAccessBarCorner;
var gXML = getXMLHTTP();														// XMLHttpRequestの取得

// *****************************************************************************
//		デバッグ用ログ出力処理
// *****************************************************************************
var log = function(msg) {														// subroutine
	if(document != null) {														// documentがnullでない場合
		var log = document.getElementById("pAccess_log");						// "pAccess_log"というIDを探す。<DIV>,<SPAN>等にIDを付けて置く
		if(log) {																// IDがあった場合
			log.appendChild(document.createTextNode(msg));						// メッセージを出力
			log.appendChild(document.createElement("BR"));						// 改行を出力
		}
	}
}

// *****************************************************************************
//		XMLHttpRequestの生成
// *****************************************************************************
function getXMLHTTP(){															// function return XMLHttpRequest
	var xml = null;																// 
	try{
		xml = new ActiveXObject("Msxml2.XMLHTTP");								// IEのMSXML2がある場合、MSXML2.XMLHTTPを生成
	}catch(e){																	// 無い場合
		try{
			xml = new ActiveXObject("Microsoft.XMLHTTP");						// IEのMSXMLがある場合、MSXML.XMLHTTPを生成
		}catch(e){																// 無い場合
			xml = null;															// 
		}
	}
	if(!xml && typeof XMLHttpRequest != "undefined" ){							// 上記全て無い場合
		xml = new XMLHttpRequest();												// XMLHttpRequestの生成
	}
	return xml;																	// 生成したXMLHttpRequestを返す
}

// *****************************************************************************
//		テーブルの見出しを作成
// *****************************************************************************
function addTHead(div) {														//
	var tbl  = div.getElementsByTagName("TABLE").item(0);						// 
	var node = copyNodeTree(tbl, filterForTHEAD, null);							//

	node.id          = "pAccessBarTop";											//
	node.className   = "pAccessBarTop";											//
	div.appendChild(node);														//
	gAccessBarTop    = div.getElementsByTagName("TABLE").item(1);
	gAccessBarTop.style.top = gAccessScroll.scrollTop;
}

var filterForTHEAD = function(node) {											//
	if( node.nodeType != 1 ) return true;
	if( (node.tagName == "TBODY" || node.tagName == "TFOOT") )
		return false;
	return true;
}

var copyNodeTree = function(src, filterFunc, nodeFactory) {						//
	var dst = null;
	if (nodeFactory == null) nodeFactory = document;
	if( filterFunc == null || filterFunc(src) == true ) {
		if( src.nodeType == 1 ) {
			dst = nodeFactory.createElement(src.tagName);
			for(var i=0; i < src.attributes.length; i++) {
				var val = src.getAttribute(src.attributes[i].name);
				if( val != null && val != "")
					dst.setAttribute(src.attributes[i].name, val);
			}
			for(var i=0; i < src.childNodes.length; i++) {
				var dstChild = copyNodeTree(src.childNodes[i], filterFunc, nodeFactory);
				if( dstChild != null ) dst.appendChild(dstChild);
			}
		} else if( src.nodeType == 3 )
			dst = nodeFactory.createTextNode(src.data);
	}

	return dst;
}

// *****************************************************************************
//		テーブルの行見出しを作成
// *****************************************************************************
function addRowHead(div) {
	var tbl  = div.getElementsByTagName("TABLE").item(0);						// 
	var node = copyRowNode(tbl, filterForTDATA, null, 0);						//

	node.id          = "pAccessBarLeft";										//
	node.className   = "pAccessBarLeft";										//
	div.appendChild(node);														//
	gAccessBarLeft   = div.getElementsByTagName("TABLE").item(2);
	gAccessBarLeft.style.left = gAccessScroll.scrollLeft;
}

var filterForTDATA = function(node, pos) {
	if( node.nodeType != 1 ) return true;
	if( (node.tagName == "" || node.tagName == "TFOOT") )
		return false;
	if( (node.tagName == "TD" && pos >= 1) 
		|| (node.tagName == "COL" && pos >= 1) 
		|| (node.tagName == "TH" && pos >= 1) )
		return false;
	return true;
}

var copyRowNode = function(src, filterFunc, nodeFactory, pos) {
	var dst = null;
	if( nodeFactory == null ) nodeFactory = document;
	if( filterFunc == null || filterFunc(src, pos) == true ) {
		if( src.nodeType == 1 ) {
			dst = nodeFactory.createElement(src.tagName);
			for(var i=0; i < src.attributes.length; i++) {
				var val = src.getAttribute(src.attributes[i].name);
				if( val != null && val != "")
					dst.setAttribute(src.attributes[i].name, val);
			}
			for(var i=0; i < src.childNodes.length; i++) {
				var dstChild = copyRowNode(src.childNodes[i], filterFunc, nodeFactory, i);
				if( dstChild != null ) dst.appendChild(dstChild);
			}
		} else if( src.nodeType == 3 )
			dst = nodeFactory.createTextNode(src.data);
	}
	return dst;
}

// *****************************************************************************
//		テーブルの角見出しを作成
// *****************************************************************************
function addCornerHead(div) {
	var tbl  = div.getElementsByTagName("TABLE").item(0);						// 
	var node = copyCornerNode(tbl, filterForCornerTHEAD, null, 0);				//

	node.id          = "pAccessBarCorner";										//
	node.className   = "pAccessBarCorner";										//
	div.appendChild(node);														//
	gAccessBarCorner = div.getElementsByTagName("TABLE").item(3);
	gAccessBarCorner.style.top  = gAccessScroll.scrollTop;
	gAccessBarCorner.style.left = gAccessScroll.scrollLeft;
}

var filterForCornerTHEAD = function(node, pos) {
	if( node.nodeType != 1 ) return true;
	if( (node.tagName == "TBODY" || node.tagName == "TFOOT") )
		return false;
	if( (node.tagName == "TH" && pos >= 1) 
		|| (node.tagName == "COL" && pos >= 1) )
		return false;
	return true;
}

var copyCornerNode = function(src, filterFunc, nodeFactory, pos) {
	var dst = null;
	if( nodeFactory == null ) nodeFactory = document;
	if( filterFunc == null || filterFunc(src, pos) == true ) {
		if( src.nodeType == 1 ) {
			dst = nodeFactory.createElement(src.tagName);
			for(var i=0; i < src.attributes.length; i++) {
				var val = src.getAttribute(src.attributes[i].name);
				if( val != null && val != "")
					dst.setAttribute(src.attributes[i].name, val);
			}
			for(var i=0; i < src.childNodes.length; i++) {
				var dstChild = copyCornerNode(src.childNodes[i], filterFunc, nodeFactory, i);
				if( dstChild != null ) dst.appendChild(dstChild);
			}
		} else if( src.nodeType == 3 )
			dst = nodeFactory.createTextNode(src.data);
	}
	return dst;
}

// *****************************************************************************
//		HTMLのBody読み込み終了後に、初期化処理を行う
// *****************************************************************************
var initDocument = function() {													// subroutine
	var tbl;

	try {	
		tbl = document.getElementsByName("SHEET").item(0);						// テーブルを取得
		if( tbl == null ) {
			tbl = document.getElementsByTagName("TABLE");						// テーブルを取得
			for(var i=0; i<tbl.length; i++) {
				if( tbl[i].className == "pAccess" ) {
					tbl = tbl[i];
					break;
				}
			}
		}
	} catch(e) {
		tbl = document.getElementsByTagName("TABLE").item(0);					// テーブルを取得
	}

	tbl.onresize = cellOnScroll;												// テーブルのonResizeイベント時の処理を登録

	gAccessBar = tbl.parentNode;												//
	gAccessScroll = gAccessBar.parentNode;										//
	gAccessEdit = gAccessScroll.parentNode;										//

	gAccessScroll.onscroll = cellOnScroll;										// DIV("pAccessScroll")に、onScrollイベント時の処理を登録
	gAccessScroll.onresize = cellOnScroll;										// DIV("pAccessScroll")に、onResizeイベント時の処理を登録

	addTHead(gAccessBar);														// 常に見出しが先頭に表示されるように登録
	addRowHead(gAccessBar);														// 常に行見出しが先頭に表示されるように登録
	addCornerHead(gAccessBar);													// 常に角見出しが先頭に表示されるように登録
	self.focus()
}

// *****************************************************************************
// *****************************************************************************
// *******
//			イベント処理
// *******
// *****************************************************************************
// *****************************************************************************

// *****************************************************************************
//		イベント生成用
// *****************************************************************************
var makeEventHandler = function(handler) {										// function return handler(ハンドラーの定義)
	return function(evt) {														// 無名関数の定義
		evt = (evt) ? evt : ((window.event) ? window.event : null);				// evtに値がある場合、evtを返す。値が無い場合、window.eventを返す
		if (evt) {																// evtに値がある場合、
			var target = (evt.target) ? evt.target : evt.srcElement;			// evt.targetに値がある場合、evt.targetを。値が無い場合、evt.srcElement
			return handler(evt, target);										// ハンドラーを返す
		}
	}
}

// *****************************************************************************
//		スクロール時の見出し処理
// *****************************************************************************
var cellOnScroll = makeEventHandler(function(evt, target) {						// 
	var tbl;

	switch(target.tagName) {
	case "DIV":
	case "scrollbar":
		gAccessBarTop.style.top     = gAccessScroll.scrollTop;										// 見出しを常に表示する
		gAccessBarLeft.style.left   = gAccessScroll.scrollLeft;										// 行見出しを常に表示する
		gAccessBarCorner.style.top  = gAccessScroll.scrollTop;										// 角見出しを常に表示する
		gAccessBarCorner.style.left = gAccessScroll.scrollLeft;
		break;
	case "TABLE":
		tbl = target.parentElement.childNodes[1];								// 
		tbl.style.top = Math.max(0, tbl.offsetTop - tbl.offsetHeight + 1);
		break;
	default:
	}
});

// *****************************************************************************
// *******
//			プログラムの終了
// *******
// *****************************************************************************

