/*
 * Updated 2008/11/27
 * 
 * Mail : info@graviness.com
 * Home : http://www.graviness.com/
 */



/**
 * 
 */
function class__Common__(window) {
	var className = "Common";

	var F = window[className] = function() {
	};

	/**
	 * デバッグ関数．
	 */
	window.errorMessage = location.protocol != "file:"
		? function(message) {window.alert(message);} : function(message) {};

	/**
	 * private変数の変数名の生成．
	 */
	Object.privateId = function() {
		// http://www.graviness.com/javascript/samples/str20011021code.html
		var codes = new Array();
		for (var i = 0x21, j = 0; i <= 0x7E; i++)
			codes[j++] = String.fromCharCode(i);

		var k = codes.length;

		return function(n) {
			if (n === void 0 || typeof(n) != "number")
				n = 8 + Math.floor(8 * Math.random());

			var r = "";
			for (var i = 0; i < n; i++) {
				var c = codes[Math.floor(k * Math.random())];

				// 先頭に'$'を含む変数名は生成しない．
				if (i == 0 && c == '$') {
					i = 0;
					continue;
				}

				r += c;
			}
			return r;
		};
	}();

	var getClassNames = function() {
		var CLASS_ID_PATTERN_STRING = "[_a-zA-Z\\$][_a-zA-Z0-9\\$]*";

		var EXTENSIBLE_CLASS_NAME_PATTERN = new RegExp().compile(
				"function\\s+class__("
				+ CLASS_ID_PATTERN_STRING
				+ ")__extends__("
				+ CLASS_ID_PATTERN_STRING
				+ ")__\\s*\\(");

		var BASICALLY_CLASS_NAME_PATTERN = new RegExp().compile(
			"function\\s+class__(" + CLASS_ID_PATTERN_STRING + ")__\\s*\\(");

		return function(classDefinition) {
			var s = classDefinition.toString();

			var m = s.match(EXTENSIBLE_CLASS_NAME_PATTERN);
			if (m !== null)
				return m;

			m = s.match(BASICALLY_CLASS_NAME_PATTERN);
			if (m !== null)
				return m;

			return null;
		};
	}();

	/**
	 * クラス名抽出．
	 */
	Object.getClassName = function(classDefinition) {
		var names = getClassNames(classDefinition);
		if (names != null)
			return names[1];

		return void(window.errorMessage("IllegalArgumentsException"
			+ "@Object.getClassName(Function)"));
	};

	/**
	 * プロトタイプオブジェクトの取得．
	 * 継承を自動で行う．
	 */
	Object.getPrototype = function(classDefinition, frame) {
		if (frame === void 0)
			frame = window;

		var names = getClassNames(classDefinition);
		if (names == null)
			return void(window.errorMessage("IllegalArgumentsException"
			+ "@Object.getPrototype(Function, Window)"));

		switch (names.length) {
			case 2 :
				return frame[names[1]].prototype;
			case 3 : {
				// http://blog.graviness.com/?eid=405821
				var subClass = frame[names[1]];
				var superClass = frame[names[2]];

				var Temp = new Function();
				Temp.prototype = superClass.prototype;
				subClass.prototype = new Temp;
				subClass.prototype.constructor = subClass;
				subClass.prototype.__super__ = function () {
					var originalSuper = this.__super__;
					this.__super__ = superClass.prototype.__super__ || null;

					superClass.apply(this, arguments);

					if (this.constructor == subClass) {
						delete this.__super__;
					} else {
						this.__super__ = originalSuper;
					}
				};

				return subClass.prototype;
			}
			default :
				// DONOTPASS
				return null;
		}
	};

	/**
	 * 継承．
	 * Prototype Function#inherit(Function superClass)
	 * <strong>クラスメンバは継承されない．</strong>
	 * @param superClass	継承元クラス（関数）．
	 * @return 自分自身のprototypeオブジェクト．
	 */
	/*Function.prototype.inherit = function(superClass) {
		function Temp() {}
		Temp.prototype = superClass.prototype;
		return this.prototype = new Temp;
	};*/

	// Window#onloadリスナー初期化等
	{
		var ws = new Object();
		ws.loaded = false;
		ws.onloadListeners = null;

		window.isLoaded = function() {
			return ws.loaded;
		};

		window.addOnloadListener = function(listener) {
			if (!Boolean(listener) || typeof listener != "function")
				return void(window.errorMessage("IllegalArgumentsException"
					+ "@window#addOnloadListener(Listener)"));

			if (ws.loaded)
				return void(window.errorMessage("IllegalStateException"
					+ "@window#addOnloadListener(Listener)"));

			if (ws.onloadListeners === null)
				ws.onloadListeners = new Array();

			ws.onloadListeners.push(listener);
		};

		window.removeOnloadListener = function(listener) {
			if (!Boolean(listener) || typeof listener != "function")
				return void(window.errorMessage("IllegalArgumentsException"
					+ "@window#removeOnloadListener(Listener)"));

			if (ws.loaded)
				return void(window.errorMessage("IllegalStateException"
					+ "@window#addOnloadListener(Listener)"));

			if (ws.onloadListeners === null)
				return false;

			var ls = ws.onloadListeners;
			for (var i = 0; i < ls.length; i++) {
				if (ls[i] == listener) {
					ls[i] = null;
					return true;
				}
			}

			return false;
		};

		window.onload = function() {
			ws.loaded = true;

			if (ws.onloadListeners === null)
				return;

			var ls = ws.onloadListeners;
			for (var i = 0; i < ls.length; i++) {
				if (ls[i] !== null) {
					ls[i]();
				}
			}

			ws.onloadListeners = null;
		};
	}
} class__Common__(window);

