var date_field_switch_info = {
   from: null,
   length: -1,
   toname: ''
};

function dateFieldSetSwitchInfo(from, length, toname)
{
   date_field_switch_info.from = from;
   date_field_switch_info.length = length;
   date_field_switch_info.toname = toname;
}

function dateFieldResetSwitchInfo()
{
   dateFieldSetSwitchInfo(null, -1, '');
}

function dateFieldKeyUp(parent, callback)
{
   if (date_field_switch_info.toname && date_field_switch_info.from
       && date_field_switch_info.from.value.length == date_field_switch_info.length)
   {
      var nodes = parent.childNodes;
      for (var i = 0; i < nodes.length; i++)
      {
         if (nodes[i].name == date_field_switch_info.toname)
         {
            nodes[i].focus();
            break;
         }
      }
      dateFieldResetSwitchInfo();
   }

   if (callback)
   {
      eval(callback);
   }
}

function dateFieldKeyDown(event, field, prev, next)
{
   var keynum;
   if (window.event) // IE
   {
      keynum = event.keyCode;
   }
   else if (event.which) // Netscape/Firefox/Opera
   {
      keynum = event.which;
   }

   if ((keynum >= 48 && keynum <= 57)           // Digit
        || (keynum >= 96 && keynum <= 105))     // Numeric keypad digit
   {
      dateFieldSetSwitchInfo(field, 2, next);
   }
   else if (field.value.length === 0 && keynum == 8) // Backspace
   {
      dateFieldSetSwitchInfo(field, 0, prev);
   }
}

function dateFieldToString(day_str, month_str, year_str)
{
   var nr_days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

   if (day_str.length === 0)
   {
      throw('Geen dag ingevuld');
   }
   if (month_str.length === 0)
   {
      throw('Geen maand ingevuld');
   }
   if (year_str.length === 0)
   {
      throw('Geen jaar ingevuld');
   }

   var day = parseInt(day_str, 10);
   var month = parseInt(month_str, 10);
   var year = parseInt(year_str, 10);

   if (isNaN(month_str) || month <= 0 || month > 12)
   {
      throw('Ongeldige maand');
   }
   if (year < 70)
   {
      year += 2000;
   }
   else if (year < 100)
   {
      year += 1900;
   }
   if (isNaN(year_str) || year < 1970 || year > 9999)
   {
      throw('Ongeldig jaar');
   }

   var leapyear = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0));

   if (isNaN(day_str) || day <= 0 || day > nr_days[month-1]
       || (month == 2 && day == 29 && !leapyear))
   {
      throw('Ongeldige dag');
   }

   day_str = day.toString();
   if (day_str.length < 2)
   {
      day_str = '0' + day_str;
   }
   month_str = month.toString();
   if (month_str.length < 2)
   {
      month_str = '0' + month_str;
   }
   year_str = year.toString();

   return year_str + '-' + month_str + '-' + day_str;
}

function dateFieldGetComponents(field)
{
   var res = { day: '', month: '', year: '' };

   var nodes = field.childNodes;
   for (var i = 0; i < nodes.length; i++)
   {
      switch (nodes[i].name)
      {
      case 'day':   res.day = nodes[i].value; break;
      case 'month': res.month = nodes[i].value; break;
      case 'year':  res.year = nodes[i].value; break;
      }
   }

   return res;
}

function dateFieldOnChange(field, callback)
{
   var comp = dateFieldGetComponents(field);

   if (comp.day.length > 0
      && comp.month.length > 0
      && comp.year.length > 0)
   {
      try
      {
         var date_str = dateFieldToString(comp.day, comp.month, comp.year);
         callback(date_str);
      }
      catch (exc)
      {
         alert(exc);
      }
   }
   else if (comp.day.length === 0
      && comp.month.length === 0
      && comp.year.length === 0)
   {
      callback('');
   }
}

function dateFieldGetValue(id, allowEmpty)
{
   var field = document.getElementById(id);
   var comp = dateFieldGetComponents(field);
   if (allowEmpty
       && (comp.day.length === 0 || comp.day == '0'
           || comp.month.length === 0 || comp.month == '0'
           || comp.year.length === 0 || comp.year == '0'))
   {
      return '';
   }

   return dateFieldToString(comp.day, comp.month, comp.year);
}

