// BCA Membership Form.
// copyright (c) 2008, David Gibson, LEEDS, UK

// ======================================================
// Specify next publication
// ======================================================

// eventually, grab this from database. for now, its hard-coded

// This section specifies the next issuesto be published (NOT including any issue currently in press)
    $cksVolume 		= 37;   // <============ altered 2/7/10, 19/01/10, 27/3/09
    $cksIssue 		= 1;	// <============ altered 2/7/10, 21/5/10, 5/5/10 [late], 9/01/10, 25/6/09 ( 27/3/09 6/10/08 )
    $speleoIssue 	= 16;	// <============ altered 2/7/10, 26/8/09 (25/6/09 ( 6/10/08 )
    $bcaNews 		= 14;	// <============ altered 2/7/10, 17/12/09, 25/6/09 ( 19/12/08
    
// This section indicates if there is an issue currently in press
// Note: 'in press' means precisely the following: address list issued to printers but not yet used
// If a previous issue is in press, variable='@'

    $cksList		= '';   // <============ altered 15/7/10, 2/7/10, 27/3/09 16/2/09 @)
    $SpeleoList		= '';   // <============ altered 15/7/10
    $bcaList		= '';	// <============ altered 12/7/10
    
    $cksNumber 		= "" + $cksVolume + $cksIssue; // was $cksVolume*3 - 3 + $cksIssue;

// The effect of the '@' flag is to warn the customer that he is not on the mailing list.
// The server also emails staff to warn them to ship an issue 'by hand'

// For Clubs and Associates, the server will - when implemented - ALWAYS warn staff
// to ship back-issues for the current year. But need to check 'rules' - do we tell customer
// he must request them?

// For subscribers, server must always warn staff to ship C&KS back to start of volume
// This is achieved by setting the flag to '@@' - no warning for customer but email to staff is still generated


// ======================================================
// Define Fees
// ======================================================


fees = new Array(1);  // make array intentionally too small
j=0;

fees[j++] = 10; 	// 0	speleology
fees[j++] = 24;		// 1	cks
//fees[j++] =  5;		// 2	bcanews
//fees[j++] =  5;		// 3	bcranews
fees[j++] =  3;		// 4 	post_sp_WE
fees[j++] =  6;		// 5 	post_sp_ROW
fees[j++] =  3;		// 6 	post_cks_WE
fees[j++] =  6;		// 7 	post_cks_ROW
fees[j++] = -50; 	// 8 	ugrad
fees[j++] = -100;	// 9 	freeissue
jmax = j-1;


freeIssueValues = new Array('X',   'EX',  'LD',  'LY',  'ED',  'OF',  'CV',  'PP');
freeIssueNews   = new Array(false, false, false, true,  true,  true,  false, false);
freeIssueReview = new Array(false, true,  true,  true,  true,  true,  false, false);
 

// ======================================================
// Initialise Form (called from BODY ONLOAD)
// ======================================================

function initialise()
{
  df = document.form;
  if ((!df.country[0].checked) & (!df.country[1].checked) & (!df.country[2].checked) & (!df.country[3].checked))
  { df.country[0].checked = true; df.country2[0].checked = true;}

  
  recalculate('');
}
  


// ======================================================
// Helper Functions
// ======================================================

function writeFee(s1,s2)
  // Fees must be integer pounds for this function.
  // This function writes the fee with optional string arguments either side.
  // (Needed because my HTML editor inserts unwanted spaces around SCRIPT tags)

  {
  var undefined;  // undefined is a variable wihch is undefined because it has not been given a value
  if (s1 === undefined) { s1 = ''}  // cant use (s1 == null) as firefox wont accept this
  if (s2 === undefined) { s2 = ''}  // in JS v1.2 [special exception]
  document.write(s1, fees[j++], s2);
  if (j > jmax) { j = 0; }
  document.close();
  }

function money_blankzero(m)
{
  if (m == 0) return ''; 
  return money(m)
}
  
function money(m)
  // Make a money string, right-aligned, 4 pounds digits and two decimal places
  // This is used to set the VALUE attribute in the sub-total boxes
{
   
  var m0 = m; m = ' ' + Math.abs(m); // forces m to be a string
  var dp = m.indexOf('.');
  if (dp == -1) 		{ m += '.00' ; }
  else if (dp == m.length -1) 	{ m += '00'; }
  else if (dp == m.length -2) 	{ m += '0'; }
  if (dp == 0)			{ m = '0' + m; }
  m = '  ' + m;
  m = m.substr(m.length -7);  // Use 7 for 4 pounds digits; 6 for 3
  m = '£' + m;
  if (m0 < 0) { m += '-'; } else { m += ' '; }
  return m;
}

function readMoney(m)
  // Read a string and extract the amount of money
  // Reads the VALUE attribute of subtotals
  {
  if (m=='') { return 0; }
  var sign = 2 * (m.indexOf('-') == -1) - 1;
  var amt = parseFloat(m.substr(2));
  return (sign * amt);
  }

// --------------------------------------------------------------------------------

function warnNoUserAlteration()
    { window.alert('You cannot change this box yourself.\nThe value is calculated for you.'); }


function countryAlert()
{
  window.alert('Please select a country from the\n' +
  	       'drop-down list to the right');
}


function addCSV(s)
{
  s = s + ''		// this converts numbers to string values
  if (s.indexOf(',') != -1) 
  {
    s = '\"' + s + '\"'
  }
  return s + ',\n';
}

//  -----  String functions -----

