/* CookieUtil
----------------------------------------------*/
function CookieUtil(){
}

CookieUtil.setCookie = function(key, value, expireDays){
	var str = "";
	var expires = "";
	if (expireDays){
		var date = new Date();
		date.setTime(date.getTime()+(expireDays*24*60*60*1000));
		expires = "; expires=" + date.toGMTString();
	}
	str = key + "=" + value + expires + "; path=/;";
	document.cookie = str;
}

CookieUtil.getCookie = function(key){
	var str = null;
	var a = document.cookie.split(";");
	var keyEq = key + "=";
	for(var i=0; i<a.length; i++){
		var c = a[i];
		while (c.charAt(0)==' ') c = c.substring(1, c.length); // strip white space
		if(c.indexOf(keyEq) == 0){
			str = c.substring(keyEq.length, c.length);
			break;
		}
	}
	return str;
}


CookieUtil.deleteCookie = function(key){
	alert("CookieUtil.deleteCookie");
	CookieUtil.setCookie(key, "" , -1);
}
/* DataLoader
----------------------------------------------*/
function DataLoader(){
	this.xhr;
	this._url = "";
	this._obj = null;
	this._handler = null;
	this._errorHandler = null;
	this._timeoutId;
	this._hasTimedOut = false;
	this._caches = new Object();
	this.responseText = "";
	this.responseXML = "";
}

DataLoader.ReadyState = {0:"uninitialized", 1:"loading", 2:"loaded", 3:"interactive", 4:"complete"};
DataLoader.Status = {0:"Unknown", 200:"Succeed", 403:"Forbidden", 404:"File Not Found", 500:"Internal Server Error", 503:"Service Unavailable"};

var p = DataLoader.prototype;

p._createXhr = function(){
	var xhr = null;
	try{
		xhr = new XMLHttpRequest();
	}catch(e){
		try{
			xhr = new ActiveXObject("Msxml2.XMLHTTP");
		}catch(e){
			try{
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			}catch(e){
				xhr = null;
				// alert("お使いのブラウザでは、このページを正常に表示することができません。\n(XMLHttpRequest has not been created.)");
			}
		}
	}
	if(xhr){
		xhr.onreadystatechange = Util.createDelegate(this, this._checkState);
	}
	return xhr;
}

p._checkState = function(){
	if(this.xhr.readyState == 4){
		if(this.xhr.status == 200) this._onLoad();
		else if(this.xhr.status == 304) this._onCache();
		else this._onError();
	}
}

p._onLoad = function(){
	clearTimeout(this._timeoutId);
	if(this.xhr.responseText == "") _onCache();
	this.responseText = this.xhr.responseText;
	this.responseXML = this.xhr.responseXML;
	var key = (this._url.indexOf("?", 0) > 0) ? this._url.split("?")[0] : this._url;
	var lastModified = this.getResponseHeader("Last-Modified");
	this._caches[key] = {lastModified:lastModified, responseText:this.responseText, responseXML:this.responseXML};
	this._handler.apply(this._obj, [this]);
}
p._onCache = function(){
	clearTimeout(this._timeoutId);
	var key = (this._url.indexOf("?", 0) > 0) ? this._url.split("?")[0] : this._url;
	if(this._caches[key]){
		var cache = this._caches[key];
		this.responseText = cache.responseText;
		this.responseXML = cache.responseXML;
	}
	this._handler.apply(this._obj, [this]);
}
p._onError = function(){
	clearTimeout(this._timeoutId);
	this.abort();
	this.responseText = null;
	this.responseXML = null;
	if(this._errorHandler != null) this._errorHandler.apply(this._obj, [this]);
}
p._onTimeout = function(){
	this._hasTimedOut = true;
	this._onError();
}

p.getStatus = function(){
	var message = (this._hasTimedOut) ? "Connection timed out" : "An error occured";
	message += "readyState: " + this.xhr.readyState + ": " + DataLoader.ReadyState[this.xhr.readyState] + "\n";
	message += this.xhr.status + ": " + DataLoader.Status[this.xhr.status];
	var status = {readyState:this.xhr.readyState, status:this.xhr.status, hasTimedOut:this.hasTimedOut, message:message};
	return status;
}

