
var Validator = {
   check: function(field, reg, extra) {
      var response;
      var rule = this.rule;
      var imp = false; //必須
	  rule.field = field;
      rule.value = field.value;
      rule.extra = extra;
	  
	  //必須
      if(!reg || !reg.match(/^!/)){
         response = rule.input();
		 //console.log(field);
	  }
      if(reg && !response && rule.value != '') {
         reg = reg.replace(/^!/, '');

         var mode = reg.split(/\s+/);
         for(var i = 0, m; m = mode[i]; i++) {
            m = m.replace(/([\d\-]+)?$/, '');
            response = rule[m](RegExp.$1);
            if(response) break;
         }
      }
	  //入力エラー
      if(response){
		 field.style.backgroundColor = '#FCC';
		 //必須チェックはバルーン表示無し
		 if(response == Validator.rule.msg.noinput){
			//バルーンが表示中のときはclose();
			if(field._validbaloon){
				field._validbaloon.close();
			}
		 	return;
		 }
         this.baloon.open(field, response);
		 
	  }
	  //正常
	  if(!response){
		  //Validator.baloon.element.prototype.box.create();
		  //$(document.getElementsByClassName('baloon')).fadeOut('slow');
		  //Validator.baloon.element.prototype.close();
		  field.style.backgroundColor = '#FFFFFF';
	  	  if(field._validbaloon) {
			 field._validbaloon.close();
		  }
	  }
   },
   //要素名の同じエレメントの選択チェック
   check_elem: function(parBox, elem) {
	   var cnt = elem.length;
	   var chk = false;
	   for(var i = 0;i < cnt;i++){
	   	 if(elem.item(i).checked){
			chk = true;
	     }
	   }
	   //非チェック
	   if(!chk){
	   		parBox.style.backgroundColor = '#FCC';
	   }else{//チェック
			parBox.style.backgroundColor = '#FFFFFF';
	   }
   },
   //セレクトボックスの値チェック
   check_sel_value: function(parBox, sel, v){
	   var idx = sel.selectedIndex;
	   var chk = false;
	   
	   if(sel.options[idx].value == v){
		  chk = true;
	   }
	   //指定の値
	   if(chk){
	   		parBox.style.backgroundColor = '#FCC';
	   }else{//それ以外
			parBox.style.backgroundColor = '#FFFFFF';
	   }
   },

   submit: function(form) {
      this.allclose(form);
      var btns = new Array;

      for(var i = 0, f; f = form[i]; i++) {
         if(f.onblur)
            f.onblur();
         if(f.type == 'submit')
            btns.push(f);
      }

      for(var i = 0, f, z; f = form[i]; i++) {
         if(f._validbaloon && f._validbaloon.visible()) {
            while(z = btns.shift())
               this.baloon.open(z, this.rule.submit());
            return false;
         }
      }

      return true;
   },

   allclose: function(form) {
      for(var i = 0, f; f = form[i]; i++)
         if(f._validbaloon) {
			 f._validbaloon.close();
		 }
   }
};

Validator.baloon = {
   index: 0,

   open: function(field, msg) {
      if(!field._validbaloon) {
         var obj = new this.element(field);
         obj.create();
         field._validbaloon = obj;
         if(field.type == 'radio' || field.type == 'checkbox') {
            for(var i = 0, e; e = field.form[field.name][i]; i++)
               addEvent(e, 'focus', function() { obj.close(); });
         }
      }
	  //エラーメッセージOPEN
      field._validbaloon.show(msg);
   },

   element: function() {
	  
      this.initialize.apply(this, arguments);
   }
};