function stripComma(s)
{
  while ((s.slice(-1) == ' ') | (s.slice(-1) == ','))
  {
    s = s.slice(0,-1);  // this removes all trailing spaces and trailing commas
  }
  return s;
}

String.prototype.toTitleCase = function()
{
  // If string contains only upper case then convert it all to lower case first
  // This means that Caps Lock/Unlock is corrected but that "Big Road NW" stays as is.
  
  sUpper = this.toUpperCase();
  s = this;
  if (s == sUpper) s = s.toLowerCase();
  s = s.split(' ');
  s1 = '';
  for (i=0; i<s.length; i++)
  {
    s1 += s[i].charAt(0).toUpperCase() + s[i].substring(1) + ' ';
  }
  s1 = s1.slice(0,-1);
  
  // WAS:   s = this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  // TRIED: s = s.replace(/ (.)/g, '_$1');  // & variants thereof, but cant convert $1 to upper
  
  return s1;
}

String.prototype.toCityCase = function()
{
  // convert to upper case, except words in brackets go to title case  
  s = this.toUpperCase();
  s = s.split(' ');
  s1 = ''; cityflag = false;
  for (i=0; i<s.length; i++)
  {
    if (s[i].charAt(0) == '(' )  { s1 += '(';  s[i] = s[i].substring(1); cityflag = true; }
    if (cityflag)
    {
      s1 += s[i].charAt(0) + s[i].substring(1).toLowerCase() + ' ';
    }
    else
    {
      s1 += s[i] + ' ';
    }
    if (s[i].slice(-1) == ')' )  { cityflag = false; }
  }
  s1 = s1.slice(0,-1);
  return s1;
}


function checkPostcode(pc, s1)
{
  // ----- check syntax of postcode -----
    // This is a basic check, based on BS 7666, as quoted at http://en.wikipedia.org/wiki/UK_postcodes#Format
    // [A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][A-Z-[CIKMOV]]{2}
    //               ^?                   ^?
    // There is a more complicated syntax check that could be done (see URL above) but is it worth it?
    
  $regexp = '^[A-Z]{1,2}[0-9][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}$';

  if ((pc.match($regexp) == null) & (pc.indexOf('BFPO') == -1) & (pc != '')) 
  {
    window.alert('The postcode in section ' + s1 + ' does not appear to have \n' +
      		 'the correct format. If you do not know your postcode \n' +
      		 'please leave this box blank or, for overseas \n' + 
      		 'addresses, please see the note in Section B.');
    return false;
  }
  return true;
}

// ======================================================
// Count characters in a textarea
// ======================================================

function countTextArea(textarea, max, $id) 
{
  textarea.value = textarea.value.substring(0, max);
  $remaining = max - textarea.value.length;   
  e = document.getElementById($id);	// use W3C DOM, global e
  if (!e) e = document.all[$id];	// Use IE4 DOM
  if (e)
  {
    e.innerHTML = $remaining + ' characters remaining'; // IE DOM but also implemented by NN and Moz
  }
}


// --------------------------------------------------------------------------------


// ======================================================
// Process User Clicks
// ======================================================


