﻿/*
--------------------------------------------------------
glayer.js - (gray out + layer) = glayer
Version 2.6 (Update 2008/09/10)

Copyright (c) 2006-2008 onozaty (http://www.enjoyxstudy.com)

Released under an MIT-style license.

For details, see the web site:
 http://www.enjoyxstudy.com/javascript/glayer/

--------------------------------------------------------
*/

var Glayer = {
	defaultId : 'glayer',
	useCSSTransition : (function() {
			var a = (new Image).style,
				b = 'ransition';
			return 't' + b in a ||
				'webkitT' + b in a ||
				'MozT' + b in a ||
				'OT' + b in a;
		})(),
	show: function(grayElement) {
		grayElement = this.createElement(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements(grayElement);
		grayElement.style.display = '';

		return grayElement;
	},
	hide: function(grayElement) {

		grayElement = $(grayElement || this.defaultId);
		grayElement.style.display = 'none';
		if (this._hideOverElements) this.showOverElements(grayElement);

		return grayElement;
	},
	fadeIn: function(grayElement, fadeOptions) {
		grayElement = this.createElement(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements(grayElement);

		if (this.useCSSTransition) {
			grayElement.style.display = "";
			Element.addClassName(grayElement, "show");
		} else {
			fadeOptions = this.copyProperties({to: grayElement.getOpacity() }, fadeOptions || {});
			new Glayer.FadeIn(grayElement, fadeOptions).start();
		}

		return grayElement;
	},
	fadeOut: function(grayElement, fadeOptions) {
		grayElement = $(grayElement || this.defaultId);

		if (this.useCSSTransition) {
			setTimeout(function() { grayElement.style.display = "none"; }, fadeOptions.duration || Glayer.Fade.duration);
			Element.removeClassName(grayElement, "show");
			if (this._hideOverElements) {
				Glayer.showOverElements(grayElement);
			}
		} else {
			fadeOptions = this.copyProperties({from: grayElement.getOpacity() }, fadeOptions || {});
			var fade = new Glayer.FadeOut(grayElement, fadeOptions);
			if (this._hideOverElements) {
				fade.end = function() {
					Glayer.showOverElements(grayElement);
					Glayer.FadeOut.prototype.end.apply(this, arguments);
				}
			}
			fade.start();
		}
		return grayElement;
	},

	showParallel: function(otherElements, grayElement) {
		grayElement = $(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements(grayElement);
		grayElement.style.display = '';

		for (var i = 0; i < otherElements.length; i++) {
			otherElements[i] = $(otherElements[i]);
			otherElements[i].style.display = '';
		}

		return grayElement;
	},
	hideParallel: function(otherElements, grayElement) {
		grayElement = $(grayElement || this.defaultId);
		grayElement.style.display = 'none';
		if (this._hideOverElements) this.showOverElements(grayElement);

		for (var i = 0; i < otherElements.length; i++) {
			otherElements[i] = $(otherElements[i]);
			otherElements[i].style.display = 'none';
		}

		return grayElement;
	},
	fadeInParallel: function(otherElements, grayElement, fadeOptions) {
		grayElement = $(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements(grayElement);

		fadeOptions = this.copyProperties({to: grayElement.getOpacity() }, fadeOptions || {});
		var otherFades = [];
		for (var i = otherElements.length; --i >= 0;) {
			otherFades.push(new Glayer.FadeIn($(otherElements[i]), { duration: fadeOptions.duration, to: Element.getOpacity(otherElements[i]) }));
		}
		if (this.useCSSTransition) {
			grayElement.style.display = "";
			setTimeout(function() { Element.addClassName(grayElement, "show"); }, 1);
			if (otherFades.length) {
				otherFades[0].callback = fadeOptions.callback;
				otherFades[0].start(function(){
					 for (var i = otherFades.length; --i >= 0;) {
						 otherFades[i].update();
					 }
				});
			}
		} else {
			var grayFade = new Glayer.FadeIn(grayElement, fadeOptions);
			grayFade.start(function(){
				grayFade.update();
				 for (var i = otherFades.length; --i >= 0;) {
					 otherFades[i].update();
				 }
			});
		}

		return grayElement;
	},
	fadeOutParallel: function(otherElements, grayElement, fadeOptions) {
		grayElement = $(grayElement || this.defaultId);
		fadeOptions = this.copyProperties({from: grayElement.getOpacity() }, fadeOptions || {});
		var otherFades = [];
		for (var i = otherElements.length; --i >= 0;) {
			var elm = $(otherElements[i]);
			otherFades.push(new Glayer.FadeOut(elm, { duration: fadeOptions.duration, from: elm.getOpacity() }));
		}

		if (this.useCSSTransition) {
			setTimeout(function() { grayElement.style.display = "none"; }, fadeOptions.duration || Glayer.Fade.duration);
			Element.removeClassName(grayElement, "show");
			if (otherFades.length) {
				otherFades[0].callback = fadeOptions.callback;
				otherFades[0].start(function() {
					 for (var i = otherFades.length; --i >= 0;) {
						 otherFades[i].update();
					 }
				});
			}
		} else {
			var grayFade = new Glayer.FadeOut(grayElement, fadeOptions);
			if (this._hideOverElements) {
				grayFade.end = function() {
					Glayer.showOverElements(grayElement);
					Glayer.FadeOut.prototype.end.apply(this, arguments);
				}
			}
			grayFade.start(function(){
				 grayFade.update();
				 for (var i = otherFades.length; --i >= 0;) {
					 otherFades[i].update();
				 }
			 });
		}


		return grayElement;
	},

	resetSize: function(element) {
		var position = this._getStyle(element, 'position');

		if (position != 'fixed') {
			var page = this.getPageSize();

			element.style.width  = page.width + 'px';
			element.style.height = page.height + 'px';
		}
	},

	// Util
	createElement: function(element) {
		var id = element;
		element = $(element);

		if (!element) {
			element = document.createElement('div');
			element.id = id;
			element.style.display = 'none';
			document.body.appendChild(element);
			element = $(element);
		}
		return element;
	},
	copyProperties: function(dest, src) {
		for (var property in src) {
			dest[property] = src[property];
		}
		return dest;
	},
	isIE : (/MSIE/.test(navigator.userAgent) && !window.opera),
	isWebKit : (navigator.userAgent.indexOf('AppleWebKit') != -1),

	// Window / Page Size
	getWindowSize: function() {
		var width;
		var height;

		if (document.compatMode == 'CSS1Compat' && !window.opera) {
			// Strict Mode && Non Opera
			width  = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
		} else if (window.innerWidth){
			// Safari
			width  = window.innerWidth;
			height = window.innerHeight;
		} else {
			// other
			width  = document.body.clientWidth;
			height = document.body.clientHeight;
		}

		return {width: width, height: height};
	},
	getPageSize: function() {
		var windowSize = this.getWindowSize();
		var width  = windowSize.width;
		var height = windowSize.height;

		if (document.compatMode == 'CSS1Compat') {
			if (document.documentElement.scrollWidth > width) {
				width  = document.documentElement.scrollWidth;
			}
			if (document.documentElement.scrollHeight > height) {
				height = document.documentElement.scrollHeight;
			}
		} else {
			if (document.body.scrollWidth > width) {
				width  = document.body.scrollWidth;
			}
			if (document.body.scrollHeight > height) {
				height = document.body.scrollHeight;
			}
		}

		return {width: width, height: height};
	},

	// Styles
	_getStyle: function(element, style) {
		var value = element.style[style];
		if (value) return value;

		if (document.defaultView && document.defaultView.getComputedStyle) {
			var oldDisplay = element.style.display;
			if (Glayer.isWebKit) element.style.display = 'block';
			var css = document.defaultView.getComputedStyle(element, null);
			if (css) value = css.getPropertyValue(style);
			if (Glayer.isWebKit) element.style.display = oldDisplay;
			return value;
		} else if (element.currentStyle) {
			return element.currentStyle[style];
		}

		return null;
	},

	// hide/show z-index over elements (IE6 bug)
	_hideOverElements: (typeof document.documentElement.style.maxHeight == "undefined"), // IE6 or older
	getIEFix: function(grayElement) {
		grayElement = $(grayElement || this.defaultId);
		var iefix = $(grayElement.id + "_iefix");
		if (!iefix) {
			var iefix = document.createElement("DIV");
			iefix.innerHTML = '<iframe id="' + grayElement.id + '_iefix" src="javascript:false;" frameborder="0" scrolling="no" '+
				'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);"></iframe>';
			iefix = grayElement.parentNode.appendChild(iefix.firstChild);
		}
		return iefix;
	},
	hideOverElements: function(grayElement) {
		this.getIEFix(grayElement).style.display = 'none';
	},
	showOverElements: function(grayElement) {
		var iefix = this.getIEFix(grayElement);
		Position.clone(grayElement, iefix, { setTop:(!grayElement.style.height) });
		iefix.style.zIndex = (grayElement.style.zIndex || 0) - 1;
		iefix.style.display = '';
	},

	// debug
	getDebugInfo: function() {

		var debugInfo = new Array();

		debugInfo.push("document.compatMode:" + document.compatMode);
		debugInfo.push("window.innerWidth:" + window.innerWidth);
		debugInfo.push("window.innerHeight:" + window.innerHeight);
		debugInfo.push("window.scrollMaxX:" + window.scrollMaxX);
		debugInfo.push("window.scrollMaxY:" + window.scrollMaxY);
		debugInfo.push("document.body.scrollWidth:" + document.body.scrollWidth);
		debugInfo.push("document.body.scrollHeight:" + document.body.scrollHeight);
		debugInfo.push("document.body.offsetWidth:" + document.body.offsetWidth);
		debugInfo.push("document.body.offsetHeight:" + document.body.offsetHeight);
		debugInfo.push("document.body.clientWidth:" + document.body.clientWidth);
		debugInfo.push("document.body.clientHeight:" + document.body.clientHeight);
		debugInfo.push("document.documentElement:" + document.documentElement);
		if (document.documentElement) {
			debugInfo.push("document.documentElement.scrollWidth:" + document.documentElement.scrollWidth);
			debugInfo.push("document.documentElement.scrollHeight:" + document.documentElement.scrollHeight);
			debugInfo.push("document.documentElement.offsetWidth:" + document.documentElement.offsetWidth);
			debugInfo.push("document.documentElement.offsetHeight:" + document.documentElement.offsetHeight);
			debugInfo.push("document.documentElement.clientWidth:" + document.documentElement.clientWidth);
			debugInfo.push("document.documentElement.clientHeight:" + document.documentElement.clientHeight);
		}

		return debugInfo;
	},



/* ====== ex から移植 (ここから) ====== */
	//// Base ////
	boxClassName: 'glayer_box',
	createBox: function(boxElement) {
		boxElement = this.createElement(boxElement);
		boxElement.className = this.boxClassName;
		return boxElement;
	},
	showBox: function(boxElement, boxOptions, grayElement) {
		this.setBoxPosition(boxElement, boxOptions);
		return this.showParallel([boxElement], grayElement);
	},
	hideBox: function(boxElement, grayElement) {
		return this.hideParallel([boxElement], grayElement);
	},
	fadeInBox: function(boxElement, boxOptions, grayElement, fadeOption) {
		this.setBoxPosition(boxElement, boxOptions);
		return this.fadeInParallel([boxElement], grayElement, fadeOption);
	},
	fadeOutBox: function(boxElement, grayElement, fadeOption) {
		return this.fadeOutParallel([boxElement], grayElement, fadeOption);
	},

	setBoxPosition: function(boxElement, boxOptions) {
		boxOptions = boxOptions || {};
		// added iwaki
		if ("moveCenterInWindow" in boxElement) { boxElement.moveCenterInWindow(boxOptions); return; }

		var style = boxElement.style;

		var topRatio = boxOptions.topRatio != null ? boxOptions.topRatio : 0.5;
		var leftRatio = boxOptions.leftRatio != null ? boxOptions.leftRatio : 0.5;
		style.width = boxOptions.width || '';
		style.height = boxOptions.height || '';

		var es = this.getElementSize(boxElement);
		var ws = this.getViewPortSize();
		var offsetX = 0;
		style.left = boxOptions.leftPosition || parseInt(ws.x + (ws.width * leftRatio) - parseInt(es.width * leftRatio)) + "px";
		style.top = boxOptions.topPosition || parseInt(ws.y + (ws.height * topRatio) - parseInt(es.height * topRatio)) + "px";
	},
	getViewPortSize : function(w) {
	var d, b;

	w = w || window;
	d = w.document;
	b = this.boxModel ? d.documentElement : d.body;

	// Returns viewport size excluding scrollbars
	return {
		x : w.pageXOffset || b.scrollLeft,
		y : w.pageYOffset || b.scrollTop,
		width : w.innerWidth || b.clientWidth,
		height : w.innerHeight || b.clientHeight
	};
	},
	getElementSize: function(element) {
	var display = element.style.display;
	if (display != 'none' && display != null) // Safari bug
		return {width: element.offsetWidth, height: element.offsetHeight};

	// All *Width and *Height properties give 0 on elements with display none
	var els = element.style;
	var originalVisibility = els.visibility;
	var originalPosition = els.position;
	var originalDisplay = els.display;
	els.visibility = 'hidden';
	els.position = 'absolute';
	els.display = 'block';
	var originalWidth = element.clientWidth;
	var originalHeight = element.clientHeight;
	els.display = originalDisplay;
	els.position = originalPosition;
	els.visibility = originalVisibility;
	return {width: originalWidth, height: originalHeight};
	},

	//// Message ////
	defaultMessage: {
		boxId: 'glayer_message',
		textId: 'glayer_message_text'
	},
	createMessageBox: function(message, boxOptions) {
		boxOptions = boxOptions || {};
		var boxElement = boxOptions.box || this.defaultMessage.boxId;
		var boxId = boxElement.id || boxElement;
		var textElement = boxOptions.text || this.defaultMessage.textId;
		var textId = textElement.id || textElement;

		boxElement = $(boxElement);
		if (!boxElement) {
			boxElement = this.createBox(boxId);
			textElement = document.createElement('p');
			textElement.id = textId;
			boxElement.appendChild(textElement);
		} else {
			textElement = $(textElement);
		}

		textElement.innerHTML = message;
		return boxElement;
	},

	showMessage: function(message, boxOptions, grayElement) {
		return this.showBox(this.createMessageBox(message, boxOptions), boxOptions, grayElement);
	},
	hideMessage: function(boxElement, grayElement) {
		return this.hideBox(boxElement || this.defaultMessage.boxId, grayElement);
	},
	fadeInMessage: function(message, boxOptions, grayElement, fadeOption) {
		return this.fadeInBox(this.createMessageBox(message, boxOptions), boxOptions, grayElement, fadeOption);
	},
	fadeOutMessage: function(boxElement, grayElement, fadeOption) {
		return this.fadeOutBox(boxElement || this.defaultMessage.boxId, grayElement, fadeOption);
	},

	//// Alert ////
	defaultAlert: {
		boxId: 'glayer_alert',
		textId: 'glayer_alert_text',
		buttonId: 'glayer_alert_button',
		okId: 'glayer_alert_ok',
		okLabel: 'OK'
	},
	getDefaultAlertOkFunc: function() {
		return function(){ Glayer.hideAlert(); };
	},

	createAlertBox: function(message, boxOptions) {

		boxOptions = boxOptions || {};
		var boxElement = boxOptions.box || this.defaultAlert.boxId;
		var boxId = boxElement.id || boxElement;
		var textElement = boxOptions.text || this.defaultAlert.textId;
		var textId = textElement.id || textElement;
		var okElement = boxOptions.ok || this.defaultAlert.okId;
		var okId = okElement.id || okElement;

		boxElement = $(boxElement);
		if (!boxElement) {
			boxElement = this.createBox(boxId);

			textElement = document.createElement('p');
			textElement.id = textId;
			boxElement.appendChild(textElement);

			var buttonElement = document.createElement('p');
			buttonElement.id = this.defaultAlert.buttonId;
			boxElement.appendChild(buttonElement);

			okElement = document.createElement('input');
			okElement.type = 'button';
			okElement.id = okId;
			buttonElement.appendChild(okElement);
		} else {
			textElement = $(textElement);
			okElement = $(okElement);
		}

		textElement.innerHTML = message;

		okElement.value = boxOptions.okLabel || this.defaultAlert.okLabel;
		okElement.onclick = boxOptions.callback || this.getDefaultAlertOkFunc();

		return boxElement;
	},

	showAlert: function(message, boxOptions, grayElement) {
		return this.showBox(this.createAlertBox(message, boxOptions), boxOptions, grayElement);
	},
	hideAlert: function(boxElement, grayElement) {
		return this.hideBox(boxElement || this.defaultAlert.boxId, grayElement);
	},
	fadeInAlert: function(message, boxOptions, grayElement, fadeOption) {
		return this.fadeInBox(this.createAlertBox(message, boxOptions), boxOptions, grayElement, fadeOption);
	},
	fadeOutAlert: function(boxElement, grayElement, fadeOption) {
		return this.fadeOutBox(boxElement || this.defaultAlert.boxId, grayElement, fadeOption);
	},

	//// Confirm ////
	defaultConfirm: {
		boxId: 'glayer_confirm',
		textId: 'glayer_confirm_text',
		buttonId: 'glayer_confirm_button',
		okId: 'glayer_confirm_ok',
		okLabel: 'OK',
		cancelId: 'glayer_confirm_cancel',
		cancelLabel: 'Cancel'
	},
	getConfirmResultFunc: function(callback, result) {
		return function(){ callback(result); };
	},

	createConfirmBox: function(message, resultCallback, boxOptions) {

		boxOptions = boxOptions || {};
		var boxElement = boxOptions.box || this.defaultConfirm.boxId;
		var boxId = boxElement.id || boxElement;
		var textElement = boxOptions.text || this.defaultConfirm.textId;
		var textId = textElement.id || textElement;
		var okElement = boxOptions.ok || this.defaultConfirm.okId;
		var okId = okElement.id || okElement;
		var cancelElement = boxOptions.cancel || this.defaultConfirm.cancelId;
		var cancelId = cancelElement.id || cancelElement;

		boxElement = $(boxElement);
		if (!boxElement) {
			boxElement = this.createBox(boxId);

			textElement = document.createElement('p');
			textElement.id = textId;
			boxElement.appendChild(textElement);

			var buttonElement = document.createElement('p');
			buttonElement.id = this.defaultConfirm.buttonId;
			boxElement.appendChild(buttonElement);

			okElement = document.createElement('input');
			okElement.type = 'button';
			okElement.id = okId;
			buttonElement.appendChild(okElement);
			cancelElement = document.createElement('input');
			cancelElement.type = 'button';
			cancelElement.id = cancelId;
			buttonElement.appendChild(cancelElement);
		} else {
			textElement = $(textElement);
			okElement = $(okElement);
			cancelElement = $(cancelElement);
		}

		textElement.innerHTML = message;

		okElement.value = boxOptions.okLabel || this.defaultConfirm.okLabel;
		okElement.onclick = this.getConfirmResultFunc(resultCallback, true);

		cancelElement.value = boxOptions.cancelLabel || this.defaultConfirm.cancelLabel;
		cancelElement.onclick = this.getConfirmResultFunc(resultCallback, false);

		return boxElement;
	},

	showConfirm: function(message, resultCallback, boxOptions, grayElement) {
		return this.showBox(this.createConfirmBox(message, resultCallback, boxOptions), boxOptions, grayElement);
	},
	hideConfirm: function(boxElement, grayElement) {
		return this.hideBox(boxElement || this.defaultConfirm.boxId, grayElement);
	},
	fadeInConfirm: function(message, resultCallback, boxOptions, grayElement, fadeOption) {
		return this.fadeInBox(this.createConfirmBox(message, resultCallback, boxOptions), boxOptions, grayElement, fadeOption);
	},
	fadeOutConfirm: function(boxElement, grayElement, fadeOption) {
		return this.fadeOutBox(boxElement || this.defaultConfirm.boxId, grayElement, fadeOption);
	}
/* ====== ex から移植 (ここまで) ====== */
};


// Fade In/Out
Glayer.Fade = function(element, options) {
	this.setup(element, options);
};

Glayer.Fade.prototype = {
	intervalTime: 10,
	duration: 800,

	setup: function(element, options) {
		this.element = $(element);
		this.style = this.element.style;

		options = options || {};

		if (options.duration != undefined) this.duration = options.duration;
		if (options.from != undefined) this.from = options.from;
		if (options.to != undefined) this.to = options.to;
		if (options.callback != undefined) this.callback = options.callback;

		this.startTime = new Date().getTime();
		this.endTime = this.startTime + this.duration;

		this.range = this.to - this.from;

		if (Glayer.isIE && (!this.element.currentStyle.hasLayout)) {
			this.style['zoom'] = 1;
		}
		this.first = true;
	},
	start: function(updater) {
		var self = this;
		updater = updater || function(){ self.update(); };
		this.intervalId = setInterval(updater, this.intervalTime);
	},
	end: function() {
		if (this.intervalId != null) {
			clearInterval(this.intervalId);
			this.intervalId = null;
		}
		this.execCallback();
	},
	execCallback: function() {
		if (!this.callback) return;

		if (typeof this.callback == 'function') {
			this.callback();
		} else {
			for (var i = 0; i < this.callback.length; i++) {
				this.callback[i]();
			}
		}
	},
	update: function() {
		var nowTime = new Date().getTime();

		if (this.first) {
			this.style.display = '';
			this.first = false;
		}

		if (nowTime >= this.endTime) {
			this.element.setOpacity(this.to);
			this.end();
		} else {
			this.element.setOpacity(this.from + (this.range * (nowTime - this.startTime) / this.duration));
		}
	}
};

Glayer.FadeIn = function() {
	Glayer.Fade.apply(this, arguments);
};
Glayer.copyProperties(Glayer.FadeIn.prototype, Glayer.Fade.prototype);
Glayer.FadeIn.prototype.from = 0.0;
Glayer.FadeIn.prototype.to = 1.0;

Glayer.FadeOut = function() {
	Glayer.Fade.apply(this, arguments);
};
Glayer.copyProperties(Glayer.FadeOut.prototype, Glayer.Fade.prototype);
Glayer.FadeOut.prototype.from = 1.0;
Glayer.FadeOut.prototype.to = 0.0;
Glayer.FadeOut.prototype.end = function() {
	this.style.display = 'none';
	this.element.setOpacity(this.from);
	Glayer.Fade.prototype.end.apply(this, arguments);
};


