/* when a page is loaded, nothing is wrong */
var highlighted = null;

/** GENERIC FUNCTIONS **/
/* tests whether two strings equal each other or not */
function stringtest(div,tofocus,field,value,message)
{ return booltest(div,tofocus,field == value, message); }

/* if the condition is true then
   a) highlights the "div"
   b) gives the "tofocus" field focus
   c) alerts the user with "message"
 */
function booltest(div,tofocus,condition,message)
{
  if (condition) {
    if(tofocus.focus) {tofocus.focus();} // give the bad field focus
    alert(message);  // tell the users they've made a mistake
    if (highlighted) { // unhighlight the previous error
      highlighted.style.background = 'transparent';
    }
    if (div != 'none') {
      highlighted = document.getElementById(div); // remember their mistake
      highlighted.style.background = '#fcc'; // highlight this error
    }
  }
  return condition;
}

/* returns true if NO radio button has been selected within a radio set */
function validateRadio(radioset)
{
  for (var i = 0; i < radioset.length; i++) {
    if (radioset[i].checked) {return false;}
  }
  return true;
}

/* returns the value of the radio checked in a radio set */
function getRadioValue(radioset)
{
  for (var i = 0; i < radioset.length; i++) {
    if (radioset[i].checked) {return radioset[i].value;}
  }
  return '';
}

/* hides or shows the given id */
function showhide(id)
{
  if (document.getElementById)
  {
    obj = document.getElementById(id);
    if (obj.style.display == "none")
    {
      obj.style.display = "";
    }
    else
    {
      obj.style.display = "none";
    }
  }
}

/* hides or shows the given id, display should be true or false */
function showOrHideElementById(element,display) {
  document.getElementById(element).style.display = (display) ? 'block' : 'none';
}

/* calls the above for every element in the array */
function showOrHideElementsById(elements, display) {
  for (var i = 0; i < elements.length; i++) {
    showOrHideElementById(elements[i],display);
  }
}

/** MORE SPECIFIC FUNCTIONS **/

/* sees whether the value given is unique in a input list */
function isUnique(list, value) {
  var count = 0;
  for (var i = 0; i < list.length; i++) {
    if (list[i].value == value) {
      if (count == 1) { // already existed
        return false;
      }
      else {
        count++;
      }
    }
  }
  return true;
}

/* checks whether a domain name is wellformed - www. is permitted */
function isValidDomain(domain,requiresSpace) {
  // who cares about the space
  if (!requiresSpace && domain.match(/^(www\.|)[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9]$/)) {
    return true;
  }
  // match all spaces but .name
  if (domain.match(/^(www\.|)[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9]\.(com|net|org|biz|info|us|mobi|eu|com\.au|net\.au|org\.au|id\.au|asn\.au|cn|com\.cn|com\.fj|com\.hk|hk|jp|la|com\.ph|ph|com\.sg|com\.tw|tv|co\.nz|net\.nz|org\.nz|at|co\.at|be|de|it|nl|com\.ru|com\.es|ch|co\.uk|ca|cc|co\.il|co\.za|to|ws)$/)) {
    return true;
  }
  // match .names
  else {
    return domain.match(/^(www\.|)([A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9]\.){2,2}name$/);
  }

}

/* Cleans a company name field 
 * Example: Jesse-Maye O'Conner & Associates (Pty. Ltd)
 * Example2: In2Music
 * Example3: 100% pty. ltd
 */