function recalculate(s)
{
  df = document.form;
  
  //  ----- boxes that user cannot alter -----
    
  if (s.substr(0,3)=='fee')	{ warnNoUserAlteration(); }
  if (s.substr(0,5)=='post_')	{ warnNoUserAlteration(); }
  
  //  ----- preset for debugging ------------------

  if ((s == 'surname') & (df.surname.value == '%%'))
  {
    df.city.value = 'LEEDS';
    df.postcode.value = 'LS8 4BX';
    df.street_line1.value = '12 Well House Drive';
    df.street_line2.value = 'Debug\'s \"quote\"';
    df.surname.value = 'Gibson';
    df.fname.value = 'David';
    
    window.alert('form populated for debugging');
  }
  
  //  ----- address actions ------------------
  
  if (s == 'city')   		df.city.value 		= stripComma(df.city.value.toCityCase()		);
  if (s == 'city2')   		df.city2.value 		= stripComma(df.city2.value.toCityCase()	);
  if (s == 'postcode')  	df.postcode.value 	= stripComma(df.postcode.value.toUpperCase()	);
  if (s == 'postcode2')  	df.postcode2.value 	= stripComma(df.postcode2.value.toUpperCase()	);
  if (s == 'surname')   	df.surname.value 	= stripComma(df.surname.value.toUpperCase()	);
  if (s == 'surname2')   	df.surname2.value 	= stripComma(df.surname2.value.toUpperCase()	);
  if (s == 'fname')  		df.fname.value 		= stripComma(df.fname.value.toTitleCase()	);
  if (s == 'fname2')    	df.fname2.value 	= stripComma(df.fname2.value.toTitleCase()	);
  if (s == 'postcode')  	checkPostcode(df.postcode.value, 'B');
  if (s == 'postcode2')  	checkPostcode(df.postcode2.value, 'C');

  // added on 29-jun-08
  if (s == 'building')		df.building.value	= stripComma(df.building.value.toTitleCase()	);
  if (s == 'street_line1') 	df.street_line1.value	= stripComma(df.street_line1.value.toTitleCase());
  if (s == 'street_line2') 	df.street_line2.value	= stripComma(df.street_line2.value.toTitleCase());
  if (s == 'building2')		df.building2.value	= stripComma(df.building2.value.toTitleCase()	);
  if (s == 'street_line1_2') 	df.street_line1_2.value	= stripComma(df.street_line1_2.value.toTitleCase());
  if (s == 'street_line2_2') 	df.street_line2_2.value	= stripComma(df.street_line2_2.value.toTitleCase());
  

  // added on 30-jun-08

  if ((s == 'street_line1') | (s == 'street_line2'))
  { if (df.street_line1.value == df.street_line2.value)  	{ df.street_line2.value = ''; } }

  if ((s == 'city') | (s == 'street_line2'))
  { if (df.street_line2.value.toUpperCase() == df.city.value)	{ df.street_line2.value = ''; } }

  if (s == 'building')
  {  if (df.building.value == parseInt(df.building.value))	
     { df.street_line1.value = df.building.value + ' ' + df.street_line1.value;
       df.building.value = '';
  }  }

  if ((s == 'street_line1_2') | (s == 'street_line2_2'))
  { if (df.street_line1_2.value == df.street_line2_2.value)  	{ df.street_line2_2.value = ''; } }

  if ((s == 'city2') | (s == 'street_line2_2'))
  { if (df.street_line2_2.value.toUpperCase() == df.city2.value){ df.street_line2_2.value = ''; } }

  if (s == 'building2')
  {  if (df.building2.value == parseInt(df.building2.value))	
     { df.street_line1_2.value = df.building2.value + ' ' + df.street_line1_2.value;
       df.building2.value = '';
  }  }

  
  //  ----- country radio-button actions -------------------
  
  function clearAllButUK()  { df.WE_list.selectedIndex =0; df.EE_list.selectedIndex =0; df.ROW_list.selectedIndex =0; df.otherCountries.value = ''}
  function clearAllButWE()  {                              df.EE_list.selectedIndex =0; df.ROW_list.selectedIndex =0; df.otherCountries.value = ''}
  function clearAllButEE()  { df.WE_list.selectedIndex =0;                              df.ROW_list.selectedIndex =0; df.otherCountries.value = ''}
  function clearAllButROW() { df.WE_list.selectedIndex =0; df.EE_list.selectedIndex =0;                              }
  
  if ( s == 'UK')   { clearAllButUK(); }
  if ( s == 'WE')   { clearAllButWE(); }
  if ( s == 'EE')   { clearAllButEE(); }
  if ( s == 'ROW')  { clearAllButROW(); }
 
  if ((s == 'WE')  & (df.WE_list.selectedIndex == 0))  countryAlert();  
  if ((s == 'EE')  & (df.EE_list.selectedIndex == 0))  countryAlert();  
  if ((s == 'ROW') & (df.ROW_list.selectedIndex == 0)) countryAlert();  
    
  //  ----- country2 radio-button actions -------------------
  
  function clearAllButUK2()  { df.WE_list2.selectedIndex =0; df.EE_list2.selectedIndex =0; df.ROW_list2.selectedIndex =0; df.otherCountries2.value = ''}
  function clearAllButWE2()  {                               df.EE_list2.selectedIndex =0; df.ROW_list2.selectedIndex =0; df.otherCountries2.value = ''}
  function clearAllButEE2()  { df.WE_list2.selectedIndex =0;                               df.ROW_list2.selectedIndex =0; df.otherCountries2.value = ''}
  function clearAllButROW2() { df.WE_list2.selectedIndex =0; df.EE_list2.selectedIndex =0;                              }
  
  if ( s == 'UK2')   { clearAllButUK2(); }
  if ( s == 'WE2')   { clearAllButWE2(); }
  if ( s == 'EE2')   { clearAllButEE2(); }
  if ( s == 'ROW2')  { clearAllButROW2(); }
 
  if ((s == 'WE2')  & (df.WE_list2.selectedIndex == 0))  countryAlert();  
  if ((s == 'EE2')  & (df.EE_list2.selectedIndex == 0))  countryAlert();  
  if ((s == 'ROW2') & (df.ROW_list2.selectedIndex == 0)) countryAlert();  

  //  ----- country drop-down list actions ------------------
  
  $maxCountryList = 13;
  
  if ((s == 'WE_list')  & (df.WE_list.selectedIndex !=0))  { df.country[1].checked = true; clearAllButWE(); }
  if ((s == 'EE_list')  & (df.EE_list.selectedIndex !=0))  { df.country[2].checked = true; clearAllButEE(); }
  if ((s == 'ROW_list') & (df.ROW_list.selectedIndex !=0)) { df.country[3].checked = true; clearAllButROW(); }
  
  if ((s == 'ROW_list') & (df.ROW_list.selectedIndex == $maxCountryList)) 
  { window.alert('If your country is not in this list, \nplease type it in the box below'); }
  
  if ((s == 'ROW_list') & (df.ROW_list.selectedIndex != $maxCountryList)) 
  { df.otherCountries.value = ''; }
  
  
 if (s == 'otherCountries')
 {
   if ((df.otherCountries.value != '') & (df.otherCountries.value != df.ROW_list[df.ROW_list.selectedIndex].text))
   {
     df.ROW_list.selectedIndex = $maxCountryList;
     df.country[3].checked = true; 
     clearAllButROW();
     df.otherCountries.value = df.otherCountries.value.toTitleCase();
   }
 } 
    
  //  ----- country2 drop-down list actions ------------------
  
  if ((s == 'WE_list2')  & (df.WE_list2.selectedIndex !=0))  { df.country2[1].checked = true; clearAllButWE2(); }
  if ((s == 'EE_list2')  & (df.EE_list2.selectedIndex !=0))  { df.country2[2].checked = true; clearAllButEE2(); }
  if ((s == 'ROW_list2') & (df.ROW_list2.selectedIndex !=0)) { df.country2[3].checked = true; clearAllButROW2(); }
  
  if ((s == 'ROW_list2') & (df.ROW_list2.selectedIndex == $maxCountryList)) 
  { window.alert('If your country is not in this list, \nplease type it in the box below'); }
  
  if ((s == 'ROW_list2') & (df.ROW_list2.selectedIndex != $maxCountryList)) 
  { df.otherCountries2.value = ''; }
  
  
 if (s == 'otherCountries2')
 {
   if ((df.otherCountries2.value != '') & (df.otherCountries2.value != df.ROW_list2[df.ROW_list2.selectedIndex].text))
   {
     df.ROW_list2.selectedIndex = $maxCountryList;
     df.country2[3].checked = true; 
     clearAllButROW2();
     df.otherCountries2.value = df.otherCountries2.value.toTitleCase();
   }
 } 
 
  //  ----- Copy settings to 2nd address
  
  if (s == 'copyC2')
  {
    df.org2.value	 	= df.org.value;
    df.fname2.value	 	= df.fname.value;
    df.surname2.value	 	= df.surname.value;
    df.position2.value	 	= df.position.value;
    df.building2.value	 	= df.building.value;
    df.street_line1_2.value	= df.street_line1.value;
    df.street_line2_2.value	= df.street_line2.value;
    df.city2.value	 	= df.city.value;
    df.postcode2.value	 	= df.postcode.value;
    df.country2[0].checked 	= df.country[0].checked;
    df.country2[1].checked 	= df.country[1].checked;
    df.country2[2].checked 	= df.country[2].checked;
    df.country2[3].checked 	= df.country[3].checked;
    df.WE_list2.selectedIndex 	= df.WE_list.selectedIndex;
    df.EE_list2.selectedIndex 	= df.EE_list.selectedIndex;
    df.ROW_list2.selectedIndex 	= df.ROW_list.selectedIndex;
    df.otherCountries2.value	= df.otherCountries.value;
    
  }
  
  if (s == 'eraseC2')  eraseCountry2() ;

  //  ----- from country settings, select postage type

  // if (df.country[0].checked)  // UK
  // clear these to begin with, always.
  {
    df.post_sp_WE.checked = false;
    df.post_sp_ROW.checked = false;
    df.post_cks_WE.checked = false;
    df.post_cks_ROW.checked = false;
  }
  
  if (df.country[1].checked)  // WE
  {
    if (df.speleology.checked) 	df.post_sp_WE.checked 	= true;
    if (df.cks.checked) 	df.post_cks_WE.checked 	= true;
  }
   
  if ((df.country[2].checked) | (df.country[3].checked))  // EE and ROW
  {
    if (df.speleology.checked) 	df.post_sp_ROW.checked 	= true;
    if (df.cks.checked) 	df.post_cks_ROW.checked	= true;
  }
  
  /* What a fucking pain. Although Firefox likes {select.value} MSIE seems not
     to consider {value} to be a property of {select}, and therefore requires
     {select[select.selectedIndex].text}
  */
  
  if (df.country[0].checked) country1 = '';
  if (df.country[1].checked) country1 = df.WE_list[df.WE_list.selectedIndex].text;
  if (df.country[2].checked) country1 = df.EE_list[df.EE_list.selectedIndex].text;
  if (df.country[3].checked) 
  {
    if (df.ROW_list.selectedIndex == $maxCountryList)
          { country1 = df.otherCountries.value; }
    else  { country1 = df.ROW_list[df.ROW_list.selectedIndex].text;       }
  }
  countryWithEU = country1;
  $regexp = ' \(EU\)';
  country1 = country1.replace($regexp,'');

  //  ----- country2 value ------
  
  if (df.country2[0].checked) country2 = '';
  if (df.country2[1].checked) country2 = df.WE_list2[df.WE_list2.selectedIndex].text;
  if (df.country2[2].checked) country2 = df.EE_list2[df.EE_list2.selectedIndex].text;
  if (df.country2[3].checked) 
  {
    if (df.ROW_list2.selectedIndex == $maxCountryList)
          { country2 = df.otherCountries2.value; }
    else  { country2 = df.ROW_list2[df.ROW_list2.selectedIndex].text;       }
  }
  country2 = country2.replace($regexp,'');
  
  // ----- discounts -----
  
  if ((s == 'ugrad') 	 & (df.ugrad.checked)) 		df.freeissue.checked = false; 
  if ((s == 'freeissue') & (df.freeissue.checked)) 	df.ugrad.checked = false; 
  if ((s == 'freeissue') & (!df.freeissue.checked)) 	
  { 
    df.freeissueclass.selectedIndex = 0; 
    df.auth.value = '';
  }
  
  // ----- deal with free-issue items -----
  
  /*
  if ((s == 'bcanews') | (s == 'bcranews'))
  {
    if ((df.bcanews.checked) | (df.bcranews.checked))
    {
      window.alert('Newsletter are only available to certain special\n' +
    		 'classes of subscription (See section F).');
    }
  }
  */
  
  if ((s == 'freeissueclass') & (df.freeissueclass.selectedIndex !=0))  
  {  df.freeissue.checked = true; df.ugrad.checked = false;  }
  
  if ((s == 'freeissueclass') & (df.freeissueclass.selectedIndex == 0) & (df.freeissue.checked == true))  
  { df.freeissue.checked = false; }
  
 
  // ----- calculate the fees
  
  j=0;
  df.fee_speleology.value	= money_blankzero(df.speleology.checked			* fees[j++]); 
  df.fee_cks.value		= money_blankzero(df.cks.checked			* fees[j++]); 
//df.fee_bcanews.value		= money_blankzero(df.bcanews.checked			* fees[j++]); 
//df.fee_bcranews.value		= money_blankzero(df.bcranews.checked			* fees[j++]); 

  df.fee_post_sp_WE.value 	= money_blankzero(df.post_sp_WE.checked 		* fees[j++]);
  df.fee_post_sp_ROW.value 	= money_blankzero(df.post_sp_ROW.checked 		* fees[j++]);
  df.fee_post_cks_WE.value 	= money_blankzero(df.post_cks_WE.checked 		* fees[j++]);
  df.fee_post_cks_ROW.value 	= money_blankzero(df.post_cks_ROW.checked 		* fees[j++]);
  
  $sp_total =   readMoney(df.fee_speleology.value) +
		readMoney(df.fee_post_sp_WE.value) +
		readMoney(df.fee_post_sp_ROW.value);

  $cks_total = 	readMoney(df.fee_cks.value) +
		readMoney(df.fee_post_cks_WE.value) +
		readMoney(df.fee_post_cks_ROW.value) ;

  $subtotal =   $sp_total + $cks_total;
  
  df.fee_subtotal.value =  money_blankzero($subtotal);
			
  df.fee_ugrad.value		= money_blankzero(df.ugrad.checked 	* $cks_total	* fees[j++]/100);
  df.fee_freeissue.value	= money_blankzero(df.freeissue.checked  * $subtotal	* fees[j++]/100);
  
  $total = 	readMoney(df.fee_subtotal.value) +
  		readMoney(df.fee_ugrad.value) +
		readMoney(df.fee_freeissue.value);

  fraction = '';
  // need to calculate fraction using fees[], really
  if (df.freeissue.checked)  { $sp_total = 0; $cks_total = 0; fraction = '100%';}		// to use in CSV
  if (df.ugrad.checked)      { $cks_total += readMoney(df.fee_ugrad.value); fraction = '50%';}	// to use in CSV
  
  
  df.fee_total.value =  money($total);

}

