//==============================================================
//	エレメント
//==============================================================
function $(id) {
	return Element.get(id);
}

function $F(id) {
	return Element.getValue(id);
}

var Element = {

	//--------------------------------------------------------------
	// <summary>
	//		エレメントの取得
	// <param>
	//		id = ID
	//--------------------------------------------------------------
	get: function (id) {

		return document.getElementById(id);
	},

	//--------------------------------------------------------------
	// <summary>
	//		エレメントの値を取得
	// <param>
	//		id = ID
	//--------------------------------------------------------------
	getValue: function (id) {

		var value	= null;
		var element = Element.get(id);

		if(!element) {
			return value;
		}

		switch(element.type.toLowerCase()) {

			case "checkbox":
			case "radio":
				value	= element.checked;
				break;

			default:
				value	= element.value;
				break;
		}

		return value;
	},

	//--------------------------------------------------------------
	// <summary>
	//		エレメントの不透明度設定
	// <param>
	//		element		= エレメント
	//		opacity		= 不透明度
	//--------------------------------------------------------------
	setOpacity: function (element, opacity) {
		element.style.filter		= 'alpha(opacity=' + opacity + ')';
		element.style.mozOpacity	= opacity / 100;
		element.style.opacity		= opacity / 100;
	}
}

//==============================================================
//	イベント
//==============================================================
var Event = {

	//--------------------------------------------------------------
	// <summary>
	//		イベントハンドラの設定
	// <param>
	//		element		= エレメント
	//		eventName	= イベント名
	//		eventHandler= イベントハンドラ
	//		capture		= キャプチャ
	//--------------------------------------------------------------
	add: function (element, eventName, eventHandler, capture) {

		if(element.addEventListener) {
			element.addEventListener(eventName, eventHandler, capture);
		} else if(element.attachEvent) {
			element.attachEvent("on" + eventName, eventHandler);
		}
	},

	//--------------------------------------------------------------
	// <summary>
	//		イベントハンドラの解除
	// <param>
	//		element		= エレメント
	//		eventName	= イベント名
	//		eventHandler= イベントハンドラ
	//		capture		= キャプチャ
	//--------------------------------------------------------------
	remove: function (element, eventName, eventHandler, capture) {

		if(element.removeEventListener) {
			element.removeEventListener(eventName, eventHandler, capture);
		} else if(element.detachEvent) {
			element.detachEvent("on" + eventName, eventHandler);
		}
	},

	//--------------------------------------------------------------
	// <summary>
	//		イベント発生元の取得
	// <param>
	//		e			= イベント引数
	//--------------------------------------------------------------
	source: function (e) {

		var source	= e.target;

		if(!source) {
			source	= e.srcElement;
		}

		return source;
	},

	//--------------------------------------------------------------
	// <summary>
	//		イベントの停止
	// <param>
	//		e			= イベント引数
	//--------------------------------------------------------------
	stop: function (e) {

		if(e.stopPropagation) {
			e.stopPropagation();
		} else if(window.event) {
			window.event.cancelBubble = true;
		}

		// デフォルトアクションの抑止
		if(e.preventDefault) {
			e.preventDefault();
		} else if(window.event) {
			window.event.returnValue = false;
		}
	}
}

//==============================================================
//	文字列関数
//==============================================================
var Util = {

	//--------------------------------------------------------------
	// <summary>
	//		URIエンコード
	// <param>
	//		value		= 文字列
	// <return>
	//		valueをURIエンコードした文字列
	//--------------------------------------------------------------
	encode: function (value) {

		return encodeURIComponent(value);
	}
}

//==============================================================
//	拡張
//==============================================================
String.prototype.encode			= function () { return Util.encode(this); }

//==============================================================
//	AjaxRequestParameter
//==============================================================
//**************************************************************
//	コンストラクタ
//**************************************************************
//--------------------------------------------------------------
// <summary>
//		コンストラクタ
// <remarks>
//		AjaxRequestParameterオブジェクトを生成する
//--------------------------------------------------------------
function AjaxRequestParameter() {

	this.url			= "";
	this.method			= "GET";
	this.async			= true;
	this.parameter		= "";
	this.onComplete		= null;
	this.onSuccess		= null;
	this.onError		= null;
	this.onException	= null;
}