function dateFieldParseValue(value)
{
   value = value.replace(/\-/g, '').toLowerCase();
   var date = {};
   var day = value.substr(6, 2);
   if (day != '??')
   {
      if (day == 'nn')
      {
         day = new Date().getDate();
         if (day < 10)
         {
            day = '0' + day;
         }
      }
      date.day = day;
   }
   var month = value.substr(4, 2);
   if (month != '??')
   {
      if (month == 'nn')
      {
         month = new Date().getMonth() + 1;
         if (month < 10)
         {
            month = '0' + month;
         }
      }
      date.month = month;
   }
   var year = value.substr(0, 4);
   if (year != '????')
   {
      if (year == 'nnnn')
      {
         year = new Date().getFullYear();
      }
      date.year = year;
   }

   return date;         
}

function dateFieldSetValue(id, value)
{
   var date = dateFieldParseValue(value);
   if (!date.day)
   {
      date.day = '';
   }
   if (!date.month)
   {
      date.month = '';
   }
   if (!date.year)
   {
      date.year = '';
   }

   var field = document.getElementById(id);
   var nodes = field.childNodes;
   for (var i = 0; i < nodes.length; i++)
   {
      var name = nodes[i].name;
      if (name == 'day' || name == 'month' || name == 'year')
      {
         nodes[i].value = date[name];
      }
   }
}

function createDateField(id, attrs)
{
   var cb_str = '';
   var attr_str = '';
   var day_str = '';
   var month_str = '';
   var year_str = '';
   var keyup_str = '';
   if (attrs)
   {
      for (var name in attrs)
      {
         var value = attrs[name];
         switch (name)
         {
         case 'value':
            var date = dateFieldParseValue(value);
            if (date.day)
            {
               day_str += ' value="' + date.day + '"';
            }
            if (date.month)
            {
               month_str += ' value="' + date.month + '"';
            }
            if (date.year)
            {
               year_str += ' value="' + date.year + '"';
            }
            break;
         case 'callback':
            cb_str = ' onchange="dateFieldOnChange(this.parentNode, ' + value + ');"';
            break;
         case 'onkeyup':
            keyup_str = value;
            break;
         case 'readonly':
            day_str   += ' readonly="' + value + '"'; 
            month_str += ' readonly="' + value + '"'; 
            year_str  += ' readonly="' + value + '"'; 
            break;
         case 'day_attrs':
            for (var dname in value)
            {
               day_str += ' ' + dname + '="' + value[dname] + '"';
            }
            break;
         case 'month_attrs':
            for (var mname in value)
            {
               month_str += ' ' + mname + '="' + value[mname] + '"';
            }
            break;
         case 'year_attrs':
            for (var yname in value)
            {
               year_str += ' ' + yname + '="' + value[yname] + '"';
            }
            break;
         default:
            attr_str += ' ' + name + '="' + value + '"';
         }
      }
   }

   var field = '<div id="' + id + '"' + attr_str + '>'
             + '<input type="text" maxlength="2" class="date_field_day" name="day"'
             +   ' onKeyDown="dateFieldKeyDown(event, this, \'\', \'month\');"'
             +   ' onKeyUp="dateFieldKeyUp(this.parentNode, \'' + keyup_str + '\');"'
             +   cb_str + day_str + '>-'
             + '<input type="text" maxlength="2" class="date_field_month" name="month" '
             +   ' onKeyDown="dateFieldKeyDown(event, this, \'day\', \'year\');"'
             +   ' onKeyUp="dateFieldKeyUp(this.parentNode, \'' + keyup_str + '\');"'
             +   cb_str + month_str + '>-'
             + '<input type="text" maxlength="4" class="date_field_year" name="year"'
             +   ' onKeyDown="dateFieldKeyDown(event, this, \'month\', \'\');"'
             +   ' onKeyUp="dateFieldKeyUp(this.parentNode, \'' + keyup_str + '\');"'
             +   cb_str + year_str + '>'
             + '</div>';
   return field;
}

