/* $Id: formchecker.js,v 1.9 2009-09-17 14:43:17 jasper Exp $ */

var lang = {
	dateParts: { "year": "jjjj", "month": "mm", "day": "dd" }
, dateRegs: { "year": "[0-9]{4}", "month": "[0-3]?[0-9]", "day": "[0-3]?[0-9]" }
, daysAbbr: ["ma","di","wo","do","vr","za","zo"]
, monthsFull: ["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"]
, inputErrors: "Er zijn fouten gevonden in de invoer"
, inputRequired: "Dit veld is verplicht"
, inputInvalid: "Dit veld heeft geen geldige waarde"
, inputCharsLeft: "%1 / %2 karakters"
, inputClassHelp: {
		"postcode": "Een postcode moet 4 cijfer en 2 letters bevatten. Bijvoorbeeld <code>1234 AB</code>"
	,	"datum": "Een datum moet in het formaat <code>dd-mm-jjjj</code> opgegeven worden. Bijvoorbeeld <code>31-12-2008</code>"
	,	"gsm": "Een 06-nummer moet in het formaat <code>06-12345678</code> opgegeven worden"
	,	"gsm-optioneel": "Een 06-nummer moet in het formaat <code>06-12345678</code> opgegeven worden"
  ,	"gsm-kort": "Een 06-nummer moet in het formaat <code>12345678</code> opgegeven worden"
  , "getal": "Dit veld accepteerd alleen numerieke waarden"
	}
, inputClassChecks: {
		"email": "^[\\w-\\.\\']{1,}\\@([\\da-z-]{1,}\\.){1,}[\\da-z-]{2,}$"
	,	"postcode": "^[1-9][0-9]{3} ?[A-Z]{2}$"
	,	"datum": "^[0-3]?[0-9]-[0-1]?[0-9]-[1-2][0-9]{3}$"
  ,	"datum-kort": "^[0-3][0-9][0-1][0-9]{3}$"
	,	"gsm": "^06\\s?-?\\s?[1-9][0-9]{7}$"
	,	"gsm-optioneel": "^06\\s?-?(\\s?[1-9][0-9]{7})?$"
  ,	"gsm-kort": "^\\s?[1-9][0-9]{7}?$"
  , "getal": "^[0-9]+$"
	}
, calendar: "Kalender"
}