Validator.baloon.element.prototype = {
   initialize: function(field) {
      this.parent = Validator.baloon;
      this.field = field;
   },

   create: function() {
      var field  = this.field;

      var box = document.createElement('div');
      box.className = 'baloon';

      var offset = Position.offset(field);
      
	  //var top  = offset.y - 25;
      //var left = offset.x - 20 + field.offsetWidth;
	  
	  //ダイアログ描画位置
	  var top  = offset.y - 30;
      var left = offset.x;
	  
      box.style.top  = top +'px';
      box.style.left = left+'px';

      var self = this;
      addEvent(box, 'click', function() { self.toTop(); });

      var bindClose = function() { 
		self.close(); 
	  };
      var link = document.createElement('a');
	  
	  /*IMGノード追加
	  var imgTag = document.createElement("img");
	  imgTag.src = "./img/close_001.gif";
	  imgTag.width = 15;
	  imgTag.height = 15;
	  imgTag.style.cssText = "border-style:none;";
	  link.appendChild(imgTag);
      */
	  
	  link.setAttribute('href', 'javascript:void(0);');
      addEvent(link, 'click', bindClose);
      addEvent(field, 'focus', bindClose);

      var msg = document.createElement('span');
      var div = document.createElement('div');
      div.appendChild(link);
      div.appendChild(msg);
      box.appendChild(div);
      document.body.appendChild(box);

      this.box = box;
      this.msg = msg;
   },

   show: function(msg) {
      var field = this.field;
      this.msg.innerHTML  = msg;

      this.box.style.display = '';
      this.toTop();

      if(field.type != 'radio' && field.type != 'checkbox') {
         var colors = new Array('#FF6666', '#FFAAAA', '#FF6666', '#FFAAAA');
         window.setTimeout(function() {
            if(colors.length > 0) {
               //field.style.backgroundColor = colors.shift();
               //window.setTimeout(arguments.callee, 70);
            }
         }, 10);
      }
   },

   close: function() {
      //this.box.style.display = 'none';
	  //console.log(this.box);
	  $(this.box).fadeOut('slow');
      //this.field.style.backgroundColor = '';
   },

   visible: function() {
      return (this.box.style.display == '');
   },

   toTop: function() {
      this.box.style.zIndex = ++ this.parent.index;
   }
};

Validator.rule = {
   msg: null,

   submit: function() {
      return this.msg.submit;
   },

   input: function() {
      if(this.field.type == 'radio' || this.field.type == 'checkbox') {
         for(var i = 0, e; e = this.field.form[this.field.name][i]; i++)
            if(e.checked) return;
         return this.msg.noselect;
      } else if(this.value == '')
         return (this.field.type == 'select-one') ? this.msg.noselect : this.msg.noinput;
   },

   mail: function() {
      if(!this.value.match(/^[\x01-\x7F]+@((([-a-z0-9]+\.)*[a-z]+)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))$/))
         return this.msg.mail;
   },

   equal: function() {
      if(this.field.form[this.extra].value && this.value != this.field.form[this.extra].value)
         return this.msg.unequal;
   },

   alphabet: function() {
      //if(!this.value.match(/^[a-zA-Z\-\d]+$/)) //ハイフンあり
	  if(!this.value.match(/^[a-zA-Z\d]+$/)) //ハイフンなし
         return this.msg.alphabet;
   },
   //全角カタカナ
   kana: function() {
      for(var i = 0;i < this.value.length;i++) {
         if(this.value.charAt(i) == ' ' || this.value.charAt(i) == '\u3000') continue;
         if(this.value.charAt(i) < '\u30A1' || this.value.charAt(i) > '\u30F6')
            return this.msg.kana;
      }
   },
   //全角ひらがな
   KANA: function() {
      for(var i = 0;i < this.value.length;i++) {
         if(this.value.charAt(i) == ' ' || this.value.charAt(i) == '\u3000') continue;
         //全角かな(ぁ〜ん)
		 if(this.value.charAt(i) < '\u3041' || this.value.charAt(i) > '\u3093'){
            return this.msg.KANA;
		 }
	  }
   },
   //日本語(全角かな&全角カナ&漢字)
   japan_names: function() {
      for(var i = 0;i < this.value.length;i++) {
		 //空白はcontinue
         if(this.value.charAt(i) == ' ' || this.value.charAt(i) == '\u3000'){
			 continue;
		 }
		 //全角カナ(ァ〜ヶ)
		 if(this.value.charAt(i) < '\u30A1' || this.value.charAt(i) > '\u30F6'){
			//全角かな(ぁ〜ん)
			if(this.value.charAt(i) < '\u3041' || this.value.charAt(i) > '\u3093'){
				//漢字(一〜龍)
				if(this.value.charAt(i) < '\u4E00' || this.value.charAt(i) > '\u9F8D'){
            		return this.msg.japan_names;
				}
			}
		 }
      }
   },

   count: function(arg) {
      return this._range(arg, this.value.length, this.msg.count);
   },

   num: function(arg) {
      if(!this.value.match(/^[\d]+$/))
         return this.msg.num.nonumber;

      return this._range(arg, parseInt(this.value), this.msg.num);
   },

   check: function(arg) {
      var value = 0;
      for(var i = 0, e; e = this.field.form[this.field.name][i]; i++)
         if(e.checked) value += 1;

      return this._range(arg, value, this.msg.check);
   },

   _range: function(range, value, msg) {
      if(!range) return;

      var result = '';
      var c = (" "+range).split(/\-/);
      var min = parseInt(c[0]) || 0;
      var max = parseInt(c[1]) || 0;

      if(value != min && /^\d+$/.test(range))
         result = msg.unequal;
      else if(min == 0 && value > max)
         result = msg.too_big;
      else if(max == 0 && value < min)
         result = msg.too_small;
      else if(min > 0 && max > 0 && (value < min || value > max))
         result = msg.outofrange;

      return result.replace(/%1/g, min).replace(/%2/g, max);
   }
};