// ======================================================
// Check and submit form
// ======================================================

function checkAndSubmit(button)
{
  if (button != '_submit')
  {
    window.alert('Submitting debug info without populating form');
  }
  if (!checkUserInput()) return false;
  
  buildPurchaseOrder();
  addSubsInfo();
  addValuesToForm();
  df.submit(); 
}
  




  //  -----  Check user input ---------------------------
  
function eraseCountry2()
{
    df.org2.value	 	= '';
    df.fname2.value	 	= '';
    df.surname2.value	 	= '';
    df.position2.value	 	= '';
    df.building2.value	 	= '';
    df.street_line1_2.value	= '';
    df.street_line2_2.value	= '';
    df.city2.value	 	= '';
    df.postcode2.value	 	= '';
    df.country2[0].checked 	= true;
    df.WE_list2.selectedIndex 	= '';
    df.EE_list2.selectedIndex 	= '';
    df.ROW_list2.selectedIndex	= '';
    df.otherCountries2.value	= '';
}

function compareAddresses() 
{
  return (
    (df.org2.value	 	== df.org.value) & 
    (df.fname2.value	 	== df.fname.value) & 
    (df.surname2.value	 	== df.surname.value) & 
    (df.position2.value	 	== df.position.value) & 
    (df.building2.value	 	== df.building.value) & 
    (df.street_line1_2.value	== df.street_line1.value) & 
    (df.street_line2_2.value	== df.street_line2.value) & 
    (df.city2.value	 	== df.city.value) & 
    (df.postcode2.value	 	== df.postcode.value) & 
    (df.country2[0].checked 	== df.country[0].checked) & 
    (df.country2[1].checked 	== df.country[1].checked) & 
    (df.country2[2].checked 	== df.country[2].checked) & 
    (df.country2[3].checked 	== df.country[3].checked) & 
    (df.WE_list2.selectedIndex 	== df.WE_list.selectedIndex) & 
    (df.EE_list2.selectedIndex 	== df.EE_list.selectedIndex) & 
    (df.ROW_list2.selectedIndex	== df.ROW_list.selectedIndex) & 
    (df.otherCountries2.value	== df.otherCountries.value)
    )
}
  
