function changeCountry(c) {
  canada = document.getElementById('stateCanada');
  usa = document.getElementById('stateUSA');
  other = document.getElementById('stateOther');
  useOther = 1;
  if (c == 'CA') {
    useOther = 0;
    canada.disabled = false;
    canada.style.visibility = 'visible';
  } else {
    canada.value = '';
    canada.disabled = true;
    canada.style.visibility = 'hidden';
  }
  if (c == 'US') {
    useOther = 0;
    usa.disabled = false;
    usa.style.visibility = 'visible';
  } else {
    usa.value = '';
    usa.disabled = true;
    usa.style.visibility = 'hidden';
  }
  if (useOther) {
    other.disabled = false;
    other.style.visibility = 'visible';
  } else {
    other.value = '';
    other.disabled = true;
    other.style.visibility = 'hidden';
  }
  numAvail = 0;
  for (i=0; i<numShipping; i++) {
    if (countryShipping[c]['s'+i] == i) {
      document.getElementById('shipping'+i).style.display = 'block';
      if (numAvail == 0)
        document.getElementById('shipradio'+i).checked = true;
      numAvail++;
    } else {
      document.getElementById('shipping'+i).style.display = 'none';
    }
  }
  if (numAvail > 0) {
    document.getElementById('noshipping').style.display = 'none';
  } else {
    document.getElementById('noshipping').style.display = 'block';
  }
}

function trim(s) {
  return s.replace(/^\s*|\s*$/g,"");
}

function changeProvince(currState) {
  if (currState.length == 3) {
    country = document.getElementById('country');
    country.value = 'US';
    changeCountry('US');
    state = document.getElementById('stateUSA');
    state.value = trim(currState);
  }
}

function changeState(currState) {
  if (currState.length == 3) {
    country = document.getElementById('country');
    country.value = 'CA';
    changeCountry('CA');
    state = document.getElementById('stateCanada');
    state.value = trim(currState);
  }
}

function validateOrder() {
  // loop through all products
  numItems = 0;
  for (i=0; i<numProducts; i++) {
    x = document.getElementById('product'+i);
    if (!x) continue;
    q = x.value;
    q = trim(q);
    if (q != '') {
      // check that quantity is a valid non-zero integer
      if (q.search(/^[1-9][0-9]*$/) == -1) {
        alert("Invalid quantity specified (" + q + ")");
        return false;
      }
      numItems += 1;
    } else {
      // if qty is blank, addcards cannot be checked
      if (document.getElementById('addcards'+i).checked) {
        alert("You cannot add mini cards to an item that you have not ordered");
        return false;
      }
    }
  }
  // at least one item must have been ordered
  if (numItems == 0) {
    alert("You must order at least one item");
    return false;
  }
  // fname, lname, address1, city, country must be specified
  req = new Array('fname', 'lname', 'address1', 'city', 'country');
  for (i=0; i<req.length; i++) {
    field = document.getElementById(req[i]).value;
    field = trim(field);
    if (field == '') {
      alert("Please enter your complete name and shipping address");
      return false;
    }
  }

  // if country=canada or us, zip, state must be specified
  country = document.getElementById('country').value;
  switch (country) {

    // canadian addresses must have valid province and postal code
    case 'CA':
      state = document.getElementById('stateCanada').value;
      zip = trim(document.getElementById('zip').value);
      if (state == '' || zip == '') {
        alert("Canadian addresses must include a province and postal code");
        return false;
      }
      if (zip.search(/^[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]$/i) == -1) {
        alert("Invalid Canadian postal code");
        return false;
      }
      break;

    // us addresses must have valid state and zip code
    case 'US':
      state = document.getElementById('stateUSA').value;
      zip = trim(document.getElementById('zip').value);
      if (state == '' || zip == '') {
        alert("US addresses must include a state and zip code");
        return false;
      }
      if (zip.search(/^[0-9]{5}$/) == -1) {
        alert("Invalid US zip code");
        return false;
      }
      break;
  }
  return true;
}
