/**
@fileOverview  jQuery Extentions for NBS LiveValidation
@name          jquery.nbs.lv.ajax
@author        (RECRUIT.co., LTD.
*/
;(function(){
	jQuery.lvconfig = {
		bgColor          : "#FFFFFF",
		errorBgColor     : "PEACHPUFF",
		fadeInTime       : 1*1000,
		fadeOutTime      : 1*1000,
		lvUrl            : "",
		complexLvUrl     : "",
		timeout          : 10*1000,
		maxActiveRequest : 1,
		maxLvErrorCount  : 5
	};

	jQuery.lvscope = {
		lvErrorCount	: 0
	};

})(jQuery);

;(function() {
	jQuery.fn.showNoteMsg = function() {
		this.parent().siblings(".noteMsg").fadeIn(jQuery.lvconfig.fadeInTime);
	}

	jQuery.fn.eraseNoteMsg = function() {
		this.parent().siblings(".noteMsg").css("display", "none");
	}

	jQuery.fn.showErrMsg = function(err_msg) {
		if (err_msg.length == 0)
			return;

		this.parent().siblings(".errMsg").fadeIn(jQuery.lvconfig.fadeInTime);
 		this.parent().siblings(".errMsg").append(err_msg[0]);

		if (err_msg.length >= 1) {
			for (var i = 1; i < err_msg.length; i++) {
		 		this.parent().siblings(".errMsg").append($("<br>"));
	 			this.parent().siblings(".errMsg").append(err_msg[i]);
			}
		}
	}

	jQuery.fn.eraseErrMsg = function() {
		this.parent().siblings(".errMsg").css("display", "none");
		this.parent().siblings(".errMsg").empty();
	}

	jQuery.fn.renderInputNow = function() {
		if(this.parent().siblings(".iconValidNow").css("display") == "none"
			&&  this.parent().siblings(".iconOk").css("display") == "none"
				&& this.parent().siblings(".iconNg").css("display") == "none"){
			this.parent().css("background-color", jQuery.lvconfig.bgColor);
			this.parent().siblings(".iconValidNow").css("display", "none");
			this.parent().siblings(".iconOk").css("display", "none");
			this.parent().siblings(".iconNg").css("display", "none");
			this.eraseErrMsg();
			this.showNoteMsg();
		}
	}

	jQuery.fn.renderValidNow = function(err_msg){
		this.eraseErrMsg();
		this.parent().parent().parent().css("background-color", jQuery.lvconfig.bgColor);
		this.parent().css("background-color", jQuery.lvconfig.bgColor);
		this.parent().siblings(".iconValidNow").css("display", "inline");
		this.parent().siblings(".iconOk").css("display", "none");
		this.parent().siblings(".iconNg").css("display", "none");
	}

	jQuery.fn.renderTrue = function(){
		this.parent().parent().parent().css("background-color", jQuery.lvconfig.bgColor);
		this.parent().css("background-color", jQuery.lvconfig.bgColor);
		this.parent().siblings(".iconValidNow").css("display", "none");
		this.parent().siblings(".iconOk").css("display", "inline");
		this.parent().siblings(".iconNg").css("display", "none");
		this.showNoteMsg();
		this.eraseErrMsg();
	}

	jQuery.fn.renderFalse = function(err_msg){
		this.parent().parent().parent().css("background-color", jQuery.lvconfig.errorBgColor);
		this.parent().css("background-color", jQuery.lvconfig.errorBgColor);
		this.parent().siblings(".iconValidNow").css("display", "none");
		this.parent().siblings(".iconOk").css("display", "none");
		this.parent().siblings(".iconNg").css("display", "inline");
		this.eraseNoteMsg();
		this.showErrMsg(err_msg);
	}

	jQuery.fn.renderClear = function(){
		this.parent().parent().parent().css("background-color", jQuery.lvconfig.bgColor);
		this.parent().css("background-color", jQuery.lvconfig.bgColor);
		this.parent().siblings(".iconValidNowNow").fadeOut(jQuery.lvconfig.fadeOutTime);
		this.parent().siblings(".iconOk").fadeOut(jQuery.lvconfig.fadeOutTime);
		this.parent().siblings(".iconNg").fadeOut(jQuery.lvconfig.fadeOutTime);
		this.eraseErrMsg();
		this.showNoteMsg();
	}
})(jQuery);