function address2Blank() 
{
  return (
    (df.org2.value	 	== '') & 
    (df.fname2.value	 	== '') & 
    (df.surname2.value	 	== '') & 
    (df.position2.value	 	== '') & 
    (df.building2.value	 	== '') & 
    (df.street_line1_2.value	== '') & 
    (df.street_line2_2.value	== '') & 
    (df.city2.value	 	== '') & 
    (df.postcode2.value	 	== '') & 
    (df.country2[0].checked 	== true) & 
    (df.otherCountries2.value	== '')
    )
}
  
function checkUserInput()
{  
  //  ----- check integrity of name and address -----
 
   if ((df.surname.value == '') & (df.org.value == '') & (df.position.value == ''))
      { window.alert('Your name and address appears to be  \nincomplete in section B.'); return false; }
      		    
   if ((df.building.value != '') & (df.street_line1.value == ''))
   {
     df.street_line1.value = df.building.value;
     df.building.value = '';
   }

   if ((df.building2.value != '') & (df.street_line1_2.value == ''))
   {
     df.street_line1_2.value = df.building2.value;
     df.building2.value = '';
   }

   if ((df.street_line1.value == '') | (df.city.value == ''))
     { window.alert('Your postal address appears to be  \nincomplete in section B.'); return false; }

   if ((df.country[0].checked) & (df.postcode.value == ''))
     { window.alert('Your postcode is missing in section B.'); return false; }
     
   use2ndAddress = !((df.surname2.value == '') & (df.org2.value == '') & (df.position2.value == ''));
   
   if ((!use2ndAddress) & (!address2Blank))
     { window.alert('The correspondence address in section C\nappears to be incomplete. Please \n' +
     		    'complete it or delete it.'); return false; }
 
   if (use2ndAddress)
   {
     if ((df.street_line1_2.value == '') | (df.city2.value == ''))
     { window.alert('Your postal address appears to be  \nincomplete in section C.'); return false; }

     if ((df.country2[0].checked) & (df.postcode2.value == ''))
     { window.alert('Your postcode is missing in section C.'); return false; }
     
     if (compareAddresses())
     { window.alert('The delivery address was the same as the \n' +
    		 'correspondence address. If this is correct \n' +
    		 'please delete the correspondence address. \n'); return false; }
   }

  //  ----- check country data has been given ---------
  
  if ((df.country[1].checked) & (df.WE_list.selectedIndex == 0))
    { window.alert('You have indicated an overseas address [WE], but \n' +
    		   'you have not selected a country in section B.');   return false; }

  if ((df.country[2].checked) & (df.EE_list.selectedIndex == 0))
    { window.alert('You have indicated an overseas address [EE], but \n' +
    		   'you have not selected a country in section B.');   return false; }

  if ((df.country[3].checked) & (df.ROW_list.selectedIndex == 0))
    { window.alert('You have indicated an overseas address [RW], but \n' +
    		   'you have not selected a country in section B.');   return false; }

  if ((df.country[3].checked) & (df.ROW_list.selectedIndex == $maxCountryList) & (df.otherCountries.value = ""))
    { window.alert('You have indicated an overseas address [RW], but \n' +
    		   'you have not selected a country from the list or \n' +
    		   'typed one in the box in section B.');   return false; }
    		   
  //  ----- check country2 data has been given ---------
  
  if ((df.country2[1].checked) & (df.WE_list2.selectedIndex == 0))
    { window.alert('You have indicated an overseas address [WE], but \n' +
    		   'you have not selected a country in section C.');   return false; }

  if ((df.country2[2].checked) & (df.EE_list2.selectedIndex == 0))
    { window.alert('You have indicated an overseas address [EE], but \n' +
    		   'you have not selected a country in section C.');   return false; }

  if ((df.country2[3].checked) & (df.ROW_list2.selectedIndex == 0))
    { window.alert('You have indicated an overseas address [RW], but \n' +
    		   'you have not selected a country in section C.');   return false; }

  if ((df.country2[3].checked) & (df.ROW_list2.selectedIndex == $maxCountryList) & (df.otherCountries2.value = ""))
    { window.alert('You have indicated an overseas address [RW], but \n' +
    		   'you have not selected a country from the list or \n' +
    		   'typed one in the box in section C.');   return false; }
    		   
    // ----- use of postcode boxes ------------------------------

  if ((!df.country[0].checked) & (df.postcode.value != ''))
    { window.alert('You have indicated an overseas address but you\n' +
    		   'have typed a postcode in the \'UK postcode\' box\n' +
    		   'in section B. Please delete this and read the \n' +
    		   'note on overseas addresses in section B.');   return false; }

  if ((!df.country2[0].checked) & (df.postcode2.value != ''))
    { window.alert('You have indicated an overseas address but you\n' +
    		   'have typed a postcode in the \'UK postcode\' box\n' +
    		   'in section C. Please delete this and read the \n' +
    		   'note on overseas addresses in section B.');   return false; }

  if (!checkPostcode(df.postcode.value,  'B')) return false;
  if (!checkPostcode(df.postcode2.value, 'C')) return false;
    		   
   // ----- check for illegal characters, used for substitutions in csv -----
 
  for (var i=0; i < df.elements.length; i++)
  {
    var f = df.elements[i].value;
    if ( (f.indexOf('$') != -1) | (f.indexOf('=') != -1))
    {
      window.alert('You have typed a character ($ or =) that is not permitted. \n' +
     		   'Please check all the boxes carefully and try again.\n\n' + f);
      return false;
    }
  }

  
  //  ----- check that something has been ordered -----
  
  if ((!df.speleology.checked) & (!df.cks.checked)) // & (!df.bcanews.checked) & (!df.bcranews.checked))
  {
    window.alert('You have not selected any publications \nin section D.');
    return false;
  }

  //  ----- warn if newsletters selected ----------------
  
  /*
  if (((df.bcanews.checked) | (df.bcranews.checked)) & (!freeIssueNews[df.freeissueclass.selectedIndex]))
  {
    window.alert('You have requested newsletters in section E. These are \n' +
    		 'not available on subscription except in certain very \n' +
    		 'limited situations. Please uncheck the newsletter boxes \n' +
    		 'or select the free-issue subscription you have agreed \n' +
    		 'with BCA.');
    return false;
  }
  */
  if (!df.freeissue.checked)
  { df.freeissueclass.selectedIndex = 0;  df.auth.value = ''; }
  
  //  ----- free-issue subscriptions ----------------



  if ((df.freeissue.checked) & (df.freeissueclass.selectedIndex == 0))
  {
    window.alert('You have requested a free-issue subscription \n' +
    		 'but you have not given a reason in section F.');
    return false;
  }
    
  if ((df.freeissue.checked) & (df.auth.value == ''))
  {
    window.alert('You have requested a free-issue subscription \n' +
    		 'but you have not given an authorisation code \n' +
    		 'in section F. You must obtain this from BCA or BCRA.');
    return false;
  }
  
  // authorisation must be at least 5 characters including a final full-stop
  if ((df.freeissue.checked) & ((df.auth.length < 5) | (df.auth.value.slice(-1) != '.')) )
  {
    window.alert('You have requested a free-issue subscription \n' +
    		 'but you have not given a valid authorisation code \n' +
    		 'in section F. You must obtain this from BCA or BCRA.');
    return false;
  }

  // ----- everything is in order ------
  
  return true;
}