p.load = function(url, obj, handler, errorHandler){
	this.xhr = this._createXhr();
	if(this.xhr){
		this._url = url;
		this._obj = obj;
		this._handler = handler;
		this._errorHandler = (errorHandler) ? errorHandler : null;
		this._hasTimedOut = false;
		this._timeoutId = Util.setTimeout(this, this._onTimeout, 8000);
		var key = (url.indexOf("?", 0) > 0) ? url.split("?")[0] : url;
		this.xhr.open("GET", url ,true);
		if(this._caches[key] && this._caches[key].lastModified){
			this.setRequestHeader("If-Modified-Since", this._caches[key].lastModified);
		}
		this.xhr.send(null);
	}
}
p.send = function(url, method){
	if(this.xhr){
		// to be implemented
	}
}
p.sendAndLoad = function(){
	if(this.xhr){
		// to be implemented
	}
}

p.abort = function(){
	this.xhr.abort();
}
p.getAllResponseHeaders = function(){
	return this.xhr.getAllResponseHeaders();
}
p.getResponseHeader = function(key){
	return this.xhr.getResponseHeader(key);
}
p.setRequestHeader = function(key, value){
	this.xhr.setRequestHeader(key, value);
}
/* DateEx
----------------------------------------------*/
Date.daysInMonthList = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
Date.getDaysInMonth = function(year, month){
	var days = Date.daysInMonthList[month];
	if(month==1 && Date.isLeapYear(year)) days = 29;
	return days;
}
Date.isLeapYear = function(year){
	var b = false;
	if ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))) b = true;
	return b;
}
// parse yymmdd-hh:mm
Date.parseDateString = function(str){
	var year;
	var month;
	var date;
	var hours = 0;
	var minutes = 0;
	var d, h;
	if(str.indexOf("-") == 7){
		var a = str.split("-");
		d= a[0];
		h = a[1];
		if(h.length == 5){
			var ha = h.split(":");
			hours = parseInt(ha[0], 10);
			minutes = parseInt(ha[1], 10);
		}
	}else{
		d = str;
	}
	year = 2000 + (parseInt(d.substring(0, 2), 10));
	month = (parseInt(d.substring(2, 4), 10)) - 1;
	date = parseInt(d.substring(4, 6), 10);
	return new Date(year, month, date, hours, minutes);
}
var p = Date.prototype;
p.getDaysInMonth = function(){
	return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
}
p.addDate = function(aDate){
	var ms = 1000 * 60 * 60 * 24 * aDate;
	var time = this.getTime();
	this.setTime(time + ms);
}
p.subtractDate = function(aDate){
	var ms = 1000 * 60 * 60 * 24 * aDate;
	var time = this.getTime();
	this.setTime(time - ms);
}
delete p;
/* DateVirtual
----------------------------------------------*/
function DateVirtual(d){
	this.trueDate = new Date(d.getTime());
	this.isDateAhead = (d.getHours() < DateVirtual.hoursMin) ? true : false;
}

DateVirtual.now = new DateVirtual(new Date());
DateVirtual.hoursMin = 4;
DateVirtual.hoursMax = 28;

DateVirtual.setNow = function(aNow){
	DateVirtual.now = new DateVirtual(aNow);
}

var p = DateVirtual.prototype;