function cleanCompanyField(companyField) {
  var notAllowed = /[^\%-\'\(\)\.\&a-zA-Z\s0-9]/g;
  companyField.value = companyField.value.replace(notAllowed, '');
} 

/* removes all non-digit characters */
function cleanNumericField(textField)
{
  var notDigit = /[^0-9]/g;
  textField.value = textField.value.replace(notDigit,'');
}

/* removes all non-digit characters */
function stripIllegalChars(textField)
{
  var notDigit = /[\<\>]/g;
  textField.value = textField.value.replace(notDigit,'');
}

/* Cleans a text field (Jesse-May O'Connor 12 will pass) */
function cleanTextField(textField) {
  var notAllowed = /[^0-9a-zA-Z\s'-]/g;
  textField.value = textField.value.replace(notAllowed,'');
}

/* sees whether an email is wellformed or not */
function isValidEmail(email) {
  return email.match(/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,4}$/);
}

/* sees whether a name is wellformed or not */
function isValidName(name) {
  return name.match(/^[-\'a-zA-Z\s]+$/);
} 

/* sees whether a phone is wellformed or not 
   We are defining a valid phone as one that may
   contain one or more of: ".", "-", "+"
   AND at least 8 of these "0-9"
*/
function isValidPhone(phone) {
  return phone.match(/^[-\+\s\.0-9]{8,}$/);
}


/* checks whether a given date is valid or not */
function isValidDate(day, month, year)
{
  // strip leading zeros from day month and year so we can treat them as numbers
  day = day.replace(/^0+/,'');
  month = month.replace(/^0+/,'');
  year = year.replace(/^0+/,'');

  // validate february (and a few others besides)
  var isLeapYear = (year % 4 == 0);
  if (day <= 28) {return true;}
  if (isLeapYear && day == 29) {return true;}
  if (month == 2) {return false;}

  // validate 30 day months
  if (day <= 30) {return true;}
  if (month == 4 || month == 6 || month == 9 || month == 11) {return false;}

  // validate 31 day months
  if (day <= 31) {return true;}

  // everything else should be bogus
  return false;
}

/* returns 1 if the date is after today
   returns 0 if the date IS today 
   returns -1 if the date is before today */
function compareDate(year, month, day)
{
  // strip leading zeros from day month and year so we can treat them as numbers
  if (year) year = year.replace(/^0+/,'');
  if (month) month = month.replace(/^0+/,'');
  if (day) day = day.replace(/^0+/,'');

  // get todays date
  var today = new Date();

  // check if it's before or after today - introducing year 3000 bug - bad
  if (year && year > today.getFullYear() - 2000) return 1;
  if (year && year < today.getFullYear() - 2000) return -1;
  if (month && month > today.getMonth() + 1) return 1;
  if (month && month < today.getMonth() + 1) return -1;
  if (day && day > today.getDate()) return 1;
  if (day && day < today.getDate()) return -1;

  // if all the tests above failed - then it must be today
  return 0;
}

/* make sure the user has reached a 18 years - ?maybe make age an input */
function isAtleast18(day, month, year)
{
  // strip leading zeros from the day month and year
  day = day.replace(/^0+/,'');
  month = month.replace(/^0+/,'');
  year = year.replace(/^0+/,'');

  // get todays date
  var today = new Date();

  // see whether they're clearly over or under 18
  if ((today.getFullYear() - year) > 18) {return true;}
  if ((today.getFullYear() - year) < 18) {return false;}

  // check the month
  if (today.getMonth() >= month) {return true;}

  // check the day (+ month)
  if (today.getMonth() + 1 == month && today.getDate() >= day) {return true;}

  // not yet 18
  return false;
}

/* somebody thinks they've broken a world record */
function isRidiculousAge(year)
{
  var today = new Date();
  if (today.getFullYear() - year > 129) {return true;}
  return false;
}


/* returns true if the credit card number is invalid
  - assumes non-numeric characters have been stripped */
function isBadCreditCardNumber(cardtype, cardnumber)
{
  if (cardtype == 'VISA') {
    if (cardnumber.match(/^4([0-9]{12,12}|[0-9]{15,15})$/)) {return false;}
  }
  else if (cardtype == 'MASTERCARD') {
    if (cardnumber.match(/^5[1-5][0-9]{14,14}$/)) {return false;}
  }
  else if (cardtype == 'AMEX' || cardtype == 'AMERICAN EXPRESS') {
    if (cardnumber.match(/^3[47][0-9]{13,13}$/)) {return false;}
  }
  else if (cardtype == 'DINERS' || cardtype == 'DINERS CLUB') {
    if (cardnumber.match(/^3[068][0-9]{12,12}$/)) {return false;}
  }
  else if (cardtype == 'BANKCARD') {
    if (cardnumber.match(/^5610[0-9]{12,12}$/)) {return false;}
  }
  return true;
}

/**
 * Format a number into a nice looking currency
 * @param {Number} num - The number to format
 * @param {Boolean} showCents - Specifiy whether to show cents or not 
 */
function formatCurrency(num, showCents) {
  num = num.toString().replace(/\$|\,/g,'');
  if(isNaN(num)) num = "0";
  sign = (num == (num = Math.abs(num)));
  num = Math.floor(num*100+0.50000000001);
  cents = num%100;
  num = Math.floor(num/100).toString();
  if(cents<10) cents = "0" + cents;
  for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++) {
    num = num.substring(0,num.length-(4*i+3))+','+
    num.substring(num.length-(4*i+3));
  }
  if(showCents) {
    return (((sign)?'':'-') + '$' + num + '.' + cents);
  } else {
    return (((sign)?'':'-') + '$' + num);
  }
}
    
/**
 * Convert a form into a query string
 * Taken from: http://www.state26.com/downloads/formdata2querystring.txt
 * Modified by me (Matt) to add the 'select-multiple' case and fix a few bugs
 * AND also strip the naughty chars from the text fields
 * AND only add the param if there is a value
 * @param {Object} docForm - the form to turn into a query string
 */
function formData2QueryString(docForm)
{   
   var submitString = '?';
   var formElement = '';
   var lastElementName = '';
   
   for(i = 0 ; i < docForm.elements.length ; i++)
   {
     formElement = docForm.elements[i];
		 switch(formElement.type)
     {    
        case 'text' :
        case 'select-one' :
        case 'hidden' :
        case 'password' :
        case 'textarea' :
					 var notDigit = /[\<\>]/g;
					 formElement.value = formElement.value.replace(notDigit,'');					 
           if(trim(formElement.value) != '') {submitString += formElement.name + '=' + encodeURIComponent(formElement.value) + '&';}
           break;
        case 'radio' :   
           if(formElement.checked)
           {
              if(trim(formElement.value) != '') {submitString += formElement.name + '=' + encodeURIComponent(formElement.value) + '&';}           
           }
           break;
        case 'checkbox' :   
           if(formElement.checked) 
           {
             if(trim(formElement.value) != '') {
               submitString += formElement.name + '=' + encodeURIComponent(formElement.value) + '&';            
               lastElementName = formElement.name;
             }               
           }
           break; 
        case 'select-multiple' :

          for(var j=0; j < formElement.options.length; j++) {
            if(formElement.options[j].selected) {
              if(trim(formElement.value) != '') {submitString += formElement.name + '=' + encodeURIComponent(formElement.value) + '&';}
            }
          }           
          break;          
        default:
          break;
     }                                                                            
   }
   submitString = submitString.substring(0, submitString.length - 1);
   return submitString;                               
}

/* Attach an event to an element. Handles for most browsers
   NB. To make it work in crappy old browsers assign the
   element an id
*/
function addEvent(element, event, handler) {
  if(element.attachEvent) {                           // IE (6+?)
    element.attachEvent('on'+event, handler);
  } else if(element.addEventListener) {               // Most nice browsers
    element.addEventListener(event, handler, false);
  } else {                                            // Old browsers
    // Assign an id based on the time for this element if it has no id
    if(!element.id) {
      var date = new Date();
      element.id = date.getTime();
    }
    eval('document.getElementById('+ element.id +').on'+event+'='+handler);             
  }
}
/** Hide an element when the ESC key is pressed 
 * @param element The DOM element to hide on keyup
 */
function hideElementOnEscape(element) {
	  var DOM_VK_ESCAPE = 27; // Cross browser ESC code
    // If pressing escape, hide form
    document.getElementsByTagName("body")[0].onkeyup = function(e) {
			alert("ASDFSDAF")            
      if(!e) e = window.event;
      target = (e.target) ? e.target : e.srcElement; // IE uses srcElement
      			
      if(element.style.display == "block" && e.keyCode == DOM_VK_ESCAPE) {
				alert('ESC pressed;') 
			  element.style.display = 'none'; 
			}
    }        
}

/* calls the above for every element in the array */
function hideElementsOnEscape(element) {
  for (var i = 0; i < elements.length; i++) {
    hideElementOnEscape(elements[i]);
    }        
}
  
/* Check if an element has a parent given an id */
function hasParentRecursive(element, parentId) {
  var el = element;
  // Parent node IS what we're looking for
  if(el.parentNode && el.parentNode.id && el.parentNode.id == parentId) {    
    return true;
  } else if(el.parentNode) { // Still has a parent? Keep looking!
    return hasParentRecursive(el.parentNode, parentId);
  } else { // No more parents, not found
    return false;
  }
  
}
	