//**************************************************************
//	メソッド
//**************************************************************
AjaxRequestParameter.prototype = {

	//--------------------------------------------------------------
	// <summary>
	//		パラメータの追加
	// <param>
	//		name		= 名前
	//		value		= 値
	//--------------------------------------------------------------
	addParameter: function (name, value) {

		if(this.parameter != "") {
			this.parameter = this.parameter + "&";
		}

		this.parameter = this.parameter + encodeURIComponent(name) + "=" + encodeURIComponent(value);
	}
}

//==============================================================
//	AjaxRequest
//==============================================================
var AjaxRequest = {

	XMLHTTP: 0,
	IFRAME: 1,

	//--------------------------------------------------------------
	// <summary>
	//		AjaxRequestオブジェクトの生成
	// <param>
	//		type		= タイプ
	// <return>
	//		AjaxRequestオブジェクト
	//--------------------------------------------------------------
	create: function (type) {

		var instance = null;

		if(type == AjaxRequest.IFRAME) {
			instance = new IFrameAjaxRequest();
		} else {
			instance = new XMLHttpAjaxRequest();
		}

		return instance;
	}
}

//==============================================================
//	XMLHttpAjaxRequest
//==============================================================
//**************************************************************
//	コンストラクタ
//**************************************************************
//--------------------------------------------------------------
// <summary>
//		コンストラクタ
// <remarks>
//		XMLHttpAjaxRequestオブジェクトを生成する
//--------------------------------------------------------------
function XMLHttpAjaxRequest() {

	this.innerRequest	= null;

	var req				= null;

	if(window.ActiveXObject) {
		try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {

			}
		}
	} else if(window.XMLHttpRequest) {
		req = new XMLHttpRequest();
	} else {

	}

	this.innerRequest	= req;
}

//**************************************************************
//	メソッド
//**************************************************************
XMLHttpAjaxRequest.prototype = {

	responseXML: null,
	responseDocument: null,
	responseText: null,
	responseHTML: null,

	//--------------------------------------------------------------
	// <summary>
	//		送信
	// <param>
	//		parameter	= パラメータ
	//--------------------------------------------------------------
	send: function (parameter) {

		var ajaxRequest = this;

		this.innerRequest.onreadystatechange = function() {

			if(ajaxRequest.innerRequest.readyState == 4) {

				try {
					try {
						try {
							ajaxRequest.responseText	= ajaxRequest.innerRequest.responseText;
							ajaxRequest.responseHTML	= ajaxRequest.responseText;
							ajaxRequest.responseXML		= ajaxRequest.innerRequest.responseXML;
							ajaxRequest.responseDocument= ajaxRequest.responseXML;

							if(ajaxRequest.innerRequest.status >= 200 && ajaxRequest.innerRequest.status < 300) {
								if(parameter.onSuccess) {
									parameter.onSuccess(ajaxRequest);
								}
							} else {
								if(parameter.onError) {
									parameter.onError(ajaxRequest);
								}
							}
						} catch (e) {
							throw e;
						} finally {
							if(parameter.onComplete) {
								parameter.onComplete(ajaxRequest);
							}
						}
					} catch (e) {
						if(parameter.onException) {
							parameter.onException(e);
						} else {
							throw e;
						}
					}
				} catch (e) {
					if(AjaxRequest.onException) {
						AjaxRequest.onException(e);
					}
				}
			}

		}

		var url		= parameter.url;
		var param	= "";

		if(parameter.parameter != "") {
			if(parameter.method == "get" || parameter.method == "GET") {
				url		= url + "?" + parameter.parameter;
			} else {
				param	= parameter.parameter;
			}
		}

		this.innerRequest.open(parameter.method, url, parameter.async);
		this.innerRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=EUC-JP");
		this.innerRequest.send(param);
	},

	//--------------------------------------------------------------
	// <summary>
	//		リクエスト状態の取得
	// <return>
	//		リクエスト状態
	//--------------------------------------------------------------
	getReadyState: function () {
		return this.innerRequest.readyState;
	},

	//--------------------------------------------------------------
	// <summary>
	//		ステータスの取得
	// <return>
	//		ステータス
	//--------------------------------------------------------------
	getStatus: function () {
		return this.innerRequest.status;
	}
}

//==============================================================
//	IFrameAjaxRequest
//==============================================================
//**************************************************************
//	コンストラクタ
//**************************************************************
//--------------------------------------------------------------
// <summary>
//		コンストラクタ
// <remarks>
//		IFrameAjaxRequestオブジェクトを生成する
//--------------------------------------------------------------
function IFrameAjaxRequest() {

}