p.addDate = function(d){
	this.trueDate.addDate(d);
}
p.subtractDate = function(d){
	this.trueDate.subtractDate(d);
}
// h: 4 - 28
p.setHours = function(h){
	if(h >= 24){
		h -= 24;
		if(!this.isDateAhead) this.trueDate.addDate(1);
	}else if(this.isDateAhead){
		this.trueDate.subtractDate(1);
	}
	this.trueDate.setHours(h);
}
p.setMinutes = function(m){
	if(m > 59) m = 59;
	return this.trueDate.setMinutes(m);
}
p.getFullYear = function(){
	var fullYear = this.trueDate.getFullYear();
	var month = this.trueDate.getMonth();
	if(this.isDateAhead){
		if(this.trueDate.getDate() == 1) --month;
		if(month < 0) --fullYear;
	}	
	return fullYear;
}
p.getMonth = function(){
	var month = this.trueDate.getMonth();
	if(this.isDateAhead){
		if(this.trueDate.getDate() == 1) --month;
		if(month < 0) month = 11;
	}
	return month;
}
p.getDate = function(){
	var date;
	if(this.trueDate.getHours() < 4){
		var d = new Date(this.trueDate.getTime());
		d.subtractDate(1);
		date = d.getDate();
	}else{
		date = this.trueDate.getDate();
	}
	return date;
}
p.getDay = function(){
	var day;
	if(this.trueDate.getHours() < 4){
		var d = new Date(this.trueDate.getTime());
		d.subtractDate(1);
		day = d.getDay();
	}else{
		day = this.trueDate.getDay();
	}
	return day;
}
p.getHours = function(){
	var hours = this.trueDate.getHours();
	if(hours < 4) hours += 24;
	return hours;
}
p.getMinutes = function(){
	return this.trueDate.getMinutes();
}
p.getTime = function(){
	return this.trueDate.getTime();
}

p.clone = function(){
	return new DateVirtual(this.trueDate);
}
p.toString = function(){
	var y = this.getFullYear() - 2000;
	var yy = (y<10) ? "0" + y : y.toString();
	var m = this.getMonth() + 1;
	var mm = (m<10) ? "0" + m : m.toString();
	var d = this.getDate();
	var dd = (d<10) ? "0" + d : d.toString();
	
	var h = this.getHours();
	var hh = (h<10) ? "0" + h : h.toString();
	var n = this.getMinutes();
	var nn = (n<10) ? "0" + n : n.toString();
	
	return (yy + mm + dd + "-" + hh + ":" + nn);
}
/* FlashElement
----------------------------------------------*/
function FlashElement(id, src, width, height){
	this.id = id;
	this.src = src;
	this.width = width;
	this.height = height;
	this.version = "8,0,15,0";
	this.className = "";
	this.style = "";
	this.bgcolor = "#ffffff";
	this.quality = "high";
	this.scale = "showAll";
	this.salign = "LT";
	this.allowScriptAccess = "sameDomain";
	this.flashVars = null;
	this.isPlugin = this._detectPlugin();
}

