/********************************************************************************
// This is a collection of JavaScript code to allow easy integration of 
// postcode lookup functionality into any website
//
// Provided by www.CraftyClicks.co.uk
//
// Version - 2.2.1  (08/12/2008)
//
// Feel free to copy/use/modify this code any way you see fit. Please keep this
// comment header in place when you do.
//
// To integrate UK postcode lookup on your website, please visit www.craftyclicks.co.uk for
// details of how to sign up for an account.
//
// Compacted by ScriptingMagic.com to speed up load time, if you want the full version, please email us.
**********************************************************************************/
var _cp_config = { 
	lookup_url		: 'pcls1.craftyclicks.co.uk/lookup_js.php', // url to use for lookup
	access_token	: '', // specify access token here to use the direct JS method,  lookup_url must be set to 'http://pcls1.craftyclicks.co.uk/lookup_js.php'
	form			: '',	// if left blank in/out elements will be shearched by id, if provided elemts will be searched by name
	elements		: 'crafty_out_company,crafty_out_street1,crafty_out_street2,crafty_out_street3,crafty_out_town,crafty_out_county,crafty_in_out_postcode', // element ids or form fields
	traditional_county	: 0, // 0 - postal county, 1 - traditional county name
	busy_img_url	: '../images/crafty_postcode_busy.gif',	// full url of the gif to show when waiting for result
	max_width		: '423px',  // width of the results box in px
	max_lines		: 0,		// height of the rsults box in text lines
	hide_result		: 0,		// 1 - results box disappears once a result is clicked, 0 - it stays up
	org_uppercase	: 0,		// 0 - leading uppercase, 1- all in uppercase
	town_uppercase	: 0,		// 0 - leading uppercase, 1- all in uppercase
	county_uppercase: 0,		// 0 - leading uppercase, 1- all in uppercase
	addr_uppercase	: 0,		// 0 - leading uppercase, 1- all in uppercase
	delimiter		: ', ',
	msg1			: 'Please wait while we find the address',
	err_msg1		: 'This postcode could not be found, please try again or enter your address manually',
	err_msg2		: 'This postcode is not valid! Please try again or enter your address manually',
	err_msg3		: 'Unable to connect to address lookup server, please enter your address manually.',
	err_msg4		: 'An unexpected error occured, please enter your address manually.',
	res_autoselect	: 0, // the first result will be auto-selected by default
	res_select_on_change : 1, // 1 - if the user scrolls through the results they will be selected, 0 - user must explicitly click to select 
	first_res_line	: '----- please select your address ----', // adds a dummy 1st line  eg '----- please select your address ----'
	debug_mode		: 0,
	lookup_timeout	: 10000 // time in ms
};

var _cp_xmlhttp = null;
var _cp_res_arr = null;
var _cp_disp_arr = null;
var _cp_res_arr_idx = 0;
var _cp_cc = 0;
var _cp_res_locality = null;
var _cp_clean_pc = '';
var _cp_lookup_timeout = null;

function cp_set_config(field, val){
	_cp_config[field] = val;
}

function _cp_res_clicked(idx) {
	_cp_cc++;
	if (_cp_res_selected(idx)) {
		if(0 != _cp_config.hide_result && ( (2 >=_cp_config.max_lines && 1 < _cp_cc) || (2 < _cp_config.max_lines) ) ) {
			_cp_update_res(null);
			_cp_cc = 0;
		}
	}
}

function _cp_res_key_press(idx, e){
	var cc;
	if (!e) var e = window.event;
	if(e.keyCode) {cc = e.keyCode;}
	else if(e.which) {cc = e.which;}
	if(cc == 13){
		_cp_cc = 1;
		_cp_res_clicked(idx);
	}
}

