(function($) {
	$(function(){
		//エラー時の表示メッセージ定義
		var validateMessages = {
			required: "【注】入力されていません。",
			requiredMultiText: "【注】入力されていません。",
			requiredMultiSelect: "【注】未選択です。",
			requiredMultiCheck: "【注】未選択です。",
			requiredAskSeltxt: "【注】上記チェックボックスにチェックを入れた際は、詳細を入力してください。",
			requiredContactTel: "【注】「連絡方法・電話」にチェックを入れた際は、電話番号を入力してください。",
			requiredContactFax: "【注】「連絡方法・FAX」にチェックを入れた際は、FAX番号を入力してください。",
			requiredRsvDate: "【注】第１希望の見学日時を入力してください。",
			requiredRsvDateSub: "【注】第２希望の見学日時を入力してください。"
			//email: "【注】正しいメールアドレスが入力されていません。"
		};

		//validateの独自メソッド定義
		var validateMethods = {
			requiredMultiText: validateCommonMethod,
			requiredMultiSelect: validateCommonMethod,
			requiredMultiCheck: validateCommonMethod,
			requiredAskSeltxt: validateAskSeltxt_Method,
			requiredContactTel: validateContactTel_Method,
			requiredContactFax: validateContactFax_Method,
			requiredRsvDate: validateRsvDate_Method,
			requiredRsvDateSub: validateRsvDateSub_Method
		};

		//フォーム要素にフォーカスしたかどうかを格納するハッシュ
		var validateFocusFlg = {};

		//validatetorに独自メソッド、エラーメッセージを追加
		for (var i in validateMethods) {
			var x = validateMethods[i];
			jQuery.validator.addMethod(i, x, "[E] Message not set.");
		}
		$.each(validateMessages, function(i, val) { validateMessages[i] = $.format(val); });
		jQuery.extend(jQuery.validator.messages, validateMessages);

		//validatorにclassによるルールを追加
		jQuery.validator.addClassRules({
			required: { required: true },
			required_multi_text: { requiredMultiText: true },
			required_multi_select: { requiredMultiSelect: true },
			required_multi_check: { requiredMultiCheck: true },
			required_AskSeltxt: { requiredAskSeltxt: true },
			required_ContactTel: { requiredContactTel: true },
			required_ContactFax: { requiredContactFax: true },
			required_RsvDate: { requiredRsvDate: true },
			required_RsvDateSub: { requiredRsvDateSub: true }
		});

		//validatorのデフォルトを設定する
		jQuery.validator.setDefaults({
			onclick: false,
			onkeyup: false,
			onfocusout: false,
			errorElement: "p",
			errorPlacement: function(error, element) {
				$($(element).parents('td')[0]).prepend(error);
			},
			highlight: function(element, errorClass) {
				var parentTd = $($(element).parents('td')[0]);
				parentTd.parent("tr").addClass("has_error");
				parentTd.removeClass("validate_ok");
			},
			unhighlight: function(element, errorClass) {
				var parentTd = $($(element).parents('td')[0]);
				parentTd.parent("tr").removeClass("has_error");
			},
			success: function(label) {
				var grp = $(label).attr("htmlfor");
				var cnt = 0;
				var parentTd = $(label).parent("td");
				parentTd.find("." + grp).each(function(){
					if(validateFocusFlg[$(this).attr("name")]) { cnt++	}
				});
				if(parentTd.find("." + grp).size() == cnt || $(parentTd.find("." + grp)[0]).attr("type") == "checkbox") {
					if(parentTd.hasClass('non_ok')){
						parentTd.removeClass('non_ok');
					}else{
						parentTd.addClass("validate_ok");
					}
				}
			}
		});

		//validateの独自判定メソッド
		function validateCommonMethod(value, element) {
			var classes = $(element).attr("class").split(" ");
			for(i = 0; i < classes.length; i++) {
				if(classes[i].indexOf("grp") == 0) {
					var c = classes[i];
					break;
				}
			}
			var parentTd = $($(element).parents('td')[0]);
			if(element.type == "checkbox") {
				return parentTd.find("." + c + ":checked").size() > 0;
			} else {
				var tmp = parentTd.find("." + c + ":filled").filter(checkFocus);
				var inp = 0;
				$.each(tmp, function(){
					if($(this).val()!=$(this).attr('lang')) inp++;
				});
				return parentTd.find("." + c).filter(checkFocus).size() == inp;
			}
		}
		function validateAskSeltxt_Method(value, element){
			var parentTd = $($(element).parents('td')[0]);
			var chk = $(element).parent().parent().find('input[type=checkbox]:checked');
			if(chk.length>0 && value==""){
				return false;
			}else{
				if(parentTd.find('input[type=checkbox]:checked').length==0){
					parentTd.addClass('non_ok').removeClass('validate_ok');
				}
				return true;
			}
		}
		function validateRsvDate_Method(value, element){
			var parentTd = $($(element).parents('td')[0]);
			var $this = $(element);
			var num = $this.attr('id').substr($this.attr('id').length-1);
			var date = $('input#date' + num);
			var time = $('input#time' + num);
			if(date.val()!='' && date.val()!=date.attr('lang') && time.val()!='' && time.val()!=time.attr('lang')){
				parentTd.removeClass('non_ok');
				return true;
			}else if($this.attr('id')!='time' + num && (time.val()=='' || time.val()==time.attr('lang'))){
				parentTd.addClass('non_ok');
				return true;
			}else{
				return false;
			}
		}
		function validateRsvDateSub_Method(value, element){
			var parentTd = $($(element).parents('td')[0]);
			var $this = $(element);
			var num = $this.attr('id').substr($this.attr('id').length-1);
			var date = $('input#date' + num);
			var time = $('input#time' + num);
			if(date.val()!='' && date.val()!=date.attr('lang') && time.val()!='' && time.val()!=time.attr('lang')){
				parentTd.removeClass('non_ok');
				return true;
			}else if($this.attr('id')=='time' + num && (date.val()!='' && date.val()!=date.attr('lang'))){
				return false;
			}else{
				parentTd.addClass('non_ok');
				return true;
			}
		}
		function validateContactTel_Method(value, element){
			var parentTd = $($(element).parents('td')[0]);
			return chkExtInput('tel', parentTd);
		}
		function validateContactFax_Method(value, element){
			var parentTd = $($(element).parents('td')[0]);
			return chkExtInput('fax', parentTd);
		}
		function chkExtInput(type, parentTd){
			var flg = true;
			var chk = $('input#cnt_' + type + ':checked');
			var vals = parentTd.find('#' + type + '1,#' + type + '2,#' + type + '3');
			$.each(vals, function(){
				if($(this).val()==''){flg = false;return false;}
			});
			if(flg){
				parentTd.addClass('validate_ok');
				return true;
			}else{
				parentTd.removeClass('validate_ok');
				if(chk.length>0){
					return false;
				}else{
					parentTd.addClass('non_ok');
					return true;
				}
			}
		}

		//filterのコールバック
		function checkFocus() {
			return validateFocusFlg[$(this).attr("name")] == true;
		}

		//ブラー時にvalidateする
		function validateOnBlur(selector) {
			$(selector).find(":input").filter("[class*='required']").not(":checkbox, :radio").each(function() {
				$(this).blur(function() {
					$(this).valid();
				});
			});
		}

		//checkbox、radioのときはクリック時にvalidateする
		function validateOnClick(selector) {
			$(selector).find(":checkbox, :radio").filter("[class*='required']").each(function() {
				$(this).click(function() {
					$(this).valid();
				});
			});
		}

		//classからグループ適用のためのハッシュ生成
		function getGroups(selector) {
			var elm = $(selector).find("[class*='grp']");
			var grpClass = [];
			elm.each(function(i){
				var classes = $(this).attr("class").split(" ");
				for(j = 0; j < classes.length; j++) {
					if(classes[j].indexOf("grp") == 0) {
						 var c = classes[j];
						 if(grpClass[grpClass.length - 1] != c) { grpClass.push(c) }
					}
				}
			});
			var groups = {};
			for(i = 0; i < grpClass.length; i++) {
				var grpElm = $(selector).find("[class*=" + grpClass[i]+ "]");
				var grpNameArr = [];
				grpElm.each(function() {
					grpNameArr.push($(this).attr("name"));
				});
				groups[grpClass[i]] = grpNameArr.join(" ");
			}
			return groups;
		}

		//フォーカスしたかどうかを調べる
		function getFocusFlg(selector) {
			$(selector).find(":input").filter("[class*='grp']").each(function() {
				$(this).focus(function() {
					validateFocusFlg[$(this).attr("name")] = true;
				});
			});
		}

		//ロード完了時に実行する処理
		$.validateInit = function(selector) {
			var itemGroups = getGroups(selector);
			$(selector).validate({ groups: itemGroups });
			validateOnBlur(selector);
			validateOnClick(selector);
			getFocusFlg(selector);
		}

		//郵便番号で住所を検索
		$(".js_search_address").click(function() {
			var box = $($(this).attr("href"));
			if(box.filter(':hidden').size()) {
				box.show();
				$("body").bind("click", box, hideAddressList);
			} else {
				box.hide();
				$("body").unbind("click", hideAddressList);
			}
			return false;
		});

		function hideAddressList(e) {
			e.data.hide();
			$("body").unbind("click", hideAddressList);
		}
	});
})(jQuery);
