/**
 * formcheckr.js
 *
 * @version  0.1.3.20061213
 * @require  prototype.js 1.4+
 * @usage
 * <form method="post" action="hoge" class="formcheckr">
 * <div>
 * <input name="a" value="" class="number required"/>
 * <input name="b" value="" class="katakana"/>
 * </div>
 * <p><input type="submit" value="send"/></p>
 * </form>
 * <script type="text/javascript" src="prototype.js"></script>
 * <script type="text/javascript" src="formcheckr.js" charset="utf-8"></script>
 * <script type="text/javascript">
 * var f = new Formcheckr('/common/js/formcheckr/rules.json.js');
 * f.setEvent();
 * </script>
 * - <form ... class="formcheckr">でフォームチェック対象に指定
 * - inputのclass属性にそれぞれの判定を。必要になったらその都度増やす
 *   - required: 必須項目
 *   # 以下は複数設定した場合上から評価される
 *   - mail    : メールアドレス
 *   - number  : 半角数字
 *   - katakana: 全角カタカナ
 *
 * @todo     クラス名にprefixオプション
 */


var Formcheckr = Class.create();
Formcheckr.prototype = {

	initialize : function(conf)
	{
		this.conf = conf;
	},


	setEvent : function()
	{
		var forms = document.forms;
		for (var i = 0; i < forms.length; i++)
			if (Element.hasClassName(forms[i], 'formcheckr'))
			{
				var inputs = Form.getInputs(forms[i], 'text');
				for (var j = 0; j < inputs.length; j++)
				{
					new Form.Element.EventObserver(inputs[j], this.check.bindAsEventListener(this));
					Event.observe(inputs[i], 'submit', this.checkAtLast.bindAsEventListener(this));
				}
				Event.observe(forms[i], 'submit', this.checkAtLast.bindAsEventListener(this));
			}
	},


	check : function(target)
	{
		var isError = false;
		this.hideError(target);
		if (!$F(target)) return false;

		for (var i = 0; i < this.conf.length; i++)
			if (Element.hasClassName(target, this.conf[i].targetClass))
				if (!$F(target).match(this.conf[i].rule))
				{
					this.showError(target, this.conf[i].errorMessage);
					return true;
				}
	},


	checkAtLast : function(e)
	{
		var form = Event.element(e).tagName.toLowerCase() == 'input' ?
			Event.findElement(e, 'form') :
			Event.element(e);

		var elements = Form.getElements(form);
		var isError  = false;
		for (var i = 0; i < elements.length; i++)
		{
			isError = this.check(elements[i]) || isError;

			if (Element.hasClassName(elements[i], 'required') && !elements[i].value)
			{
				this.showError(elements[i], '項目が入力されていません');
				isError = true;
			}
			if (elements[i].name == 'mail_again')
			{
				var mail = Form.getInputs(form, 'text', 'mail')[0].value;
				if (mail != elements[i].value)
				{
					this.showError(elements[i], 'メールアドレスをもう一度確認してください');
					isError = true;
				}
			}
				
		}

		if (isError)
			Event.stop(e);
	},


	showError : function(target, message)
	{
		new Insertion.After(target, '<span class="error"> ' + message + '</span>');
	},


	hideError : function(target)
	{
		var nodes = target.parentNode.childNodes;
		for (var i = nodes.length - 1; i > 0; i--)
			if (nodes[i].className == 'error')
				Element.remove(nodes[i]);
	}

};