//  ----- display free-issue reasons ----------

function showReasons()
{
  aw=5*screen.width/8;
  ah=4*screen.height/8;
  ax=(screen.width-aw)/2;
  ay=(screen.height-ah)/2;
  as = 'height='+ah+',width='+aw+',left='+ax+',screenX='+ax+',top='+ay+',screenY='+ay;
  a=window.open('reasons.html', 'reasons', as + ',status=yes,resizable=yes,scrollbars=yes'); 
  a.focus();
}


// ======================================================
// Write Purchase Order
// ======================================================

function buildPurchaseOrder()
{
  log = 'Form M4: Application for Subscription to Periodicals \n' +
        '---------------------------------------------------- \n\n';

// ----- add money --------------------------------------        

  memClass = 'SUB-';
  if (df.freeissue.checked) memClass = 'SUBF-';
  
//if (df.bcranews.checked)    {log += 'BCRA Newsletter                            ' +  df.fee_bcranews.value + '\n';	memClass +='B'; }
  if (df.cks.checked)  	      {log += 'Cave and Karst Science (print edition)     ' +  df.fee_cks.value + '\n';		memClass +='K'; }
//if (df.bcanews.checked)     {log += 'BCA Newsletter                             ' +  df.fee_bcanews.value + '\n';	memClass +='N'; }
  if (df.speleology.checked)  {log += 'Speleology                                 ' +  df.fee_speleology.value + '\n';	memClass +='S'; }
  if (df.country[0].checked)  { log += 'Postage of publications to a UK address    ' + money(0) + '\n';  countryCode = 'UK'}
                                       
  if (df.country[1].checked)  { log += 'Postage of publications to Western Europe\n';  countryCode = 'WE'}
  if (df.country[2].checked)  { log += 'Postage of publications to Eastern Europe\n';  countryCode = 'EE'}
  if (df.country[3].checked)  { log += 'Postage of publications to outside Europe\n';  countryCode = 'RW'}
  
  if (!df.country[0].checked) { log += '  Country: ' + countryWithEU + '\n';}
  
  if (df.post_sp_WE.checked)  { log +=  '  Speleology                               ' + df.fee_post_sp_WE.value + '\n' };
  if (df.post_sp_ROW.checked) { log +=  '  Speleology                               ' + df.fee_post_sp_ROW.value + '\n' };
  if (df.post_cks_WE.checked) { log +=  '  Cave & Karst Science (print edition)     ' + df.fee_post_cks_WE.value + '\n' };
  if (df.post_cks_ROW.checked){ log +=  '  Cave & Karst Science (print edition)     ' + df.fee_post_cks_ROW.value + '\n' };
  
  log +=                                '                                              -----\n' + 
                                        'Sub-total                                  ' + df.fee_subtotal.value + '\n';
    
  if (df.ugrad.checked)       { log +=  fees[6] + '% undergraduate discount                ' + df.fee_ugrad.value + '\n' };
  if (df.freeissue.checked)   { log +=  fees[7] + '% discount for free-issue subs.        ' + df.fee_freeissue.value + '\n';
  				log +=  'Reason: ' + df.freeissueclass[df.freeissueclass.selectedIndex].text + '\n';
  			      }
  
  log +=                                '                                              -----\n' + 
                                        'Total                                      ' + df.fee_total.value + '\n\n';

// ----- add name and address ---------------------------        
// HE08 uses form of...     addr += punctuate(df.locality.value);

  $org  = (df.org.value != '');
  $post = (df.position.value != '');
  $name = (df.surname.value  != '');
  $fname = df.fname.value; if ($fname != '') $fname += ' ';
  
  if ($org) 				log += df.org.value + '\n';
  
  $composite = '';   $composite2 = '';
  if (($org) & (($post) | ($name)))	$composite += '(';
  if ($name)				$composite += $fname + df.surname.value;
  if (($post) & ($name))		$composite += ', ';
  if ($post)				$composite += df.position.value;
  if (($org) & (($post) | ($name)))	$composite += ')';
  if (($post) | ($name))		log += $composite + '\n';
  
  if (df.building.value !='') 		log += df.building.value + '\n';
  if (df.street_line1.value !='') 	log += df.street_line1.value + '\n';
  if (df.street_line2.value !='') 	log += df.street_line2.value + '\n';
  if (df.city.value !='') 		log += df.city.value + '\n';
  if (df.postcode.value !='') 		log += df.postcode.value + '\n';
  if (country1 !='') 			log += country1 + '\n';
  
// ----- add membership class etc -----------------------        
  
  log += '\nAgency reference number                    ' ;
  if (df.agency.value == '') {log += '(none)'; } else {log += df.agency.value; }
  log += '\n';

  if (df.freeissueclass.selectedIndex != 0) 
  {
    memClass += '-' + freeIssueValues[df.freeissueclass.selectedIndex];
  }

  log += 'Subscription Class                         ' + memClass + '\n';
  
  // ======================= add periodicals info =============================
  
  periodicals = '';
  if (df.speleology.checked)
  { periodicals += 's' + $SpeleoList + $speleoIssue; }
  if (df.cks.checked)
  { periodicals += 'k' + $cksList + $cksNumber; }
  
  log += 'Periodicals code (for office use)          ' + periodicals  + '\n';

  if (df.freeissueclass.selectedIndex != 0)
  {
    log +=   'Authorisation for free-issue subscription: ' ;
    if (df.auth.value == '') {log += '(none)'; } else {log += df.auth.value; }
    log += '\n';
  }
  log +=     'Country code                               ' + countryCode  + '\n';
  
// ----- add 2nd name and address ---------------------------        

    if (df.country2[0].checked)  { country2Code = 'UK'}                                       
    if (df.country2[1].checked)  { country2Code = 'WE'}
    if (df.country2[2].checked)  { country2Code = 'EE'}
    if (df.country2[3].checked)  { country2Code = 'RW'}

  if (use2ndAddress)
  {
    log +=      '\nSecond address for correspondence?         Yes: ' + country2Code  + '\n';

  $org  = (df.org2.value != '');
  $post = (df.position2.value != '');
  $name = (df.surname2.value  != '');
  $fname2 = df.fname2.value; if ($fname2 != '') $fname2 += ' ';
  if ($org) 				log += df.org2.value + '\n';

  if (($org) & (($post) | ($name)))	$composite2 += '(';
  if ($name)				$composite2 += $fname2 + df.surname2.value;
  if (($post) & ($name))		$composite2 += ', ';
  if ($post)				$composite2 += df.position2.value;
  if (($org) & (($post) | ($name)))	$composite2 += ')';
  if (($post) | ($name))		log += $composite2 + '\n';
    
    if (df.building2.value !='') 	log += df.building2.value + '\n';
    if (df.street_line1_2.value !='') 	log += df.street_line1_2.value + '\n';
    if (df.street_line2_2.value !='') 	log += df.street_line2_2.value + '\n';
    if (df.city2.value !='') 		log += df.city2.value + '\n';
    if (df.postcode2.value !='') 	log += df.postcode2.value + '\n';
    if (country2 !='') 			log += country2 + '\n';
  }
  else
  { 
    country2Code = '';
    log +=      '\nSecond address for correspondence?         No\n'; 
  }
}