formchecker = function(form) {
	form.submit(function(){
		$("button[type=submit]", form).attr("disabled", true);
		var errors = false, names = {}, field;
		$("label[for]", form).each(function(){
      field = $(this.form[this.htmlFor]);
			if (! names[field.attr("name")] && ! showError(field)) errors = true;
			names[field.attr("name")] = true;
		});
		$("button[type=submit]", form).attr("disabled", ! errors);
		return ! errors;
	});

	$("input, select, textarea", form).blur(function(){	showError($(this)) }).focus(function(){ hideError($(this)) });

	function showError(field) {
		var name = field[0].name;
		var errorDiv = $("<div class=error id=error-"+ field[0].name +"/>").hide();
		if (field.is("[class]") && ! isValid(field)) {
			errorDiv.append(lang.inputInvalid);
			var classes = field[0].className.split(" ");
			for (var i = 0, className; className = classes[i]; i++)
				if (lang.inputClassHelp[className]) errorDiv.append("<br>"+ lang.inputClassHelp[className]);
		}
		else if ($("label[for='"+ name +"']").is("label") &&
								$("label[for='"+ name +"']:first").parent().is("strong") && (
									$.trim(field.val()) == "" || (field.is("[type=radio], [type=checkbox]") && ! field.is(":checked"))))
			errorDiv.append(lang.inputRequired);
		if (errorDiv.html() != "") {
			$("#error-"+ name).remove();
			field.parent().after(errorDiv);
			errorDiv.slideDown(
        "fast"
      , function(){
          $("#content .correctMe:visible").each(function(){ fixDivHeight($(this)); });
        }
      );
			return false;
		}
		else return true;
	}

	function hideError(field) {
    return $("#vraag-"+ field[0].name +" .error").slideUp("fast", function(){
      $("#content .correctMe:visible").each(function(){ fixDivHeight($(this)); });
    });
  }

	function isValid(field) {
		if (!field.val()) return true;
		for (classCheck in lang.inputClassChecks)
			if (field.hasClass(classCheck) && ! field.val().match(new RegExp(lang.inputClassChecks[classCheck], "i")))
				return false;
		return true;
	}

  $("textarea", form).each(function(){
    var field = $(this);
    var maxlength = $(field).next().children("span").text();
    if (parseInt(maxlength, 10) <= 0) return;
    var textLength = null;

    function limit(){
      textLength = field.val().length;
      if (navigator.platform.indexOf("Win") >= 0 && $.browser == "mozilla")
        textLength = field.val().replace(/\r?\n/g, "\r\n").length;
      if (maxlength < textLength) {
        field.val(field.val().substr(0, maxlength));
        textLength = maxlength;
      }
      $(field).next().html(lang.inputCharsLeft.replace("%1", textLength).replace("%2", maxlength));
    }

    field.change(limit).keyup(limit);
    limit();
  });


  $("input.datum", form).each(function(){
    var field = $(this);
    var pattern = field.nextAll("span:first").text();
    if (pattern == "") return alert("Pattern missing");
    var date = readDate(this.value);

    var picker = $("<div class=picker><div class=nav><a class=close><span>x</span></a></div><table><thead><tr /></thead><tbody /></table></div>").hide();
    field.after(picker);
    $("div.nav", picker).append("<a class=month-12><span>&laquo;</span></a><a class=month-1><span>&lsaquo;</span></a><select class=month/><select class=year/><a class=month1><span>&rsaquo;</span></a><a class=month12><span>&raquo;</span></a>");
    $("thead tr", picker).append("<th>"+ lang.daysAbbr.join("</th><th>") +"</th>");
    $("select", picker).change(function(){ jumpMonth($(this).val()) });
    $("div.nav a:not(.close)", picker).click(function(){ jumpMonth(this.className.replace("month", "")) });
    $("a.close", picker).click(hide);
    if (picker.css("position") == "absolute") {
      picker.css({left: field.offset().left, top: field.offset().top + field[0].offsetHeight});
    }
    var open = $("<a class=calendar href='javascript://'><span><span></span>"+ lang.calendar +"</span></a>").click(show);
    field.after(open);
    $("a", picker).attr("href", "javascript://");

    function render() {
      var buffer = "";
      for (var i = 0; i < 12; i++) buffer += "<option value="+ (i - date.getMonth()) +">"+ lang.monthsFull[i];
      $("div.nav select.month", picker).html(buffer)[0].selectedIndex = date.getMonth();

      buffer = "";
      for (var i = -80; i <= 80; i++) buffer += "<option value="+ (i * 12) +">"+ (date.getFullYear() + i);
      $("div.nav select.year", picker).html(buffer)[0].selectedIndex = 80;

      buffer = "<tr>";
      var pre = (7 - (date.getDate() % 7 - date.getDay())) % 7;
      var days = daysInMonth(date);
      var post = (7 - (pre + days) % 7) % 7;
      for (var i = pre; i > 0; i--) buffer += "<td></td>";
      for (var i = 1; i <= days; i++) {
        buffer += "<td><a href='javascript://'>"+ i +"</a></td>";
        if ((i + pre) % 7 == 0) buffer += "</tr><tr>";
      }
      for (var i = post; i > 0; i--) buffer += "<td></td>";
      $("tbody", picker).html(buffer + "</tr>");
      $("tbody a").click(function(){ writeDate($(this).text()); hide() });
    }

    function show() {
      date = readDate(field.val());
      render();
      picker.show();
      $("#content .correctMe:visible").each(function(){ fixDivHeight($(this)); });
    }

    function hide() {
      picker.hide();
      $("#content .correctMe:visible").each(function(){ fixDivHeight($(this)); });
      field[0].focus();
    }

    function readDate(value) {
      if (value != "") {
        var dateParts = {};
        for (part in lang.dateParts) {
          dateParts[part] = new RegExp(regForPart(pattern, part)).exec(value);
          if (!dateParts[part]) return new Date();
          dateParts[part] = dateParts[part][1] ? dateParts[part][1] : null;
        }
        if (dateParts.year != null && dateParts.month != null && dateParts.day != null)
          return new Date(dateParts.year, dateParts.month - 1, dateParts.day);
      }
      return new Date();
    }

    function writeDate(day) {
      field.val(pattern.replace(lang.dateParts.year, date.getFullYear())
        .replace(lang.dateParts.month, date.getMonth() + 1)
        .replace(lang.dateParts.day, day)
      );
    }

    function regForPart(pattern, part) {
      for (currPart in lang.dateParts)
        if (currPart != part) pattern = pattern.replace(lang.dateParts[currPart], lang.dateRegs[currPart]);
      return pattern.replace(lang.dateParts[part], "("+ lang.dateRegs[part] +")");
    }

    function daysInMonth(date) {
      var days = ([31,28,31,30,31,30,31,31,30,31,30,31])[date.getMonth()];
      if (date.getMonth() == 1 && (
        date.getFullYear() % 400 == 0 || (date.getFullYear() % 4 == 0 && date.getFullYear() % 100 != 0)
      )) days++;
      return days;
    }

    function jumpMonth(month) {
      date.setDate(1);
      date.setMonth(date.getMonth() + parseInt(month));
      render();
    }
  });

};

$("form").each(function(){ formchecker($(this)) });
$(window).unload(function(){ $("button[type=submit]").attr("disabled", false) });