/*
FlashElement.hasFlashPlugin:
The function is modified version of hasFlashVerssion method of Unobtrusive Flash Objects (UFO) v3.02 by Bobby van der Sluis
UFO is under the CC-GNU LGPL
*/
/*	Unobtrusive Flash Objects (UFO) v3.02 <http://www.bobbyvandersluis.com/ufo/>
	Copyright 2005, 2006 Bobby van der Sluis
	This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/
FlashElement.hasFlashPlugin = function(majorVersion, buildVersion) {
	var reqVersion = parseFloat(majorVersion + "." + buildVersion);
	if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
		var desc = navigator.plugins["Shockwave Flash"].description;
		if (desc) {
			var versionStr = desc.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
			var major = parseInt(versionStr.replace(/^(.*)\..*$/, "$1"));
			var build = parseInt(versionStr.replace(/^.*r(.*)$/, "$1"));
			var flashVersion = parseFloat(major + "." + build);
		}
	}
	else if (window.ActiveXObject) {
		try {
			var flashObj = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			var desc = flashObj.GetVariable("$version");
			if (desc) {
				var versionArr = desc.replace(/^\S+\s+(.*)$/, "$1").split(",");
				var major = parseInt(versionArr[0]);
				var build = parseInt(versionArr[2]);
				var flashVersion = parseFloat(major + "." + build);
			}
		}
		catch(e) {}
	}
	if (typeof flashVersion != "undefined"){
		return (flashVersion >= reqVersion ? true : false); 
	}
	return false;
}

var p = FlashElement.prototype;

p.toString = function(){
    var isMS = (navigator.appName.indexOf ("Microsoft") != -1) ? true : false;
    var str = "";
    if(isMS){
        str += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" type="application/x-shockwave-flash" ';
        str += 'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + this.version + '" ';
		if(this.id != null) str += 'id="' + this.id + '" ';
		str += 'className="' + this.className + '" ';
		str += 'style="' + this.style + '" ';
		str += 'width="' + this.width + '" ';
        str += 'height="' + this.height + '">';
        str += '<param name="movie" value="' + this.src + '" />';
		str += '<param name="src" value="' + this.src + '" />';
		str += '<param name="bgcolor" value="' + this.bgcolor + '" />';
        str += '<param name="quality" value="' + this.quality + '" />';
		str += '<param name="scale" value="' + this.scale + '" />';
		str += '<param name="salign" value="' + this.salign + '" />';
		str += '<param name="allowScriptAccess" value="' + this.allowScriptAccess + '" />';
        if(this.flashVars != null) str += '<param name="flashvars" value="' + this.flashVars + '" />';
        str += '</object>';
    }
    else{
        str += '<embed src="' + this.src + '" ';
        str += 'width="' + this.width + '" ';
        str += 'height="' + this.height + '" ';
		if(this.id != null) str += 'id="' + this.id + '" ';
		str += 'name="' + this.id + '" ';
		str += 'className="' + this.className + '" ';
		str += 'style="' + this.style + '" ';
		str += 'bgcolor="' + this.bgcolor + '" ';
		str += 'quality="' + this.quality + '" ';
		str += 'scale="' + this.scale + '" ';
		str += 'salign="' + this.salign + '" ';
		str += 'allowScriptAccess="' + this.allowScriptAccess + '" ';
		if (this.flashVars != null)  str += 'flashvars="' + this.flashVars + '" ';
        str += 'type="application/x-shockwave-flash" ';
        str += 'pluginspage="http://www.macromedia.com/go/getflashplayer">';
        str += '</embed>';
    }
    return str;
}

p.write = function(){
	if(this.isPlugin){
		var str = this.toString();
		document.write(str);
	}
}

p._detectPlugin = function(){
	var b = false;
	var plugin;
	if(navigator.plugins && navigator.mimeTypes.length){
		plugin = navigator.plugins["Shockwave Flash"];
		if(plugin && plugin.description) {
			b = true;
		}
	}else if (window.ActiveXObject){
		try {
		   plugin = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
		   b = true;
		}catch (e) {
			// do nothing
		}
	}
	return b;
}

delete p;
/* NodeUtil
----------------------------------------------*/
function NodeUtil(){
}

NodeUtil.Element = 1;
NodeUtil.Attribute = 2;
NodeUtil.Text = 3;
NodeUtil.CDATASection = 4;
NodeUtil.EntityReference = 5;
NodeUtil.Entity = 6;
NodeUtil.ProcessingInstruction = 7;
NodeUtil.Comment = 8;
NodeUtil.Document = 9;
NodeUtil.DocumentType = 10;
NodeUtil.Notation = 11;

NodeUtil.createIndex = function(node, aIndexOn){
	if(node.nodeType == NodeUtil.ProcessingInstruction) node = node.nextSibling; // fix IE6 prpblem
	if(node.hasChildNodes() == true){
		var index = {};
		if(node.nodeType == NodeUtil.Element || node.nodeType == NodeUtil.Document) node.index = index; // IE6 does not allow this
		var childNodes = node.childNodes;
		var checker = {};
		for (var i=0; i< childNodes.length; ++i){
			var childNode = childNodes[i];
			if(childNode.nodeType == NodeUtil.Element || childNode.nodeType == NodeUtil.Document){
				if(aIndexOn == undefined || childNode.getAttributeNode(aIndexOn) != undefined){
					var indexKey = (aIndexOn == undefined) ? childNode.nodeName : childNode.getAttributeNode(aIndexOn).value;
					if(checker[indexKey] == undefined){
						index[indexKey] = childNode;
						checker[indexKey] = {num:0, origin:childNode};
					}else{
						var currentCheckerObj = checker[indexKey];
						if (currentCheckerObj.num == 0) {
							index[indexKey + "_0"] = currentCheckerObj.origin;
							delete index[indexKey];
						}
						currentCheckerObj.num++;
						index[indexKey + "_"  + currentCheckerObj.num] = childNode;
					}
				}
				NodeUtil.createIndex(childNode, aIndexOn);
			}else if(childNode.nodeType == NodeUtil.Text){
				index["innerText"] = childNode.nodeValue;
			}else if(childNode.nodeType == NodeUtil.CDATASection){
				index["cdata"] = childNode.nodeValue;
			}
		}
	}
}