Validator.lang = {
   ja: {
      noselect:   '\u9078\u629E\u304C\u5FC5\u8981\u3067\u3059\u3002',
      noinput:    '\u5165\u529B\u304C\u5FC5\u8981\u3067\u3059\u3002',
      unequal:    '\u5165\u529B\u304C\u63C3\u3063\u3066\u3044\u307E\u305B\u3093\u3002',
   
      submit:     '\u5165\u529B\u30A8\u30E9\u30FC\u304C\u3042\u308A\u307E\u3059\u3002',
	  //正しいメールアドレスを入力してください。
      mail:       '\u6B63\u3057\u3044\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002',
	  
	  alphabet:   '\u30A2\u30EB\u30D5\u30A1\u30D9\u30C3\u30C8\u3001\u534A\u89D2\u6570\u5B57\u4EE5\u5916\u306F\u5165\u529B\u3067\u304D\u307E\u305B\u3093\u3002',
	  //全角カタカナで入力してください。
      kana:       '\u5168\u89D2\u30AB\u30BF\u30AB\u30CA\u3067\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
	  //全角ひらがなで入力してください。
	  KANA:       '\u5168\u89D2\u3072\u3089\u304C\u306A\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002',
	  //氏名を正しく入力してください。
	  japan_names:       '\u6C0F\u540D\u3092\u6B63\u3057\u304F\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002',
      
	  count: {
         unequal:    '%1'+'\u6587\u5B57\u3067\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         too_big:    '%2'+'\u6587\u5B57\u4EE5\u5185\u3067\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         too_small:  '%1'+'\u6587\u5B57\u4EE5\u4E0A\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         outofrange: '%1'+'\u304B\u3089'+'%2'+'\u6587\u5B57\u306E\u9593\u3067\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002'
      },
   
      num: {
         nonumber:   '\u534A\u89D2\u6570\u5B57\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002',
         unequal:    '%1'+'\u3068\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         too_big:    '%2'+'\u4EE5\u4E0B\u306E\u5024\u3092\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         too_small:  '%1'+'\u4EE5\u4E0A\u306E\u5024\u3092\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         outofrange: '%1'+'\u304B\u3089'+'%2'+'\u306E\u9593\u3067\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\u3002'
      },
   
      check: {
         unequal:    '\u30C1\u30A7\u30C3\u30AF\u306F'+'%1'+'\u500B\u3057\u3066\u4E0B\u3055\u3044\u3002',
         too_big:    '\u30C1\u30A7\u30C3\u30AF\u306F'+'%2'+'\u500B\u307E\u3067\u3067\u3059\u3002',
         too_small:  '\u30C1\u30A7\u30C3\u30AF\u306F'+'%1'+'\u500B\u4EE5\u4E0A\u3057\u3066\u4E0B\u3055\u3044\u3002',
         outofrange: '\u30C1\u30A7\u30C3\u30AF\u306F'+'%1'+'\u500B\u304B\u3089'+'%2'+'\u500B\u307E\u3067\u3067\u3059\u3002'
      }
   }
};

Validator.rule.msg = Validator.lang.ja;