// ======================================================
// Write subscription info
// ======================================================

  //  ----- Add info about subscription dates. This will eventually read parameters 
  // -----  from a txt file or other source. But now now, it is hard-coded.

function addSubsInfo()
{
  if (df.message.value != '') 
  { log += '\n* Message to BCA: ' + df.message.value + '\n'; }

  
  if (df.speleology.checked)
  { 
    log += '\n* The next issue of Speleology to be published will be #' + $speleoIssue + '. '; 
    if ($SpeleoList == '@')
    { 
      log += 'Please note that the previous issue is currently in press - see note below. '; 
    }
    log += '\n';  
  }
  
  if (df.cks.checked)
  { 
    log += '\n* The next issue of Cave and Karst Science to be published will be volume ' +
           $cksVolume + '(' + $cksIssue + '). ';

    if ($cksIssue > 1)
    { log += 'If our records show that you have not received the earlier issues of this volume ' +
      ' we will send them to you, but please allow four weeks for delivery. '; }
  
    if (($cksList != '')&($cksIssue > 1))
    { log += 'Please note that the previous issue is currently in press - see note below. '; 
    }
    log += '\n';
  }
  
  if ( ((df.speleology.checked)&($SpeleoList == '@')) | ((df.cks.checked)&($cksList == '@')&($cksIssue > 1)) )
  { log += '\n* Issues in press: Our printer has already been sent a mailing list, ' +
  	   'which cannot be updated to allow for your current order. Your item(s) will therefore be mailed separately, and ' +
  	   'this may take a while to arrange. Please allow four weeks before enquiring.\n'; 
  }

  if (freeIssueReview[df.freeissueclass.selectedIndex])
  { log += '\n* Your free subscription (reason: ' + df.freeissueclass[df.freeissueclass.selectedIndex].text + 
    ') will be reviewed on expiry. Depending on the class ' +
    'of the subscription, we may ask you to re-confirm your eligibility.\n' }
    
  log += '\n';


}  

// ======================================================
// Add useful parameters to Form
// ======================================================

// to make the PHP simpler, we record a few additional variables
// order, memberexpiry, periodicals, countryname, memClass, memClass2, breakdown
// When the order form is assembled in PHP, these might not be needed here.

function addValuesToForm()
{
  df.formtype.value = 'BCA9-M4-0v1';
  df.order_js.value 	= log;
//  df.memberexpiry.value	= $memberexpiry;
  df.periodicals.value	= periodicals;
  df.countryname.value	= country1;
  df.memClass.value	= memClass;
//  df.memClass2.value	= memClass2;

  df.nameandpost.value	= $composite;
  df.nameandpost2.value	= $composite2;


  df.breakdown.value = 0 + ',' + 
  	0 + ',' + 
  	$sp_total + ',' + 
  	$cks_total + ',' + 
	fraction;
}
