function updateNightsAndCost()
{
  var printHiding = document.getElementById('datesNights');
  // This script is used on prices.html as well as bookingform.html, and should
  // not do any print hiding / showing on prices.html. I do not use any of the
  // IDs datesNights, detailsCost or detailsAndCost on bookingform.html so this
  // script now only does print hiding stuff if datesNights exists.

  var granary = document.getElementById('granary').checked;
  var saddle = document.getElementById('saddle').checked;
  var stables = document.getElementById('stables').checked;

  var arrivalDateD = document.getElementById('arrivalDateD').value;
  var arrivalDateM = document.getElementById('arrivalDateM').value;
  var arrivalDateY = document.getElementById('arrivalDateY').value;
  var departureDateD = document.getElementById('departureDateD').value;
  var departureDateM = document.getElementById('departureDateM').value;
  var departureDateY = document.getElementById('departureDateY').value;

  var dogs = document.getElementById('dogs').value;

//   // UPDATE DEPOSIT ------------------------------------------------------------
//   // NOW SET ONLY WHEN BOTH APARTMENTS AND *DATES* SELECTED (SINCE PER WEEK TOO)
// 
//   var deposit = 0;
//   if (granary) deposit += 100;
//   if (saddle) deposit += 100;
//   if (stables) deposit += 100;
//   if (deposit > 0) document.getElementById('deposit').value = '£' + deposit + ' (£100 per apartment per week)'
//   else document.getElementById('deposit').value = '£100 per apartment per week';

  // AUTO-SET DEPARTURE DATE ---------------------------------------------------
  
  // Chosen not to automatically set the date for now.
  if (departureDateM == 0 && arrivalDateM != 0)
  {
    departureDateM = arrivalDateM;
    document.getElementById('departureDateM').value = departureDateM;
  }
  if (departureDateY == 0 && arrivalDateY != 0)
  {
    departureDateY = arrivalDateY;
    document.getElementById('departureDateY').value = departureDateY;
  }

  // UPDATE NIGHTS ------------------------------------------------------------

  if (arrivalDateD == 0
  ||  arrivalDateM == 0
  ||  arrivalDateY == 0
  ||  departureDateD == 0
  ||  departureDateM == 0
  ||  departureDateY == 0)
  {
    document.getElementById('nights').value = '';
    document.getElementById('nights').className = '';
    document.getElementById('cost').value = '';
    if (printHiding)
    {
      // Hide nights & cost from printouts while they're blank
      document.getElementById('datesNights').className = 'readOnly phide';
      document.getElementById('detailsAndCost').className = 'phide';
      document.getElementById('detailsCost').className = 'phide';
    }
  }
  else
  {
    var arrival = new Date(arrivalDateY, arrivalDateM-1, arrivalDateD);
    var departure = new Date(departureDateY, departureDateM-1, departureDateD);

    var nights = Math.round((departure.getTime() - arrival.getTime()) / (24 * 60 * 60 * 1000));
  
    var error = '';

    if      (arrival.getDate() != arrivalDateD
    ||       arrival.getMonth()+1 != arrivalDateM
    ||       arrival.getFullYear() != arrivalDateY)
    {
      error = 'Error: invalid arrival date.';
    }
    else if (departure.getDate() != departureDateD
    ||       departure.getMonth()+1 != departureDateM
    ||       departure.getFullYear()!= departureDateY)
    {
      error = 'Error: invalid departure date.';
    }
    // Don't allow a date in the past, unless the 'allowpast' flag is in the query string
    else if ((arrival.getTime()+(24*3600*1000)) < new Date().getTime() && !isQueryVariable('allowpast'))
    {
      error = 'Error: arrival is not in future.';
    }
    else if (nights <= 0)
    {
      error = 'Error: departure before arrival.';
    }
    else if (nights > 92)
    {
      error = 'Error: stay exceeds 3 months.';
    }

    if (error != '')
    {
      document.getElementById('nights').value = error;
      document.getElementById('nights').className = 'error';
      document.getElementById('cost').value = '';
      if (printHiding)
      {
        // Hide nights & cost from printouts while they're blank
        document.getElementById('datesNights').className = 'readOnly phide';
        document.getElementById('detailsAndCost').className = 'phide';
        document.getElementById('detailsCost').className = 'phide';
      }
    }
    else
    {
      var dayNames = new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
      var nightsBox = document.getElementById('nights');
      nightsBox.value = nights + ' night' + (nights == 1 ? '' : 's');
      nightsBox.value += ' (' + dayNames[arrival.getDay()] + ' to ' + dayNames[departure.getDay()] + ')';
      nightsBox.className = '';

      // Add note if arrival date is in past (can only get this far if 'allowpast' query flag was used)
      if ((arrival.getTime()+(24*3600*1000)) < new Date().getTime())
      {
        nightsBox.className = 'error';
        nightsBox.value = '[PAST] ' + nightsBox.value;
      }

      if (printHiding)
      {
        document.getElementById('datesNights').className = 'readOnly'; // not hidden from printing
      }

      // UPDATE TOTAL COST AND DEPOSIT ------------------------------------------------
      // NB: If this is changed the equivalent code in booking.php needs updating too.

      if (!(granary || saddle || stables))
      {
        document.getElementById('cost').value = '';
        document.getElementById('deposit').value = '£100 per apartment per week';
        if (printHiding)
        {
          // Hide cost from printouts while it's blank
          document.getElementById('detailsAndCost').className = 'phide';
          document.getElementById('detailsCost').className = 'phide';
        }
      }
      else
      {
        // Update deposit first (done whether or not selected dates within tariff)
        var deposit = 0;
        var weeks = Math.ceil(nights/7);
        if (granary) deposit += (weeks*100);
        if (saddle) deposit += (weeks*100);
        if (stables) deposit += (weeks*100);
        if (deposit > 0) document.getElementById('deposit').value = '£' + deposit + ' (£100 per apartment per week)'
        else document.getElementById('deposit').value = '£100 per apartment per week';

        // Find first relevant Saturday date for tariff lookups
        // Days are 0-6 with 0 as Sunday, so substract day+1 mod 7 from date
        tariffDate = new Date(arrival.valueOf());
        tariffDate.setDate(tariffDate.getDate() - ((tariffDate.getDay() + 1) % 7));

        var granaryPrices = new Array();
        var saddleStablesPrices = new Array();

        // Pick out all relevant (overlapped) tariff prices
        var i = 0;
        var outOfTariff = false;
        while (tariffDate.valueOf() < departure.valueOf())
        {
          if (tariffGranary[getTariffId(tariffDate)] == undefined)
          {
            outOfTariff = true;
            break;
          }
          granaryPrices[i] = tariffGranary[getTariffId(tariffDate)];
          saddleStablesPrices[i] = tariffSaddleStables[getTariffId(tariffDate)];
          i++;
          tariffDate.setDate(tariffDate.getDate() + 7);
        }

        if (outOfTariff)
        {
          document.getElementById('cost').value = 'Subject to confirmation (outside tariff dates)';
          if (printHiding)
          {
            document.getElementById('detailsAndCost').className = ''; // not hidden
            document.getElementById('detailsCost').className = '';    // from printing
          }  
        }
        else
        {
          granaryPrices = granaryPrices.sort(function(a,b){return b-a});
          saddleStablesPrices = saddleStablesPrices.sort(function(a,b){return b-a});

          var totalCost = 0;
          // Short breaks: using most expensive overlapped tariff price,
          // 40% of price for first night and 10% for each additional night
          if (nights < 8)
          {
            var fraction = 0.4 + ((nights - 1) * 0.1);
            if (granary) totalCost += (fraction * granaryPrices[0]);
            if (saddle) totalCost += (fraction * saddleStablesPrices[0]);
            if (stables) totalCost += (fraction * saddleStablesPrices[0]);
          }
          // Longer breaks:
          // 100% of most expensive overlapped tariff price for first week
          // plus 10% per night of second most expensive for next 7 nights
          // plus 10% per night of third most expensive for next 7 nights etc
          else
          {
            if (granary) totalCost += granaryPrices[0];
            if (saddle) totalCost += saddleStablesPrices[0];
            if (stables) totalCost += saddleStablesPrices[0];
            var i = 1;
            for (daysLeft = (nights-7); daysLeft > 0; daysLeft -= 7)
            {
              if (daysLeft > 6) var fraction = 0.7
              else var fraction = 0.1 * daysLeft;
              if (granary) totalCost += (fraction * granaryPrices[i]);
              if (saddle) totalCost += (fraction * saddleStablesPrices[i]);
              if (stables) totalCost += (fraction * saddleStablesPrices[i]);
              i++;
            }
          }
          totalCost = Math.floor(totalCost);

          if (dogs > 0) totalCost += 10 * dogs;

          document.getElementById('cost').value = '£' + totalCost + ' (subject to confirmation)';
          if (printHiding)
          {
            document.getElementById('detailsAndCost').className = ''; // not hidden
            document.getElementById('detailsCost').className = '';    // from printing
          }  
        }
      }
    }
  }
}