function _cp_res_selected(index) {
	if ('' != _cp_config.first_res_line) {
		if (0 == index) {
			return 0; // don't select the dummy first line if present
		} else {
			index--;
		}
	}

	var elem = new Array();
	var dc = _cp_config.delimiter;
	
	for (i=0; i<6; i++) {
		elem[i] = _cp_get_elem(i);
	}	
	// translate index
	index = _cp_disp_arr[index]['index'];
	var selected_line = _cp_res_arr[index]; 

	if (elem[0]) { // company
		elem[0].value = selected_line['org'];
	}

	var str1 = selected_line['street1'];
	var str2 = selected_line['street2'];
	var combined_street =  str2 + (str2==''?'':dc) + str1;
	var locality_dep = _cp_res_locality['locality_dep'] ;
	var locality = _cp_res_locality['locality'] ;
	if ('' != combined_street && parseInt(combined_street) == combined_street) {
		if ('' != locality_dep) {
			locality_dep = parseInt(combined_street) + ' ' + locality_dep;
		} else {
			locality = parseInt(combined_street) + ' ' + locality;
		}
		combined_street = ''; str1 = '';
	}
	var combined_loc =  locality_dep + (locality_dep==''?'':dc) + locality;
	var combined_str_loc = combined_street + (combined_street==''?'':dc) + combined_loc;
	
	if (elem[1] && elem[2] && elem[3]) {
		if ('' != selected_line['pobox'] || '' != selected_line['housename']) {
			if ('' != selected_line['pobox']) { elem[1].value = selected_line['pobox']; } else { elem[1].value = selected_line['housename']; }
			if ('' == combined_loc) {
				if ('' == str2) {
					elem[2].value = str1;
					elem[3].value = '';
				} else {
					elem[2].value = str2;
					elem[3].value = str1;
				}
			} else if ('' == combined_street) {
				if ('' == locality_dep) {
					elem[2].value = locality;
					elem[3].value = '';
				} else {
					elem[2].value = locality_dep;
					elem[3].value = locality;
				}
			} else {
				elem[2].value = combined_street;
				elem[3].value = combined_loc;
			}
		} else if ('' == combined_street) { 
			if ('' == locality_dep) {
				elem[1].value = locality;
				elem[2].value = '';
				elem[3].value = '';
			} else {
				elem[1].value = locality_dep;
				elem[2].value = locality;
				elem[3].value = '';
			}
		} else if ('' == combined_loc) { 
			if ('' == str2) {
				elem[1].value = str1;
				elem[2].value = '';
				elem[3].value = '';
			} else {
				elem[1].value = str2;
				elem[2].value = str1;
				elem[3].value = '';
			}
		} else { 
			if ('' == str2) {
				elem[1].value = str1;
				if ('' == locality_dep) {
					elem[2].value = locality;
					elem[3].value = '';
				} else {
					elem[2].value = locality_dep;
					elem[3].value = locality;
				}
			} else {
				if ('' == locality_dep) {
					elem[1].value = str2;
					elem[2].value = str1;
					elem[3].value = locality;
				} else {
					if (combined_street.length < combined_loc.length) {
						elem[1].value = combined_street;
						elem[2].value = locality_dep;
						elem[3].value = locality;
					} else {
						elem[1].value = str2;
						elem[2].value = str1;
						elem[3].value = combined_loc;
					}
				}
			}
		} 
	} else if (elem[1] && elem[2])	{
		if ('' != selected_line['pobox']) {
			elem[1].value = selected_line['pobox'];
			elem[2].value = combined_str_loc; // might be blank
		} else if ('' == selected_line['housename'] && '' != combined_street) {
			if ('' == combined_loc) {
				if ('' != str2) {
					elem[1].value = str2;
					elem[2].value = str1;
				} else {
					elem[1].value = combined_street;
					elem[2].value = '';
				}
			} else {
				elem[1].value = combined_street;
				elem[2].value = combined_loc;
			}
		} else if ('' == combined_street && '' != selected_line['housename']) {
			elem[1].value = selected_line['housename'];
			elem[2].value = combined_loc;
		} else if ('' == combined_loc ) { // got house, street but no loc
			elem[1].value = selected_line['housename'];
			elem[2].value = combined_street;
		} else { // got it all baby! spread it evenly
			if ((selected_line['housename'].length + combined_street.length) < (combined_street.length + combined_loc.length)) {
				elem[1].value = selected_line['housename'] + dc + combined_street;
				elem[2].value = combined_loc;
			} else {
				elem[1].value = selected_line['housename'];
				elem[2].value = combined_street + dc + combined_loc;
			}
		} 
	} else { // only got one line!
		var single_elem;
		if (elem[1]) { single_elem = elem[1]; } else if (elem[2]) { single_elem = elem[2]; } else { single_elem = elem[3]; }
		if ('' != selected_line['pobox']) {
			single_elem.value = selected_line['pobox'] + dc + combined_loc;
		} else {
			single_elem.value = selected_line['housename'] + (selected_line['housename']==''?'':dc) + combined_street + (combined_street==''?'':dc) + combined_loc;
		}
	}
	
	if (elem[4]) {
		elem[4].value = _cp_res_locality['town'];
	}
	
	if (elem[5]) {
		elem[5].value = _cp_res_locality['county'];
	}
	return 1;
}