//**************************************************************
//	メソッド
//**************************************************************
IFrameAjaxRequest.prototype = {

	responseDocument: null,
	responseText: null,
	responseHTML: null,

	//--------------------------------------------------------------
	// <summary>
	//		完了時コールバック
	// <param>
	//		request		= 名前
	//		parameter	= パラメータ
	//--------------------------------------------------------------
	complete: function (request, parameter) {

		if(!request.iframe) {
			return;
		}

		try {
			try {
				try {
					var document				= request.iframe.contentWindow.document;
					request.responseDocument	= document;
		
					var responseElement			= null;

					if(parameter.targetID) {
						responseElement		= document.getElementById(parameter.targetID);
					} else {
						responseElement		= document.body;
					}

					if(responseElement) {

						if(responseElement.innerText) {
							request.responseText= responseElement.innerText;
						} else if(responseElement.textContent) {
							request.responseText= responseElement.textContent;
						}

						request.responseHTML= responseElement.innerHTML;

						if(parameter.onSuccess) {
							parameter.onSuccess(request);
						}
					} else {
						if(parameter.onError) {
							parameter.onError(request);
						}
					}

				} catch (e) {
					throw e;
				} finally {
					if(parameter.onComplete) {
						parameter.onComplete(request);
					}
				}
			} catch (e) {
				if(parameter.onException) {
					parameter.onException(e);
				} else {
					throw e;
				}
			}
		} catch (e) {
			if(AjaxRequest.onException) {
				AjaxRequest.onException(e);
			}
		} finally {
			var iframe			= request.iframe;
			request.iframe		= null;
			iframe.parentNode.removeChild(iframe);
		}
	},

	//--------------------------------------------------------------
	// <summary>
	//		リクエスト送信
	// <param>
	//		parameter	= パラメータ
	//--------------------------------------------------------------
	send: function (parameter) {

		if(!this.iframe) {

			this.iframe					= document.createElement("iframe");
			this.iframe.style.display	= "none";
			document.body.appendChild(this.iframe);

			var request = this;

			if(document.all) {
				Event.add(this.iframe, "readystatechange", function () {
					if(request.iframe.readyState == "complete") {
						request.complete(request, parameter);
					}
				}, false);
			} else {
				Event.add(this.iframe, "load", function () {
					request.complete(request, parameter);
				}, false);
			}
		}

		this.iframe.src	= parameter.url;
	}
}

//==============================================================
//	Effect
//==============================================================
var Effect = {

	//--------------------------------------------------------------
	// <summary>
	//		フェードイン
	// <param>
	//		element				= 名前
	//		opacity				= 不透明度
	//		totalMilliSeconds	= 総ミリ秒
	//		step				= ステップ数
	//		onComplete			= コールバック
	//--------------------------------------------------------------
	fadeIn: function (element, opacity, totalMilliSeconds, step, onComplete) {

		var effect = new EffectFadeIn(element);

		if(!isNaN(opacity) && !isNaN(totalMilliSeconds) && !isNaN(step)) {

			effect.setInterval(opacity, totalMilliSeconds, step);

			if(onComplete) {
				effect.onComplete = onComplete;
			}

			effect.start();
		}

		return effect;
	},

	//--------------------------------------------------------------
	// <summary>
	//		フェードアウト
	// <param>
	//		element				= 名前
	//		opacity				= 不透明度
	//		totalMilliSeconds	= 総ミリ秒
	//		step				= ステップ数
	//		onComplete			= コールバック
	//--------------------------------------------------------------
	fadeOut: function (element, opacity, totalMilliSeconds, step, onComplete) {

		var effect = new EffectFadeOut(element);

		if(!isNaN(opacity) && !isNaN(totalMilliSeconds) && !isNaN(step)) {

			effect.setInterval(opacity, totalMilliSeconds, step);

			if(onComplete) {
				effect.onComplete = onComplete;
			}

			effect.start();
		}

		return effect;
	}
}

//==============================================================
//	フェードイン
//==============================================================
//**************************************************************
//	コンストラクタ
//**************************************************************
//--------------------------------------------------------------
// <summary>
//		コンストラクタ
//--------------------------------------------------------------
function EffectFadeIn(element) {
	this.element		= element;
	this.targetOpacity	= 100;
	this.addOpacity		= 10;
	this.interval		= 100;
	this.timerId		= null;
	this.onComplete		= null;
}

