/*
Author: Michiel van der Blonk
Date: Somewhere in 2006
Description:
  cxlObject has generic form functions
  - getForm
  - imageSelect
  - addCalendar
  - initCalendars
  - validateForm
*/
function cxlObject() {
  this.getForm =
    function()
    {
      return document.forms[this.formName];
    };

  this.imageSelect =
    function()
    {
      window.open(cxlPage.imageSelection + '?dispatch=images&id=' + cxlPage.id, 'image', 'width=750, height=400, screenX=300, screenY=100, top=100,left=300, resizable=yes');
    };

  this.addCalendar =
    function(fieldId, buttonId, sOptions)
    {
      if (!this.calendars)
        this.calendars = new Array();
      this.calendars[fieldId] = {field:fieldId, button:buttonId, options:sOptions};
      if (sOptions=='startdate')
        this.startCalendar = fieldId;
      if (sOptions=='enddate')
        this.endCalendar = fieldId;
    };

  //utility functions for the calendars
  this.invalidDate =
    function(d)
    {
      var startDateElement = $(cxlPage.startCalendar);
      var startDate = Date.parseDate(startDateElement.value, "m/%d/%Y");
      return (d < startDate);
    };

  //utility functions for the calendars
  this.blockRange =
    function(d)
    {
      var ret = true;
      var out = '';
      if (cxlPage.blockedDates)
      {
        if (d.getDay()===0 && cxlPage.blockSundays) // block all sundays
          ret = true;
        else
        {
          var blockedDates = cxlPage.blockedDates;
          ret = false;
          for (i=0;i<blockedDates.length;i++)
          {
            var startDate = new Date(blockedDates[i].start);
            var endDate = new Date(blockedDates[i].end);
            var options = blockedDates[i].options;
            if (options=='yearly')
              d.setYear(startDate.getFullYear());
            if (d>=startDate && d<=endDate)
              ret = true;
          }
        }
        return ret;
      }
    };

  this.setEndDate =
    function setEndDate(cal)
    {
      var startDateElement = $(cxlPage.startCalendar);
      var endDateElement = $(cxlPage.endCalendar);

      if (startDateElement.value !== '' && endDateElement.value === '')
        endDateElement.value = startDateElement.value;
    };

  this.initCalendars =
    function() {
      var i;
      for (i in cxlPage.calendars)
      {
        var calendar = cxlPage.calendars[i];
        if (typeof calendar == "object" && $(calendar.field))
        {
          switch(calendar.options)
          {
            case 'startdate':
              cxlPage.calendars[i].object =
                Calendar.setup({inputField:calendar.field, button:calendar.button, ifFormat:"%m/%d/%Y", step:1, showsTime:false, onUpdate:cxlPage.setEndDate});
              break;
            case 'enddate':
              cxlPage.calendars[i].object =
                Calendar.setup({inputField:calendar.field, button:calendar.button, ifFormat:"%m/%d/%Y", step:1, showsTime:false, disableFunc:cxlPage.invalidDate});
              break;
            default:
              cxlPage.calendars[i].object =
                Calendar.setup({inputField:calendar.field, button:calendar.button, ifFormat:"%m/%d/%Y", step:1, showsTime:false, disableFunc:cxlPage.blockRange});
              break;
          }
        }

      }
    };

  this.isDate = function(d, formatted)
  {
    var ret = false;

    var date = new Date(d);

    // it's at least a number
    if (!isNaN(date))
    {
      if (formatted)
      {
        day = date.getDate();
        month = date.getMonth()+1;
        year = date.getFullYear();
        dateString = '' + month + '/' + day + '/' + year;
        pattern = new RegExp('' + month + '.' + day + '.' + year);
        ret = pattern.test(d);
      }
      else
        ret = true;
    }
    return ret;
  };

  /* generic validation routine */
  this.validateForm = function(frm, target)
  {
    var i;
    var ret = true;
    var field;
    var out='';
    var errorFields = [];

    // loop through all fields
    // check if they have validation class name
    // and do appropriate validation
    // @return true, if all validation passes
    for (i=0; i<frm.elements.length; i++)
    {
      field = frm.elements[i];
      // skip disabled fields
      if (field.disabled)
        continue;
      if ($('label-'+field.name))
      	field.label = $('label-'+field.name).innerHTML;
      else
      	field.label = field.name;
      // validate required fields
      filter = /validation-required/;
      if (filter.test(field.className))
      {
        if (field.type=='checkbox' && !field.checked)
        {
          out += 'Please check the ' + field.label + ' box<br />';
          errorFields.push(field);
          ret = false;
        }
        else
          if (field.value==='')
          {
            out += 'Please enter a value for ' + field.label + '<br />';
            errorFields.push(field);
            ret = false;
          }
      }
      // validate numeric fields
      filter = /validate-number/;
      if (filter.test(field.className))
      {
        if (field.value!=='' && !isNan(field.value))
        {
          out += 'Please enter a number for ' + field.label + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      // validate digit only fields
      filter = /validate-digits/;
      if (filter.test(field.className))
      {
        var filter  = /^[0-9]+$/;
        if (field.value!=='' && !filter.test(field.value))
        {
          out += 'Please enter a number for ' + field.label + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      // validate date fields
      filter = /validate-date/;
      if (filter.test(field.className))
      {
        if (field.value!=='' && isDate(field.value, true))
        {
          out += 'Please enter a number for ' + field.label + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      // validate email addresses
      filter = /format-email/;
      if (filter.test(field.className))
      {
        filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        if (field.value!=='' && !filter.test(field.value))
        {
          out += 'Please enter a valid email address in ' + field.label + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      // validate credit cards
      // this uses Luhn validation
      // which is a numeric algorithm
      filter = /format-creditcard/;
      if (filter.test(field.className))
      {
        filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        if (field.value!=='' && !this.isValidCreditCard(field.value))
        {
          out += 'Please enter a valid credit card number'  + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      // validate urls
      filter = /format-url/;
      if (filter.test(field.className))
      {
        filter  = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/i;
        if (field.value!=='' && !filter.test(field.value))
        {
          out += 'Please enter a valid url'  + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      // validate verification fields
      filter = /validation-match/;
      if (filter.test(field.className))
      {
        var otherField = field.className.replace(/.*validation-match-/,'').replace(/ .*/,'');
        if (field.value!=='' && field.value!=$(otherField).value)
        {
          out += 'The value in ' + field.label + ' does not match ' + otherField  + '<br />';
          errorFields.push(field);
          ret = false;
        }
      }
      Element.removeClassName($(field), 'error');
    }
    $(target).innerHTML = out;
    // indicate errors
    for (i = 0; i < errorFields.length; i++)
      Element.addClassName($(errorFields[i]), 'error');
    window.scroll(0,0);
    return ret;
  };

  /*
  * @Date: Feb 21, 2005
  * @Description: This function strips defined chars from a string
  * useful in validation routines
  * example: stripChars(str, "()-") returns the string with any
  * brackets and dashes removed
  **/
  this.stripChars = function(str, chars) {
    var i;
    var newstring = "";
    for (i = 0; i < str.length; i++) {
      mychar = str.charAt(i);
      if (chars.indexOf(mychar) == -1)
        newstring += mychar;
    }
    return newstring;
  };
  /**
  * @Date: Feb 21, 2005
  * @Description: This function extracts defined chars from a string
  * useful in validation routines
  * it is 'sort of' the reverse of stripChars
  * example: extractChars(str, "0123456789") returns all digits from the string
  **/
  this.extractChars = function(str, chars) {
    var i;
    var newstring = "";
    for (i = 0; i < str.length; i++) {
      mychar = str.charAt(i);
      if (chars.indexOf(mychar) != -1)
        newstring += mychar;
    }
    return newstring;
  };

  /**
  * @Date: Dec 1, 2004
  * @Description: This function tests a credit card using the Luhn validation
  * The sum of digits must be divisible by 10
  * digits in odd positions are doubled, then sum of left+right digit is taken
  **/
  this.isValidCreditCard = function(sCreditCardNumber)
  {
    var nTotal      = 0;
    var nPosition     = 0;
    var bValid      = true; // innocent until proven guilty
    sCreditCardNumber = this.extractChars(sCreditCardNumber, "0123456789");
    if (sCreditCardNumber.length < 13)
      bValid = false;
    else
    {
      for ( i = sCreditCardNumber.length; i > 0 ;  i--)
      {
        var nDigit      = 0;
        // advance
        nPosition++;
        // get digit
        nDigit= parseInt(sCreditCardNumber.charAt(i-1));
        // odd position: add to total
        if ((nPosition % 2) !== 0)
           nTotal += parseInt(nDigit);
        else
        // even position: add sum of digits to total
        {
          // calc sum of left and right digit (use parseInt to cut off fractional parts
          var nDoubled = nDigit * 2;
          var nLeftDigit  = parseInt(nDoubled / 10);
          var nRightDigit = nDoubled % 10;
          // get sum of left and right
          nTotal += nLeftDigit + nRightDigit;
        }
      }
      // if divisible by 10 it is valid
      bValid = (nTotal % 10) === 0;
    }
    return (bValid);
  };
}

// utility functions for the form
// need to become part of cxlobject
function set(target) {
  cxlPage.getForm().dispatch.value = target;
}

function submitForm(target) {
  set(target);
  cxlPage.getForm().submit();
}

function initNeverExpires() {
  var frm = cxlPage.getForm();
  frm.neverExpire.checked = (frm.expirationDate.value === '');
}

function checkFeatured() {
  var frm = cxlPage.getForm();
  frm.pressRelease.checked = false;
}

function checkPressRelease() {
  var frm = cxlPage.getForm();
  frm.featured.checked = false;
}

function deleteImage(image) {
  var frm = cxlPage.getForm();
  if (confirm(cxlPage.confirmDelete)) {
    var theLink = cxlPage.imageSelection + '?dispatch=delete&id=' + image;
    window.location.href = theLink;
  }
}