function _cp_show_busy() {
	var bi = document.createElement('img');
	var na = document.createAttribute('src');
	na.value = _cp_config.busy_img_url;
	bi.setAttributeNode(na);
	na = document.createAttribute('title');
	na.value = _cp_config.msg1;
 	bi.setAttributeNode(na);
	_cp_update_res(bi);
}

function _cp_disp_err(error_code, dbg_msg) {
	var err_node = null;	
	if ('' != error_code) 	{	
		var err_decoded_str = '';
		switch (error_code) {
			case '0001':
				err_decoded_str = _cp_config.err_msg1;
				break;
			case '0002':
				err_decoded_str = _cp_config.err_msg2;
				break;
			case '9001':
				err_decoded_str = _cp_config.err_msg3;
				break;
			default:
				err_decoded_str = '('+error_code+') '+_cp_config.err_msg4;
				break;
		}
		if (_cp_config.debug_mode) {
			var err_info = '';
			switch (error_code) {
				case '8000': err_info = ' :: No Access Token '; break; 
				case '8001': err_info = ' :: Invalid Token Format '; break; 
				case '8002': err_info = ' :: Invalid Token '; break; 
				case '8003': err_info = ' :: Out of Credits '; break; 
			}
			err_decoded_str += err_info+' :: DBG :: '+dbg_msg;
		}
		//err_node = document.createTextNode(err_decoded_str);
		err_node = document.createElement('span');
        err_node.className='postcode_error';       
        err_node.appendChild(document.createTextNode(err_decoded_str));
	}	
	_cp_update_res (err_node);
}

function _cp_disp_err_msg(error_msg) {
	var err_node = null;
	if ('' != error_msg) {	
		err_node = document.createTextNode(error_msg);
	}	
	_cp_update_res (err_node);
}

function _cp_display_res_line(dispstr, index) {
	// see if an options box exists already
	postcodeResult = document.getElementById("crafty_postcode_lookup_result_option");

	if (null != postcodeResult) {	// just add a new line to existing select box
		var newOption = document.createElement('option');
		newOption.appendChild(document.createTextNode(dispstr));
		postcodeResult.appendChild(newOption);
	} else {	// create a new select drop down list
		var newOption = document.createElement('option');
		newOption.appendChild(document.createTextNode(dispstr));
		var newSelection = document.createElement('select');
		newSelection.id = 'crafty_postcode_lookup_result_option';
		newSelection.onclick=function(){_cp_res_clicked(this.selectedIndex)};
		newSelection.onkeypress=function(event){_cp_res_key_press(this.selectedIndex, event)};
 		if (0 != _cp_config.res_select_on_change) {newSelection.onchange=function(){_cp_res_selected(this.selectedIndex)};}
		newSelection.style.width=_cp_config.max_width;
		var num_res_lines = _cp_res_arr_idx;
		if ('' != _cp_config.first_res_line) {
			num_res_lines++;
		}
		if (num_res_lines >= _cp_config.max_lines) {
			newSelection.size=_cp_config.max_lines;
		} else 	{
			newSelection.size=num_res_lines;
		}
		newSelection.appendChild(newOption);
		_cp_update_res(newSelection);
	}
}