function getTariffId(tariffDate)
{
  var month = tariffDate.getMonth()+1;
  var date = tariffDate.getDate();
  return '' + tariffDate.getFullYear() + (month < 10 ? '0' : '') + month + (date < 10 ? '0' : '') + date;
}

function isQueryVariable(variable) {
  var vars = window.location.search.substring(1).split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    if (pair[0] == variable) {
      return true;
    }
  }
  return false;
}

addLoadEvent(function() {
  document.getElementById('nights').value = '';
  document.getElementById('cost').value = '';

  document.getElementById('arrivalDateD').onchange = updateNightsAndCost;
  document.getElementById('arrivalDateM').onchange = updateNightsAndCost;
  document.getElementById('arrivalDateY').onchange = updateNightsAndCost;
  document.getElementById('departureDateD').onchange = updateNightsAndCost;
  document.getElementById('departureDateM').onchange = updateNightsAndCost;
  document.getElementById('departureDateY').onchange = updateNightsAndCost;
  document.getElementById('granary').onchange = updateNightsAndCost;
  document.getElementById('saddle').onchange = updateNightsAndCost;
  document.getElementById('stables').onchange = updateNightsAndCost;
  document.getElementById('dogs').onchange = updateNightsAndCost;

  document.getElementById('arrivalDateD').onkeyup = updateNightsAndCost;
  document.getElementById('arrivalDateM').onkeyup = updateNightsAndCost;
  document.getElementById('arrivalDateY').onkeyup = updateNightsAndCost;
  document.getElementById('departureDateD').onkeyup = updateNightsAndCost;
  document.getElementById('departureDateM').onkeyup = updateNightsAndCost;
  document.getElementById('departureDateY').onkeyup = updateNightsAndCost;
  document.getElementById('granary').onkeyup = updateNightsAndCost;
  document.getElementById('saddle').onkeyup = updateNightsAndCost;
  document.getElementById('stables').onkeyup = updateNightsAndCost;
  document.getElementById('dogs').onkeyup = updateNightsAndCost;
  
  // For IE's benefit
  document.getElementById('granary').onclick = updateNightsAndCost;
  document.getElementById('saddle').onclick = updateNightsAndCost;
  document.getElementById('stables').onclick = updateNightsAndCost;

  updateNightsAndCost();
});

// -----------------------------------------------------------
// addLoadEvent from Simon Willison
// http://simonwillison.net/2004/May/26/addLoadEvent/
// I had the idea independently but didn't write this version.
// -----------------------------------------------------------

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}