NodeUtil.getIndex = function(node, isRecursive, indexOn){
	if(node.nodeType == NodeUtil.ProcessingInstruction) node = node.nextSibling; // fix IE prpblem
	var index = {};
	var isIndexOn = !(indexOn == undefined && indexOn == null);
	if(node.hasChildNodes() == true){
		var childNodes = node.childNodes;
		var checkers = {};
		for (var i=0; i< childNodes.length; ++i){
			var childNode = childNodes[i];
			if(childNode.nodeType == NodeUtil.Element || childNode.nodeType == NodeUtil.Document){
				if(!isIndexOn || childNode.getAttributeNode(indexOn) != undefined){
					var indexKey = (indexOn && childNode.getAttributeNode(indexOn)) ? childNode.getAttributeNode(indexOn).value : childNode.nodeName;
					if(!checkers[indexKey]){
						index[indexKey] = childNode;
						checkers[indexKey] = {keyStem:indexKey, num:0, node:childNode};
					}else{
						var currentChecker = checkers[indexKey];
						if (currentChecker.num == 0){
							indexKey = currentChecker.keyStem + "_0";
							index[indexKey] = currentChecker.node;
							delete index[currentChecker.keyStem];
						}else{
							indexKey = currentChecker.keyStem + "_" + currentChecker.num;
							index[indexKey] = childNode;
						}
						++currentChecker.num;
					}
					if(isRecursive) index[indexKey] = NodeUtil.getIndex(childNode, true, indexOn);
				}
			}else if(childNode.nodeType == NodeUtil.Text){
				index["innerText"] = childNode.nodeValue;
			}else if(childNode.nodeType == NodeUtil.CDATASection){
				index["cdata"] = childNode.nodeValue;
			}
		}
	}
	return index;
}

NodeUtil.stripWhitespace = function(node){
	// to be implemented
}

NodeUtil.getAttribute = function(node, key){
	var value;
	if(isIe){
		value = node.attributes[key].value;
	}else{
		value = node.getAttribute(key);
	}
	return value;
}

NodeUtil.setAttribute = function(node, key, value){
	if(isIe){
		node.attributes[key].value = value;
	}else{
		node.setAttribute(value);
	}
}

NodeUtil.purge = function(d) {    
	var a = d.attributes, i, l, n;
	if(a){
		l = a.length;        
		for (i = 0; i < l; i += 1) {            
			n = a[i].name;            
			if (typeof d[n] === 'function') {            
				d[n] = null;            
			}        
		}    
	}
	a = d.childNodes;
	if(a){
		l = a.length;
		for (i = 0; i < l; i += 1){
			purge(d.childNodes[i]);
		}
	}
}

function removeChildNodes(node){
   if(node !== undefined && node !== null) return;
   while(node.hasChildNodes){
   		node.removeChild(node.firstChild);
   }
}
/* Util
----------------------------------------------*/
function Util(){
}

Util.createDelegate = function(obj, func){
	var f = function(){
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		return func.apply(target, arguments);
	};
	f.target = obj;
	f.func = func;
	return f;
}

Util.setTimeout = function(obj, method, interval){
	var args = Array.prototype.slice.apply(arguments, [3]);
	var f = function(){
		method.apply(obj, args);
	};
	return setTimeout(f, interval);
}

Util.setInterval = function(obj, method, interval){
	var args = Array.prototype.slice.apply(arguments, [3]);
	var f = function(){
		method.apply(obj, args);
	};
	return setInterval(f, interval);
}

Util.get2DigitStr = function(n){
	var str = "" + n;
	if(n < 10) str = "0" + str;
	return str;
}

Util.toString = function(o){
	var str = "";
	for(x in o){
		str += x + ": " + o[x] + "\n";
	}
}