function _cp_update_res(new_element) {
	if (_cp_lookup_timeout) {
		clearTimeout (_cp_lookup_timeout);
	}
	
	try	{
		if (document.getElementById) {
			var the_parent = document.getElementById('crafty_postcode_result_display');
	
			// clear out any existing contents
			if (the_parent.hasChildNodes())	{
				while (the_parent.firstChild) {
					the_parent.removeChild(the_parent.firstChild);
				}
			}
		
			// insert new contents
			if (null == new_element) {
				new_element = document.createTextNode("\u00A0"); // &nbsp;
			}		
		
			the_parent.appendChild(new_element)
		}
	}
	catch(er) {};
}

// this function is for osCommerce - attach it to your country drop down list and the lookup button will be shown
// only if the Country is UK
function crafty_postcode_country_changed() {

	var cl = _cp_get_elem(7);
	if (cl) {
		var country_id = cl.options[cl.selectedIndex].value;
		if (222 == country_id) {   // show the button for UK
			_cp_change_elem_vis('crafty_postcode_button','inline');
		} else {	// hide the button for all other countries
			_cp_change_elem_vis('crafty_postcode_button','none');
		}
		// clear any results/busy img/errors
		_cp_update_res(null);
	}
}

function _cp_change_elem_vis(id, display_setting) {
	if (document.getElementById) {
		document.getElementById(id).style.display = display_setting;
	}
}

function _crafty_str_trim(s) {
	var l=0; 
	var r=s.length -1;
	while(l < s.length && s[l] == ' ') { l++; }
	while(r > l && s[r] == ' ') { r-=1;	}
	return s.substring(l, r+1);
}

function _cp_uc(text){
	if ("PC" == text || "UK" == text || "EU" == text) {return (text);}
	var alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 	var out_text = '';
	var do_uc = 1;
	var all_uc = 0;
	for (var i=0; i<text.length; i++){
		if (-1 != alpha.indexOf(text.charAt(i))) {
			if (do_uc || all_uc) {
				out_text = out_text + text.charAt(i);
				do_uc = 0;
			} else {
				out_text = out_text + text.charAt(i).toLowerCase();
			}
		} else {
			out_text = out_text + text.charAt(i);
			if (i+2 >= text.length && "'" == text.charAt(i)) { // only one more char left, don't capitalise
				do_uc = 0; 
			} else if ("(" == text.charAt(i)) {
				close_idx = text.indexOf(")",i+1);
				if (i+3 < close_idx) { // more than 2 chars
					all_uc = 0; do_uc = 1;
				} else { // no closing bracket or 2 or les chars in brackets, leave uppercase
					all_uc = 1; 
				}				
			} else if (")" == text.charAt(i)) {
				all_uc = 0; do_uc = 1;
			} else if ("-" == text.charAt(i)) {
				close_idx = text.indexOf("-",i+1);
				if ((-1 != close_idx && i+3 >= close_idx) || i+3 >= text.length) { // less than 2 chars
					all_uc = 0; do_uc = 0;
				} else { // 2 or more chars 
					all_uc = 0; do_uc = 1;
				}		
			} else if (i+2 < text.length && "0" <= text.charAt(i) && "9" >= text.charAt(i)) {
				do_uc = 0;
			} else {
				do_uc = 1;
			}
		}
	}
	return (out_text);
}

function _crafty_leading_caps(txt, dont_do_it) {
	if (0 != dont_do_it || 2 > txt.length) { return (txt) }
	var out_text = '';
	var words = txt.split(" ");
	for (var i=0; i<words.length; i++) {	// each word in turn
		var word = _crafty_str_trim(words[i]);
		if ('' != word)	{
			if ('' != out_text)	{
				out_text = out_text + ' ';
			}
			out_text = out_text + _cp_uc(word);
		}
	}
	return (out_text);
}

