﻿/*
--------------------------------------------------------
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',
	show: function(grayElement) {

		grayElement = this.createElement(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements();
		grayElement.style.display = '';

		return grayElement;
	},
	hide: function(grayElement) {

		grayElement = this.getElement(grayElement || this.defaultId);
		grayElement.style.display = 'none';
		if (this._hideOverElements) this.showOverElements();

		return grayElement;
	},
	fadeIn: function(grayElement, fadeOptions) {

		grayElement = this.createElement(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements();

		fadeOptions = this.copyProperties({to: this.getOpacity(grayElement)}, fadeOptions || {});
		new Glayer.FadeIn(grayElement, fadeOptions).start();

		return grayElement;
	},
	fadeOut: function(grayElement, fadeOptions) {

		grayElement = this.getElement(grayElement || this.defaultId);

		fadeOptions = this.copyProperties({from: this.getOpacity(grayElement)}, fadeOptions || {});
		var fade = new Glayer.FadeOut(grayElement, fadeOptions);
		if (this._hideOverElements) {
			fade.end = function() {
				Glayer.showOverElements();
				Glayer.FadeOut.prototype.end.apply(this, arguments);
			}
		}

		fade.start();
		return grayElement;
	},

	showParallel: function(otherElements, grayElement) {

		grayElement = this.createElement(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements();
		grayElement.style.display = '';

		for (var i = 0; i < otherElements.length; i++) {
			otherElements[i] = this.getElement(otherElements[i]);
			otherElements[i].style.display = '';
		}

		return grayElement;
	},
	hideParallel: function(otherElements, grayElement) {

		grayElement = this.getElement(grayElement || this.defaultId);
		grayElement.style.display = 'none';
		if (this._hideOverElements) this.showOverElements();

		for (var i = 0; i < otherElements.length; i++) {
			otherElements[i] = this.getElement(otherElements[i]);
			otherElements[i].style.display = 'none';
		}

		return grayElement;
	},
	fadeInParallel: function(otherElements, grayElement, fadeOptions) {

		grayElement = this.createElement(grayElement || this.defaultId);
		this.resetSize(grayElement);
		if (this._hideOverElements) this.hideOverElements();

		fadeOptions = this.copyProperties({to: this.getOpacity(grayElement)}, fadeOptions || {});
		var grayFade = new Glayer.FadeIn(grayElement, fadeOptions);

		var otherFades = [];
		for (var i = 0; i < otherElements.length; i++) {
			otherElements[i] = this.getElement(otherElements[i]);
			otherFades.push(new Glayer.FadeIn(otherElements[i], {duration: fadeOptions.duration, to: this.getOpacity(otherElements[i])}));
		}

		grayFade.start(function(){
										 grayFade.update();
										 for (var i = 0; i < otherFades.length; i++) {
											 otherFades[i].update();
										 }
									 });

		return grayElement;
	},
	fadeOutParallel: function(otherElements, grayElement, fadeOptions) {

		grayElement = this.getElement(grayElement || this.defaultId);

		fadeOptions = this.copyProperties({from: this.getOpacity(grayElement)}, fadeOptions || {});
		var grayFade = new Glayer.FadeOut(grayElement, fadeOptions);
		if (this._hideOverElements) {
			grayFade.end = function() {
				Glayer.showOverElements();
				Glayer.FadeOut.prototype.end.apply(this, arguments);
			}
		}

		var otherFades = [];
		for (var i = 0; i < otherElements.length; i++) {
			otherElements[i] = this.getElement(otherElements[i]);
			otherFades.push(new Glayer.FadeOut(otherElements[i], {duration: fadeOptions.duration, from: this.getOpacity(otherElements[i])}));
		}

		grayFade.start(function(){
										 grayFade.update();
										 for (var i = 0; i < otherFades.length; i++) {
											 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
	getElement: function(element) {

		if (typeof element == 'string') {
			element = document.getElementById(element);
		}
		return element;
	},
	createElement: function(element) {

		var id = element;
		element = this.getElement(element);

		if (!element) {
			element = document.createElement('div');
			element.id = id;
			element.style.display = 'none';
			document.body.appendChild(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 (navigator.userAgent.indexOf('AppleWebKit') != -1){
			// 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
	getOpacity: function(element) {
		var value = this._getStyle(element, 'opacity');
		if (value) return parseFloat(value);

		if ((value = (element.style.filter || '').match(/alpha\(opacity=(.*)\)/))) {
			if (value[1]) return parseFloat(value[1]) / 100;
		}

		return 1.0;
	},
	_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
	overElementTagNames: ['select'],
	hideOverElements: function() {
		for (var i = 0, len1 = Glayer.overElementTagNames.length; i < len1; i++) {
			var elements = document.getElementsByTagName(Glayer.overElementTagNames[i]);
			for (var j = 0, len2 = elements.length; j < len2; j++) {
				elements[j].style.visibility = 'hidden';
			}
		}
	},
	showOverElements: function() {
		for (var i = 0, len1 = Glayer.overElementTagNames.length; i < len1; i++) {
			var elements = document.getElementsByTagName(Glayer.overElementTagNames[i]);
			for (var j = 0, len2 = elements.length; j < len2; j++) {
				elements[j].style.visibility = '';
			}
		}
	},

	// 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 = this.getElement(boxElement);
		if (!boxElement) {
			boxElement = this.createBox(boxId);
			textElement = document.createElement('p');
			textElement.id = textId;
			boxElement.appendChild(textElement);
		} else {
			textElement = this.getElement(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 = this.getElement(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 = this.getElement(textElement);
			okElement = this.getElement(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 = this.getElement(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 = this.getElement(textElement);
			okElement = this.getElement(okElement);
			cancelElement = this.getElement(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.setOpacity(this.to);
			this.end();
		} else {
			this.setOpacity(this.from + (this.range * (nowTime - this.startTime) / this.duration));
		}
	},
	setOpacity: function(opacity) {
		this.style.opacity = opacity;
		if (Glayer.isIE) this.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';
	}
};

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.setOpacity(this.from);
	Glayer.Fade.prototype.end.apply(this, arguments);
};

