/*
 * Inline Form Validation Engine, jQuery plugin
 *
 * Copyright(c) 2009, Cedric Dugas
 * http://www.position-relative.net
 *
 * Form validation engine witch allow custom regex rules to be added.
 * Licenced under the MIT Licence
 */

$(document).ready(function() {

  // SUCCESS AJAX CALL, replace "success: false," by:     success : function() { callSuccessFunction() },
  $("[class^=validate]").validationEngine({
    success :  false,
    promptPosition : "centerLeft",
    failure : function() {}
  })
});

jQuery.fn.validationEngine = function(settings) {
  if($.validationEngineLanguage){         // IS THERE A LANGUAGE LOCALISATION ?
    allRules = $.validationEngineLanguage.allRules
  }else{
    allRules = {"required":{            // Add your regex rules here, you can take telephone as an example
              "regex":"none",
              "alertText":"This field is required",
              "alertTextCheckboxMultiple":"Please select an option",
              "alertTextCheckboxe":"This checkbox is required"},
            "length":{
              "regex":"none",
              "alertText":"Between ",
              "alertText2":" and ",
              "alertText3": " characters allowed"},
            "maxCheckbox":{
              "regex":"none",
              "alertText":"Maximum ",
              "alertText2":" selctions "},
            "minCheckbox":{
              "regex":"none",
              "alertText":"Minimum ",
              "alertText2":" selctions "},
            "eqCheckbox":{
              "regex":"none",
              "alertText":"Please select ",
              "alertText2":" options "},
            "confirm":{
              "regex":"none",
              "alertText":"Your field is not matching"},
            "telephone":{
              "regex":"/^[0-9\-\(\)\+\ ]+$/",
              "alertText":"Please enter a valid phone number"},
            "email":{
              "regex":"/^[a-zA-Z0-9_\.\-]+\@([a-zA-Z0-9\-]+\.)+[a-zA-Z0-9]{2,4}$/",
              "alertText":"Please enter a valid email address"},
            "date":{
                             "regex":"/^[0-9]{4}\-\[0-9]{1,2}\-\[0-9]{1,2}$/",
                             "alertText":"Invalid date, must be in YYYY-MM-DD format"},
            "onlyNumber":{
              "regex":"/^[0-9\ ]+$/",
              "alertText":"Please only enter numbers"},
            "noSpecialCaracters":{
              "regex":"/^[0-9a-zA-Z]+$/",
              "alertText":"No special characters allowed"},
            "onlyLetter":{
              "regex":"/^[a-zA-Z\ \']+$/",
              "alertText":"Please only enter letters"},
						"message":{
							"regex":"/^((?!http).)*$/mi",
              "alertText":"Please don't put links in your message"}
          }
  }

  settings = jQuery.extend({
    allrules:allRules,
    inlineValidation: true,
    success : false,
    failure : function() {}
  }, settings);

  $("form").bind("submit", function(caller){   // ON FORM SUBMIT, CONTROL AJAX FUNCTION IF SPECIFIED ON DOCUMENT READY
    if(submitValidation(this) == false){
      if (settings.success){
        settings.success && settings.success();
        return false;
      }
    }else{
      settings.failure && settings.failure();
      return false;
    }
  })
  if(settings.inlineValidation == true){    // Validating Inline ?


    $(":checkbox").bind("click", function(caller){loadValidation(this)})
    $(":radio").bind("click", function(caller){loadValidation(this)})
    //$(this+"[type=radio]").bind("click", function(caller){loadValidation(this)})
    //$(this).not("[type=checkbox]").bind("blur", function(caller){loadValidation(this)})
    $(this).bind("keydown", function(caller){ if($(this).val().length>0)loadValidation(this) })
    $(this).bind("blur", function(caller){
			if( $(this).val().length>0)loadValidation(this)})
  }
  var buildPrompt = function(caller,promptText,showTriangle) {      // ERROR PROMPT CREATION AND DISPLAY WHEN AN ERROR OCCUR
    var divFormError = document.createElement('div')
    var formErrorContent = document.createElement('div')
    var arrow = document.createElement('div')


    $(divFormError).addClass("formError")
    $(divFormError).addClass($(caller).attr("id"))
    $(formErrorContent).addClass("formErrorContent")
    $(arrow).addClass("formErrorArrow")

    callerTopPosition = $(caller).offset().top;
    callerleftPosition = $(caller).offset().left;
    callerLeftPadding = parseInt($(caller).css("padding-left").replace("px",""))
    callerRightPadding = parseInt($(caller).css("padding-right").replace("px",""))
    callerTopPadding = parseInt($(caller).css("padding-top").replace("px",""))
    callerBottomPadding = parseInt($(caller).css("padding-bottom").replace("px",""))
    callerParentTopMargin = parseInt($(caller).parent().css("margin-top").replace("px",""))
    callerWidth =  $(caller).width() + callerLeftPadding + callerRightPadding
    callerHeight =  $(caller).height() + callerTopPadding + callerBottomPadding
    inputHeight = $(caller).height() + callerTopPadding + callerBottomPadding
    //callerBorderColor = $(caller).css("border-color");



    if ($(caller).attr('type')=='checkbox' || $(caller).attr('type')=='radio' ) {
      callerTopPadding = callerBottomPadding = 4
      if ($(caller).parents(".options").length >= 1) {
        optionsDiv = $(caller).parents(".options");
        callerleftPosition = callerleftPosition + $(optionsDiv).width() + 7
        callerTopPosition = callerTopPosition + $(optionsDiv).height()/2 - 10 - callerTopPadding - callerBottomPadding

      } else {
        label = $(caller).next(".label")
        callerleftPosition = callerleftPosition + $(label).width() + 30
      }

    } else {
      //callerleftPosition = callerleftPosition - callerWidth -204;
      callerleftPosition = 320;
      callerTopPosition = callerTopPosition + inputHeight/2 - 38
    }
     //callerTopPosition

    $("body").append(divFormError)
    $(divFormError).append(arrow)
    $(divFormError).append(formErrorContent)

    $(formErrorContent).html(promptText)

    $(divFormError).css({
      top:callerTopPosition,
      left:callerleftPosition,
      //height:inputHeight,
      opacity:0
    })

    /*$(formErrorContent).css({
      //height:inputHeight,
      'padding-top':callerTopPadding,
      'padding-bottom':callerBottomPadding

    })*/

    if(showTriangle == true){   // NO TRIANGLE ON MAX CHECKBOX AND RADIO
      //$(arrow).html('<div class="line10" style="top:'+(Math.ceil(inputHeight/2))+'px;"></div><div class="line9" style="top:'+((Math.ceil(inputHeight/2))-1)+'px;"></div><div class="line8" style="top:'+((Math.ceil(inputHeight/2))-2)+'px;"></div><div class="line7"  style="top:'+((Math.ceil(inputHeight/2))-3)+'px;"></div><div class="line6"  style="top:'+((Math.ceil(inputHeight/2))-4)+'px;"></div><div class="line5"  style="top:'+((Math.ceil(inputHeight/2))-5)+'px;"></div><div class="line4"  style="top:'+((Math.ceil(inputHeight/2))-6)+'px;"></div><div class="line3"  style="top:'+((Math.ceil(inputHeight/2))-7)+'px;"></div><div class="line2"  style="top:'+((Math.ceil(inputHeight/2))-8)+'px;"></div><div class="line1"  style="top:'+((Math.ceil(inputHeight/2))-9)+'px;"></div>');
      //$(arrow).html('<div class="line10" style="top:12px;"></div><div class="line9" style="top:11px;"></div><div class="line8" style="top:10px;"></div><div class="line7"  style="top:9px;"></div><div class="line6"  style="top:8px;"></div><div class="line5"  style="top:7px;"></div><div class="line4"  style="top:6px;"></div><div class="line3"  style="top:5px;"></div><div class="line2"  style="top:4px;"></div><div class="line1"  style="top:3px;"></div>');
    }
    if ($(caller).attr('type')=='checkbox' || $(caller).attr('type')=='radio' ) {
      if ($(caller).parents(".options").length >= 1) {
        $(optionsDiv).css({
          //'margin-top':'30px'
          //border:'1px solid rgb(220,78,67)'
        });
      } else {

      }
    } else {
      $(caller).css({
        //border:'1px solid rgb(220,78,67)'
        //background:'rgb(255,200,200)'
      });
    }
    $(divFormError).fadeTo("fast",1);

  };
  var updatePromptText = function(caller,promptText) {  // UPDATE TEXT ERROR IF AN ERROR IS ALREADY DISPLAYED
    updateThisPrompt =  $(caller).attr("id")
    $("."+updateThisPrompt).find(".formErrorContent").html(promptText)

    callerTopPosition  = $(caller).offset().top;
    inputHeight = $("."+updateThisPrompt).height()
    if ($(caller).attr('type')=='checkbox' || $(caller).attr('type')=='radio' ) {


    } else {
      callerTopPosition = callerTopPosition  -inputHeight -10
    }
    /*$("."+updateThisPrompt).animate({
      top:callerTopPosition
    });*/
  }
  var loadValidation = function(caller) {   // GET VALIDATIONS TO BE EXECUTED

    rulesParsing = $(caller).attr('class');
    rulesRegExp = /\[(.*)\]/;
    getRules = rulesRegExp.exec(rulesParsing);
    str = getRules[1]
    pattern = /\W+/;
    result= str.split(pattern);

    var validateCalll = validateCall(caller,result)
    return validateCalll

  };
  var validateCall = function(caller,rules) { // EXECUTE VALIDATION REQUIRED BY THE USER FOR THIS FIELD
    var promptText =""
    var prompt = $(caller).attr("id");
    var caller = caller;
    var callerName = $(caller).attr("name");
    isError = false;
    callerType = $(caller).attr("type");

    for (i=0; i<rules.length;i++){
      switch (rules[i]){
      case "optional":
        if(!$(caller).val()){
          closePrompt(caller)
          return isError
        }
      break;
      case "required":
        _required(caller,rules);
      break;
      case "custom":
         _customRegex(caller,rules,i);
      break;
      case "length":
         _length(caller,rules,i);
      break;
      case "minCheckbox":
         _minCheckbox(caller,rules,i);
      break;
      case "maxCheckbox":
         _maxCheckbox(caller,rules,i);
      break;
      case "eqCheckbox":
         _eqCheckbox(caller,rules,i);
      break;
      case "confirm":
         _confirm(caller,rules,i);
      break;
      default :;
      };
    };
    if (isError == true){
      var showTriangle = true
      if($("input[name="+callerName+"]").size()> 1 && callerType == "radio") {    // Hack for radio group button, the validation go the first radio
        caller = $("input[name="+callerName+"]:first")
        //showTriangle = false
        var callerId ="."+ $(caller).attr("id")
        if($(callerId).size()==0){ isError = true }else{ isError = false}
      }
      if($("input[name="+callerName+"]").size()> 1 && callerType == "checkbox") {   // Hack for radio group button, the validation go the first radio
        caller = $("input[name="+callerName+"]:first")
        //showTriangle = false
        var callerId ="div."+ $(caller).attr("id")
        if($(callerId).size()==0){ isError = true }else{ isError = false}
      }
      if (isError == true){ // show only one
        ($("div."+prompt).size() ==0) ? buildPrompt(caller,promptText,showTriangle) : updatePromptText(caller,promptText)
      }
    }else{
      if($("input[name="+callerName+"]").size()> 1 && callerType == "radio") {    // Hack for radio group button, the validation go the first radio
        caller = $("input[name="+callerName+"]:first")
      }
      if($("input[name="+callerName+"]").size()> 1 && callerType == "checkbox") {   // Hack for radio group button, the validation go the first radio
        caller = $("input[name="+callerName+"]:first")
      }
      closePrompt(caller)
    }

    /* VALIDATION FUNCTIONS */
    function _required(caller,rules){   // VALIDATE BLANK FIELD
      callerType = $(caller).attr("type")

      if (callerType == "text" || callerType == "password" || callerType == "textarea"){

        if(!$(caller).val()){
          isError = true
          callerName = $(caller).attr("id");
          callerMessage = $('#'+callerName+'_message');
          messageText = callerMessage.html();
          if (messageText) {
            promptText = messageText
          } else {
            promptText += settings.allrules[rules[i]].alertText+"<br />"
          }
        }
      }
      if (callerType == "radio" || callerType == "checkbox" ){
        callerName = $(caller).attr("name")

        if($("input[name="+callerName+"]:checked").size() == 0) {
          isError = true
          if($("input[name="+callerName+"]").size() ==1) {
            promptText += settings.allrules[rules[i]].alertTextCheckboxe+"<br />"
          }else{
             promptText += settings.allrules[rules[i]].alertTextCheckboxMultiple+"<br />"
          }
        }
      }
      if (callerType == "select-one") { // added by paul@kinetek.net for select boxes, Thank you
          callerName = $(caller).attr("id");

        if(!$("select[name="+callerName+"]").val()) {
          isError = true;
          promptText += settings.allrules[rules[i]].alertText+"<br />";
        }
      }
      if (callerType == "select-multiple") { // added by paul@kinetek.net for select boxes, Thank you
          callerName = $(caller).attr("id");

        if(!$("#"+callerName).val()) {
          isError = true;
          promptText += settings.allrules[rules[i]].alertText+"<br />";
        }
      }
    }
    function _customRegex(caller,rules,position){    // VALIDATE REGEX RULES
      customRule = rules[position+1]
      pattern = eval(settings.allrules[customRule].regex)

      if(!pattern.test($(caller).attr('value'))){
        isError = true
        promptText += settings.allrules[customRule].alertText+"<br />"
      }
    }
    function _confirm(caller,rules,position){    // VALIDATE FIELD MATCH
      confirmField = rules[position+1]

      if($(caller).attr('value') != $("#"+confirmField).attr('value')){
        isError = true
        promptText += settings.allrules["confirm"].alertText+"<br />"
      }
    }
    function _length(caller,rules,position){    // VALIDATE LENGTH

      startLength = eval(rules[position+1])
      endLength = eval(rules[position+2])
      feildLength = $(caller).attr('value').length

      if(feildLength<startLength || feildLength>endLength){
        isError = true
        promptText += settings.allrules["length"].alertText+startLength+settings.allrules["length"].alertText2+endLength+settings.allrules["length"].alertText3+"<br />"
      }
    }
    function _minCheckbox(caller,rules,position){    // VALIDATE CHECKBOX NUMBER

      nbCheck = eval(rules[position+1])

      groupname = $(caller).attr("name")
      groupSize = $("input[name="+groupname+"]:checked").size()

      if(groupSize < nbCheck){
        isError = true
        promptText += settings.allrules["minCheckbox"].alertText + nbCheck + settings.allrules["minCheckbox"].alertText2+"<br />"
      }
    }

    function _maxCheckbox(caller,rules,position){    // VALIDATE CHECKBOX NUMBER

      nbCheck = eval(rules[position+1])

      groupname = $(caller).attr("name")
      groupSize = $("input[name="+groupname+"]:checked").size()

      if(groupSize > nbCheck){
        isError = true
        promptText += settings.allrules["maxCheckbox"].alertText + nbCheck + settings.allrules["maxCheckbox"].alertText2+"<br />"
      }
    }
    function _eqCheckbox(caller,rules,position){    // VALIDATE CHECKBOX NUMBER

      nbCheck = eval(rules[position+1])

      groupname = $(caller).attr("name")
      groupSize = $("input[name="+groupname+"]:checked").size()

      if(groupSize != nbCheck){
        isError = true
        promptText += settings.allrules["eqCheckbox"].alertText + nbCheck + settings.allrules["eqCheckbox"].alertText2+"<br />"
      }
    }
    return(isError) ? isError : false;
  };
  var closePrompt = function(caller) {  // CLOSE PROMPT WHEN ERROR CORRECTED
    closingPrompt = $(caller).attr("id")
    if ($(caller).attr('type')=='checkbox' || $(caller).attr('type')=='radio' ) {
      if ($(caller).parents(".options").length >= 1) {
        optionsDiv = $(caller).parents(".options");
        $(optionsDiv).css({
          border: '1px solid white'
        });
      } else {

      }
    } else {

      /*$(caller).css({
        'border-color': callerBorderColor//'rgb(81,158,75)',//callerBorder
        //background:'rgb(168,216,160)'
      });*/
      //alert (callerBorderColor);
      $(caller).animate({backgroundColor: '#ffffff' },400);
    }
    $("."+closingPrompt).fadeTo("fast",0,function(){
      $("."+closingPrompt).remove()
    });
  };
  var submitValidation = function(caller) { // FORM SUBMIT VALIDATION LOOPING INLINE VALIDATION
    var stopForm = false
    $(caller).find(".formError").remove()
    var toValidateSize = $(caller).find("[class^=validate]").size()

    $(caller).find("[class^=validate]").each(function(){
      var validationPass = loadValidation(this)
      return(validationPass) ? stopForm = true : "";
    });
    if(stopForm){             // GET IF THERE IS AN ERROR OR NOT FROM THIS VALIDATION FUNCTIONS
      destination = $(".formError:first").offset().top;
      $("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, 1100)
      return true;
    }else{
      return false
    }
  };
};