function _cp_process_xml(tn, cn, ln, rn, pn, on, pc) {
	_cp_res_arr = new Array();
	_cp_res_locality = new Array(); 
	_cp_res_locality['town'] = _crafty_leading_caps(tn, _cp_config.town_uppercase);
	_cp_res_locality['locality'] = '';
	_cp_res_locality['locality_dep'] = '';
	if (2 < ln.length) {
		loc_arr = ln.split("|");
		_cp_res_locality['locality'] = _crafty_leading_caps(loc_arr[0], _cp_config.addr_uppercase);
		_cp_res_locality['locality_dep'] = _crafty_leading_caps(loc_arr[1], _cp_config.addr_uppercase);
	}
	_cp_res_locality['county'] = '';
	if (2 < cn.length) {
		county_arr = cn.split('|');
		_cp_res_locality['county'] = _crafty_leading_caps(county_arr[(_cp_config.traditional_county != 0 ? 1 : 0)], _cp_config.county_uppercase);
	}
	_cp_res_arr_idx = 0;
	if ('' != rn) {
		_cp_process_ranges(rn);
	}
	if ('' != pn) {
		_cp_process_points(pn);
	}
	if ('' != on) {
		_cp_process_orgs(on);
	}
	if (_cp_res_arr_idx) {
		// sort  & display results
		_cp_disp_res_arr();
		if ('' != pc) {
			var pe = _cp_get_elem(6);
			pe.value = pc;
		}
		if (0 != _cp_config.res_autoselect) {_cp_res_selected(0);}
		document.getElementById("crafty_postcode_lookup_result_option").focus();
	} else {
		_cp_disp_err( '1205', 'no result to display' );
	}
}

function _cp_new_res_line() {
	var al = new Array();
	al['org'] = ''; al['housename'] = ''; al['pobox'] = '';
	al['street1'] = ''; al['street2'] = '';
	return (al);
}

function _cp_process_ranges(txt) {
	var chunk = txt.split(";");
	var count = 0;
	
	while (count < chunk.length) {
		var numrange = chunk[count+1].split("|");
		var streets = chunk[count].split("|");

		count = count + 2;
		for (var i=0; i<numrange.length; i=i+2)	{
			if ('' != numrange[i+1]) {
				var start = numrange[i] * 1;
				var end = numrange[i+1] * 1;
				for (var j=start; j<=end; j=j+2) {
					var al = _cp_new_res_line();
					al['street1'] = _crafty_leading_caps(streets[0], _cp_config.addr_uppercase);
					al['street2'] = _crafty_leading_caps(streets[1], _cp_config.addr_uppercase);
					if ('' != al['street2']) {
						al['street2'] = j.toString() + ' ' + al['street2'];
					} else if ('' != al['street1']) {
						al['street1'] = j.toString() + ' ' + al['street1'];
					} else {
						al['street1'] = j.toString();
					}
					_cp_res_arr[_cp_res_arr_idx] = al;
					_cp_res_arr_idx++;
				}				
			} else {
				var al = _cp_new_res_line();
				al['street1'] = _crafty_leading_caps(streets[0], _cp_config.addr_uppercase);
				al['street2'] = _crafty_leading_caps(streets[1], _cp_config.addr_uppercase);
				if ('' != al['street2']) {
					al['street2'] = numrange[i].toString() + ' ' + al['street2'];
				} else if ('' != al['street1']) {
					al['street1'] = numrange[i].toString() + ' ' + al['street1'];
				} else {
					al['street1'] = numrange[i].toString();
				}
				_cp_res_arr[_cp_res_arr_idx] = al;
				_cp_res_arr_idx++;
			}
		}
	}
}

function _cp_process_points(txt) {
	var chunk = txt.split(";");
	for (var count=0; count< chunk.length; count++) {
		var al = _cp_new_res_line();
		var parts = chunk[count].split('|');
		if (4 == parts.length) {
			al['street1'] = _crafty_leading_caps(parts[0], _cp_config.addr_uppercase);
			al['street2'] = _crafty_leading_caps(parts[1], _cp_config.addr_uppercase);
			al['housename'] =  _crafty_leading_caps(parts[2] + ((parts[2]!='')&&(parts[3]!='')?_cp_config.delimiter:'') + parts[3], _cp_config.addr_uppercase);
			_cp_res_arr[_cp_res_arr_idx] = al;
			_cp_res_arr_idx++;
		}
	}
}