//**************************************************************
//	メソッド
//**************************************************************
EffectFadeIn.prototype = {

	//--------------------------------------------------------------
	// <summary>
	//		インターバルの設定
	// <param>
	//		targetOpacity		= 不透明度
	//		totalMilliSeconds	= 総ミリ秒
	//		step				= ステップ数
	//--------------------------------------------------------------
	setInterval: function (targetOpacity, totalMilliSeconds, step) {

		var opacity = parseFloat(this.element.style.opacity) * 100;

		if(isNaN(opacity)) {
			opacity = 100.0;
		}

		this.targetOpacity	= targetOpacity;
		this.addOpacity		= (targetOpacity - opacity) / step;
		this.interval		= totalMilliSeconds / step;
	},

	//--------------------------------------------------------------
	// <summary>
	//		フェードイン
	// <param>
	//		opacity				= 不透明度
	//		totalMilliSeconds	= 総ミリ秒
	//		step				= ステップ数
	//--------------------------------------------------------------
	start: function () {
		this.stop();
		var sender		= this;
		this.timerId	= setInterval(function() {sender.onTimer(sender);}, this.interval);
	},

	//--------------------------------------------------------------
	// <summary>
	//		タイマーイベント
	//--------------------------------------------------------------
	onTimer: function (sender) {

		var opacity = parseFloat(sender.element.style.opacity) * 100;

		if(isNaN(opacity)) {
			opacity = 100.0;
		}

		opacity	+= sender.addOpacity;

		if(opacity > sender.targetOpacity) {
			opacity	= sender.targetOpacity;
		}

		Element.setOpacity(sender.element, opacity);

		if(opacity >= sender.targetOpacity) {
			sender.stop();

			if(sender.onComplete) {
				sender.onComplete();
			}
		}
	},

	//--------------------------------------------------------------
	// <summary>
	//		フェードイン
	// <param>
	//		name			= 名前
	//		value			= 値
	//--------------------------------------------------------------
	stop: function () {
		if(this.timerId) {
			clearInterval(this.timerId);
			this.timerId = null;
		}
	}
}

//==============================================================
//	フェードアウト
//==============================================================
//**************************************************************
//	コンストラクタ
//**************************************************************
//--------------------------------------------------------------
// <summary>
//		コンストラクタ
//--------------------------------------------------------------
function EffectFadeOut(element) {
	this.element		= element;
	this.targetOpacity	= 0;
	this.addOpacity		= 10;
	this.interval		= 100;
	this.timerId		= null;
	this.onComplete		= null;
}

//**************************************************************
//	メソッド
//**************************************************************
EffectFadeOut.prototype = {

	//--------------------------------------------------------------
	// <summary>
	//		インターバルの設定
	// <param>
	//		targetOpacity		= 不透明度
	//		totalMilliSeconds	= 総ミリ秒
	//		step				= ステップ数
	//--------------------------------------------------------------
	setInterval: function (targetOpacity, totalMilliSeconds, step) {

		var opacity = parseFloat(this.element.style.opacity) * 100;

		if(isNaN(opacity)) {
			opacity = 100.0;
		}

		this.targetOpacity	= targetOpacity;
		this.addOpacity		= (opacity - targetOpacity) / step;
		this.interval		= totalMilliSeconds / step;
	},

	//--------------------------------------------------------------
	// <summary>
	//		フェードイン
	// <param>
	//		opacity				= 不透明度
	//		totalMilliSeconds	= 総ミリ秒
	//		step				= ステップ数
	//--------------------------------------------------------------
	start: function () {
		this.stop();
		var sender		= this;
		this.timerId	= setInterval(function() {sender.onTimer(sender);}, this.interval);
	},

	//--------------------------------------------------------------
	// <summary>
	//		タイマーイベント
	//--------------------------------------------------------------
	onTimer: function (sender) {

		var opacity = parseFloat(sender.element.style.opacity) * 100;

		if(isNaN(opacity)) {
			opacity = 100.0;
		}

		opacity	-= sender.addOpacity;

		if(opacity < sender.targetOpacity) {
			opacity	= sender.targetOpacity;
		}

		Element.setOpacity(sender.element, opacity);

		if(opacity <= sender.targetOpacity) {
			sender.stop();

			if(sender.onComplete) {
				sender.onComplete();
			}
		}
	},

	//--------------------------------------------------------------
	// <summary>
	//		フェードイン
	// <param>
	//		name			= 名前
	//		value			= 値
	//--------------------------------------------------------------
	stop: function () {
		if(this.timerId) {
			clearInterval(this.timerId);
			this.timerId = null;
		}
	}
}