;(function(){
	jQuery.fn.liveValidate = function(propertyObj){
		var target = this;
		if(jQuery.lvscope.lvErrorCount < jQuery.lvconfig.maxLvErrorCount){
			jQuery.ajax({
				type	 :	"POST",
				dataType : 	"json",
				url      : 	jQuery.lvconfig.lvUrl,
				data	 : 	propertyObj,
				timeout  : 	jQuery.lvconfig.timeout,
				cache	 :	false,
				beforeSend 	: function(xhr){
								if(jQuery.active > jQuery.lvconfig.maxActiveRequest){
									/* beforeSendオプションのコールバック関数で戻り値にfalseを設定すると送信がキャンセルされます。 */
									return false;
								}
								jQuery(target).renderValidNow();
							  },
				success	: 	function(response, status){
								jQuery.lvscope.lvErrorCount = 0;
								if (response.result.length == 0) {
									jQuery(target).renderTrue();
								} else {
									jQuery(target).renderFalse(response.result);
								}
							},
				error	:	function(xhr, status, exception){
								jQuery.lvscope.lvErrorCount++;
							},
				complete :	function(xhr, status){
								if(status == "success"){
									return;
								} else if(status == "error"){
									jQuery(target).renderClear();
									alert("サーバと通信する過程でエラーが発生しました。");
									return;
								} else if(status == "notmodified"){
									jQuery(target).renderClear();
									alert("以前と同じデータが送信されたため、その時の結果が再度表示されました。");
									return;
								} else if(status == "timeout"){
									jQuery(target).renderClear();
									alert("タイムアウトが発生しました。\n\rアクセスが集中している可能性があります。\n\rお手数ですがしばらく待ってから、再度アクセスして下さい。");
									return;
								} else if(status == "parsererror"){
									jQuery(target).renderClear();
									alert("データの解析に失敗しました。");
									return;
								} else {
									jQuery(target).renderClear();
								}
							}
			});

		} else if(jQuery.lvscope.lvErrorCount == jQuery.lvconfig.maxLvErrorCount){
			jQuery.lvscope.lvErrorCount++;
			alert("リアルタイムで入力項目をチェックする機能が正常に動作していません。\n\rリアルタイムのチェック機能をオフにします。\n\r※ボタンを押していただくと入力項目のチェックを実行します。");
		}
	}

	jQuery.fn.complexLiveValidate = function(reqObj){
		var target = this;
		if(jQuery.lvscope.lvErrorCount < jQuery.lvconfig.maxLvErrorCount){
			jQuery.ajax({
				type	 :	"POST",
				dataType : 	"json",
				url      : 	jQuery.lvconfig.complexLvUrl,
				data	 : 	reqObj,
				timeout  : 	jQuery.lvconfig.timeout,
				cache	 :	false,
				beforeSend 	: function(xhr){
								if(jQuery.active > jQuery.lvconfig.maxActiveRequest){
									return false;
								}
								jQuery(target).renderValidNow();
							  },
				success	: 	function(response, status){
								jQuery.lvscope.lvErrorCount = 0;
								if (response.result.length == 0) {
									jQuery(target).renderTrue();
								} else {
									jQuery(target).renderFalse(response.result);
								}
							},
				error		: function(xhr, status, exception){
								/*
								jQuery(target).renderClear();
								return;
								*/
								jQuery.lvscope.lvErrorCount++;
							},
				complete 	: function(xhr, status){
								if(status == "success"){
									return;
								} else if(status == "error"){
									jQuery(target).renderClear();
									alert("サーバと通信する過程でエラーが発生しました。");
									return;
								} else if(status == "notmodified"){
									jQuery(target).renderClear();
									alert("以前と同じデータが送信されたため、その時の結果が再度表示されました。");
									return;
								} else if(status == "timeout"){
									jQuery(target).renderClear();
									alert("タイムアウトが発生しました。\n\rアクセスが集中している可能性があります。\n\rお手数ですがしばらく待ってから、再度アクセスして下さい。");
									return;
								} else if(status == "parsererror"){
									jQuery(target).renderClear();
									alert("データの解析に失敗しました。");
									return;
								} else {
									jQuery(target).renderClear();
								}
							}
			});

		} else if(jQuery.lvscope.lvErrorCount == jQuery.lvconfig.maxLvErrorCount){
			jQuery.lvscope.lvErrorCount++;
			alert("リアルタイムで入力項目をチェックする機能が正常に動作していません。\n\rリアルタイムのチェック機能をオフにします。\n\r※ボタンを押していただくと入力項目のチェックを実行します。");
		}
	}
})(jQuery);

var nbs = {
	util : {
		isNoU: function(value){
			return value === null || value === void 0;
		},

		instanceOf: function(value, type){
			return ! nbs.util.isNoU(value) && value.constructor === type;
		},

		isString: function(value){
			return nbs.util.instanceOf(value, String);
		},

		isArray: function(value){
			return nbs.util.instanceOf(value, Array);
		},

		isNumber: function(value){
			return nbs.util.instanceOf(value, Number);
		},

		isBoolean: function(value){
			return nbs.util.instanceOf(value, Boolean);
		},

		isFunction: function(value){
//			return typeof value === "function" || $.isFunction(value);
			return typeof value === "function" || $.isFunction(value);
		},

		isEmpty : function(value){
			if(nbs.util.isNoU(value) || value.length === 0 || value === ""){
				return true;
			}
			return false;
		},

		isNotEmpty : function(value){
			return ! nbs.util.isEmpty(value);
		},

		apply: function(base){
			if(base){
				for(var a=arguments,i=1,m=a.length; i<m; i++){
					var v = a[i];
					for(var p in v){
						base[p] = v[p];
					}
				}
			}
			return base;
		},

		interceptor : function(fn, advices){
			var contextClass = function(){};
			nbs.util.apply(contextClass.prototype, {
				fn : fn,
				proceed : function(){
					return this.fn.apply(this.scope, this.args);
				}
			});
			return function(){
				var context = new contextClass();
				context.scope = this;
				context.args = arguments;
				if(nbs.util.isFunction(advices.before)){
					advices.before.apply(context, arguments);
				}
				var r = nbs.util.isFunction(advices.around)
						?advices.around.apply(context, arguments)
						:fn.apply(this, arguments)
				if(nbs.util.isFunction(advices.after)){
					advices.after.apply(context, arguments);
				}
				return r;
			};
		},

		insert: function(array, indexValue, value){
			var index = -1;
			for(var i=0, m=array.length; i<m; i++){
				if(array[i] === indexValue){
					index = i;
					break;
				}
			}
			return index === -1?array:array.splice(index, 0, value);
		},

		inspect: function(value, includes){
			if( ! nbs.util.isNoU(value)){
				var props = [];
				includes = includes || new RegExp(".*");
				for(var n in value){
					if(n.match(includes)){
						props.push(n);
					}
				}
				props.sort();
				alert(props.join("\n"));
			}
		},

		sanitize: function(str){
			return str.replace(/&/g, "&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
		}
	}
}