function _cp_process_orgs(txt) {
	var chunk = txt.split(";");
	for (var count=0; count< chunk.length; count++) {
		var al = _cp_new_res_line();
		var parts = chunk[count].split('|');
		if (7 == parts.length) {
			al['street1'] = _crafty_leading_caps(parts[0], _cp_config.addr_uppercase);
			al['street2'] = _crafty_leading_caps(parts[1], _cp_config.addr_uppercase);
			al['housename'] = _crafty_leading_caps(parts[2] + ((parts[2]!='')&&(parts[3]!='')?_cp_config.delimiter:'') + parts[3], _cp_config.addr_uppercase);
			al['org'] = _crafty_leading_caps((parts[4] + ((parts[4]!='')&&(parts[5]!='')?_cp_config.delimiter:'') + parts[5]), _cp_config.org_uppercase);
			al['pobox'] = _crafty_leading_caps(parts[6], _cp_config.addr_uppercase);
			_cp_res_arr[_cp_res_arr_idx] = al;
			_cp_res_arr_idx++;
		}
	}
}

function _cp_compare(a,b) {
	// see if there is a number at the start and compare that first
	var numA; var numB;
	// check for a flat
	if ('FLAT' == a['str'].substr(0,4).toUpperCase() && 'FLAT' == b['str'].substr(0,4).toUpperCase()) {
		numA = parseInt(a['str'].substr(5,a['str'].indexOf(_cp_config.delimiter,5)));
		numB = parseInt(b['str'].substr(5,b['str'].indexOf(_cp_config.delimiter,5)));
	} else {
		numA = parseInt(a['str']);
		numB = parseInt(b['str']);
	}
	if (numA > numB) { return (1);}
	if (numA < numB) { return (-1);}
	// if we get here that means either no number at start, or both numbers the same
	if (a['str'] > b['str']) { return (1); }
	return (-1);
}

function _cp_disp_res_arr() {
	var dc = _cp_config.delimiter;
	_cp_disp_arr = new Array();
	// create an unsorted display array
	for (var i=0;i<_cp_res_arr_idx;i++) {
		var arrayline = _cp_res_arr[i];
		var dispstr = arrayline['org'] + (arrayline['org'] !='' ? dc : '') + 
					  arrayline['housename'] + (arrayline['housename'] != '' ? dc : '') + 
					  arrayline['pobox'] + (arrayline['pobox'] != '' ? dc : '') + 
					  arrayline['street2'] + (arrayline['street2'] != '' ? dc : '') +
					  arrayline['street1'] + (arrayline['street1'] != '' ? dc : '') +
					  _cp_res_locality['locality_dep'] + (_cp_res_locality['locality_dep'] != '' ? dc : '') +
					  _cp_res_locality['locality'] + (_cp_res_locality['locality'] != '' ? dc : '') +
					  _cp_res_locality['town'];

		var displine = new Array();
		displine['index'] = i;
		displine['str'] = dispstr;
		_cp_disp_arr[i] = displine;
	}
	// sort it
	_cp_disp_arr = _cp_disp_arr.sort(_cp_compare);
	// display it
	if ('' != _cp_config.first_res_line) {
		_cp_display_res_line(_cp_config.first_res_line, -1);
	}
	for (var i=0;i<_cp_res_arr_idx;i++) {
		_cp_display_res_line(_cp_disp_arr[i]['str'], i);
	}
}

function _cp_get_elem(idx) {
	var en = _cp_config.elements.split(",");
	var el = null;
	if ('' != _cp_config.form) {
		el = document.forms[_cp_config.form].elements[en[idx]];
	} else if (document.getElementById) {
		el = document.getElementById(en[idx]);
	}
	return (el);
}


function _cp_handle_http_result()
{
	if(null == _cp_xmlhttp || _cp_xmlhttp.readyState != 4) {
		return;
	}
	if(_cp_xmlhttp.status != 200) {
		_cp_disp_err('1200', 'xmlhttp status='+_cp_xmlhttp.status);
		return;
	}
//alert(_cp_xmlhttp.getAllResponseHeaders());
//alert(_cp_xmlhttp.responseText);
	try {
		_cp_update_res(null);
		var doc = _cp_xmlhttp.responseXML.documentElement;
		var ef = doc.getElementsByTagName("ef");
		if (0 != ef.length) {
			var errCode = ef[0].childNodes[0].nodeValue;
			if ('7001' == errCode) {
				var em = doc.getElementsByTagName("em");
				if (0 != em.length) {
					_cp_disp_err_msg('Demo limit reached, please use one of: '+em[0].childNodes[0].nodeValue);
				} else {
					_cp_disp_err_msg("Sorry. Demo usage has a daily limit.");
				}
			} else {
				_cp_disp_err(errCode, '');
			}
		} else {
			var tnt = doc.getElementsByTagName("town");
			var cnt = doc.getElementsByTagName("county");
			var lnt = doc.getElementsByTagName("locality");
			var rnt = doc.getElementsByTagName("ranges");
			var pnt = doc.getElementsByTagName("points");
			var ont = doc.getElementsByTagName("orgs");
			var pct = doc.getElementsByTagName("postcode");
			if ( tnt && cnt && lnt && rnt && pnt && ont && pct) {
				var tn = tnt[0].childNodes[0].nodeValue;
				var cn = cnt[0].childNodes[0].nodeValue;
				var ln = lnt[0].childNodes[0].nodeValue;
				var rn = rnt[0].childNodes[0] ? rnt[0].childNodes[0].nodeValue : '';
				var pn = pnt[0].childNodes[0] ? pnt[0].childNodes[0].nodeValue : '';
				var on = ont[0].childNodes[0] ? ont[0].childNodes[0].nodeValue : '';
				var pc = pct[0].childNodes[0].nodeValue;
				_cp_process_xml(tn, cn, ln, rn, pn, on, pc);
			} else {
				_cp_disp_err( '1204', 'An xml tag is missing.' );
			}
		}
	}
	catch(er) {
		_cp_disp_err( '1201', er );
	}
}

function crafty_postcode_lookup() {
	_cp_xmlhttp=null;

	var pe = _cp_get_elem(6);
	var pc = null;
	
	if (pe) { 
		_cp_show_busy(); // show busy img - this will clear any errors/previous results
		_cp_lookup_timeout = setTimeout ( "_cp_lookup_timeout_err()", _cp_config.lookup_timeout );
		pc = _cp_validate_pc(pe.value);
	}
	
	if (null != pc) {
		if ('' != _cp_config.access_token) {
			var inc = pc.substring(pc.length-3,pc.length);
			var outc = pc.substring(0, pc.length-3);
			_cp_clean_pc = outc+' '+inc;
			_cp_direct_xml_fetch(pc, _cp_config.access_token);
		} else {
			var url = _cp_config.lookup_url+'?postcode='+pc;
			if (window.XMLHttpRequest) {// code for IE7, Firefox, Mozilla, etc.
				_cp_xmlhttp=new XMLHttpRequest();
			} else if (window.ActiveXObject) {// code for IE5, IE6
				_cp_xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
			}

			if (_cp_xmlhttp!=null)  {
				try {	
					_cp_xmlhttp.onreadystatechange=_cp_handle_http_result;
					_cp_xmlhttp.open("GET",url,true);
					_cp_xmlhttp.setRequestHeader("Content-Type", "text/xml");
					_cp_xmlhttp.send(null);
				}
				catch(er) {
					_cp_disp_err('1202', er);
				}
			} else {
				_cp_disp_err('1203', '_cp_xmlhttp==null');
			}
		}
	} else {
		_cp_disp_err('0002', 'invalid postcode format');
	}
}

function _cp_validate_pc(dirty_pc) {
	// first strip out anything not alphanumenric
	var pc = '';
	do {
		pc = dirty_pc;
		dirty_pc = dirty_pc.replace(/[^A-Za-z0-9]/, "");
	} while (pc != dirty_pc);
	pc = dirty_pc.toUpperCase();
	// check if we have the right length with what is left
	if (7 >= pc.length && 5 <= pc.length) {
		// get the in code 
		var inc = pc.substring(pc.length-3,pc.length);
		// get the out code
		var outc = pc.substring(0, pc.length-3);
		// now validate both in and out codes
		if (true == /[CIKMOV]/.test(inc)) {
			return null;
		}
		// inCode must be NAA
		if ( '0' <= inc.charAt(0) && '9' >= inc.charAt(0) &&
		     'A' <= inc.charAt(1) && 'Z' >= inc.charAt(1) &&
			 'A' <= inc.charAt(2) && 'Z' >= inc.charAt(2) ) {
			// outcode must be one of AN, ANN, AAN, ANA, AANN, AANA
			switch (outc.length) { 
				case 2: // AN
					if ('A' <= outc.charAt(0) && 'Z' >= outc.charAt(0) &&
						'0' <= outc.charAt(1) && '9' >= outc.charAt(1) ) { return (pc); }
					break;
				case 3: // ANN, AAN, ANA
					if ('A' <= outc.charAt(0) && 'Z' >= outc.charAt(0)) {
						if ('0' <= outc.charAt(1) && '9' >= outc.charAt(1) &&
							'0' <= outc.charAt(2) && '9' >= outc.charAt(2) ) { return (pc); }
						else if ('A' <= outc.charAt(1) && 'Z' >= outc.charAt(1) &&
							     '0' <= outc.charAt(2) && '9' >= outc.charAt(2) ) { return (pc); }
						else if ('0' <= outc.charAt(1) && '9' >= outc.charAt(1) &&
								 'A' <= outc.charAt(2) && 'Z' >= outc.charAt(2) ) { return (pc); }
					}
					break;
				case 4: // AANN, AANA
					if ('A' <= outc.charAt(0) && 'Z' >= outc.charAt(0) &&
					    'A' <= outc.charAt(1) && 'Z' >= outc.charAt(1) &&
					    '0' <= outc.charAt(2) && '9' >= outc.charAt(2)) {
						if ('0' <= outc.charAt(3) && '9' >= outc.charAt(3) ) { return (pc); }
						else if ('A' <= outc.charAt(3) && 'Z' >= outc.charAt(3) ) { return (pc); }
					}
					break;
				default:
					break;
			}
		}
	}
	return null;
}


function _cp_direct_xml_fetch(pc, key) {
	try	{
		var the_parent = document.getElementById('crafty_postcode_result_display');

		var url = '';
		if ("https:" == document.location.protocol) {
			url = 'https://';
		} else {
			url = 'http://';
		}
		url += _cp_config.lookup_url+'?postcode='+pc+'&key='+key;

		cs = document.createElement("script");
		cs.src = url;
		cs.type = "text/javascript";
		the_parent.appendChild(cs);
	}
	catch(er){
		_cp_disp_err('1206', er);
	};
}

function _cp_handle_js_error(ef,em) {
	if ('7001' == ef) {
		if (0 != em.length) {
			_cp_disp_err_msg('Demo limit reached, please use one of: '+em);
		} else {
			_cp_disp_err_msg("Sorry. Demo usage has a daily limit.");
		}
	} else if ('8001' == ef) {
		_cp_disp_err(ef, 'Invalid Token Format. '+em);
	} else {
		_cp_disp_err(ef, 'server error code');
	}
}

function _cp_handle_js_response(tn, cn, ln, rn, pn, on) {
	_cp_process_xml(tn, cn, ln, rn, pn, on, _cp_clean_pc);
}

function _cp_lookup_timeout_err() {
	_cp_disp_err('9001', 'Internal Timeout after '+_cp_config.lookup_timeout+'ms')
}