var d = {

		advancedSearchStore : new Array(),
			
		advancedSearchSerializedString : new String(),
				
		inputChangeCallback : function() {
			alert( "somethings changed" )
			formDataHasChanged = 1
		},
		
		
		dispatchAjaxRequest : function( query, handler ) {
			
			if (window.XMLHttpRequest) { // Mozilla, Safari, ...
				var io = new XMLHttpRequest();
			} else if (window.ActiveXObject) { // IE
				var io = new ActiveXObject("Microsoft.XMLHTTP");
			}
			io.onreadystatechange = function() { 
				if (io.readyState == 4) {
				
					// split up our return
					var responseParts = io.responseText.split('|')
					// check its formatted how we like
					if ( responseParts.length < 2 ) {
						console.error('invalid response to d.dispatchAjaxRequest recieved')
						return false
					}
					// run our callback..
					// we add d. as an anti hack thing so only things in our namespace can run
					var callback = 'd.' + responseParts[0]
					callback.replace(';', '')
					var response = responseParts[1]
					return eval( callback )
				};
		
			}
						
			var req = query + "&callback=" + encodeURI( handler ) + "&rnd=" + Math.random();
       		io.open('GET', req, true);
       		io.send(null);	
		},
	
		
		
		subscriberDelete : function( id, newUrl ) {
			
			var areSure = confirm( "Are you sure you wish to delete this person? This cannot be undone." )
			if ( ! areSure ) {
				return false;
			}
			
			// do the delete with ajax
			d.dispatchAjaxRequest( "_innards/d.ajax.subs.php?action=delete&id=" + id, 'subscriberDelete_handler( response, "' + newUrl + '")' )
		},
		
		subscriberDelete_handler : function( response, newUrl ) {
			// if we have anything comign back, we werent sucessfull
			if ( response != "" ) {
				alert( response );				
				return false;
			}
			// were ok so redirect if need be
			if ( newUrl != "" )  {
				document.location = newUrl
			}		
		},
		
		addKeywordSubmit : function() {
			
			var newName = document.getElementById('keywordAddNameField').value
			if ( newName == '' ) {
				return false
			}
			
			newName = encodeURI( newName )
			d.dispatchAjaxRequest( "_innards/d.ajax.keywords.php?action=add&name=" + newName, 'addKeyword_handler( response )' )
			
		},
		
		addKeyword_handler : function( response ) {
			
			// will add proper error things in a mo
			returnData = response.split(',')
			if ( returnData.length == 2 ) {
				var menu = document.getElementById('keywordPicker');
				var newKeyword = new Option( returnData[1], returnData[0] )
				menu.options[ menu.options.length ] = newKeyword
			}
		
		},
		
		searchBoxStringStringChangeCallback : function( resultTarget ) {
			
			if ( resultTarget == '' ) {
				return false
			}
		
			var searchText = document.getElementById( 'searchBoxSearchString' ).value
			var searchModeMenu = document.getElementById( 'searchBoxSearchType' )
			var searchMode = searchModeMenu.options[ searchModeMenu.selectedIndex ].value
			searchText = encodeURI( searchText )
			
			d.dispatchAjaxRequest( "_innards/d.ajax.search.php?action=getListing&mode=" + searchMode + "&query=" + searchText, 'searchBoxSearch_handler( response, "' + resultTarget + '" )' )
					
		},
		
		searchBoxSearch_handler : function( response, drawDestination ) {
		
			if ( drawDestination == '' ) { return false }
		
			var drawDiv = document.getElementById( drawDestination )		

			drawDiv.innerHTML = response;

		},
		
		searchResultLinkClick : function( url ) {
		
			if ( url == '' ) {
				return false;
			}
			
			var searchText = document.getElementById( 'searchBoxSearchString' ).value
			var searchModeMenu = document.getElementById( 'searchBoxSearchType' )
			var searchMode = searchModeMenu.options[ searchModeMenu.selectedIndex ].value
			searchText = encodeURI( searchText )
			
			url = url + '&search=' + searchText + '&searchMode=' + searchMode
			document.location = url
		},
		
		advancedSearchInitalize : function() {
			d.advancedSearchReadForm()
		},
		
		
		advancedSearchSaveResults : function() {
		
					
			// get a name
			var saveName = prompt('please choose a name to save these results under')
			if ( ! saveName ) { return }

			saveName = encodeURI( saveName )

			// serialize
			d.serializeAdvancedSearchObject()

			// save in the db
			d.dispatchAjaxRequest( "_innards/d.ajax.search.php?action=saveResults&object=" +  encodeURI(d.advancedSearchSerializedString) + "&saveName=" + saveName, "saveResults_handler( response )" )			
			
		},
		
		saveResults_handler : function( response ) {
			
			if ( response != '' ) {
				alert( response )
			} else {
				var newUrl = document.location + "?message=Search saved sucessfully"
				document.location = newUrl.replace("#", "")
			}	
			
		},
		
		advancedSearchClearResults : function() {
		
		},
		
		advancedSearchAddNewTerms : function( dontSave ) {
			if ( ! dontSave ) { d.advancedSearchSaveTerms() }
			// set the new index
			document.advancedSearchForm.__currentTermsIndex.value = d.advancedSearchStore.length
			// clear the ui
			d.advancedSearchClearForm()
			// update the terms listing
			d.advancedSearchFormTermSetsChangedCallback('searchCriteriaDiv')
			document.advancedSearchForm.save.style.display='inline'
			document.getElementById('editingStatusDiv').innerHTML = ''
		},
		
		advancedSearchSaveTerms : function( dontAsk ) {
		
			if ( !  d.advancedSearchStore[ document.advancedSearchForm.__currentTermsIndex.value ] ) {
				//no changes made...
				return
			}
			
			if (  ( ! dontAsk ) && ( ! d.advancedSearchStore[ document.advancedSearchForm.__currentTermsIndex.value ]['__termsName'] ) && ( ! confirm('current search terms have not been saved yet, do you want to save them?') )  ) {
				d.advancedSearchStore.pop()
				return;
			} 
		
			//check these have been saved if we dont have a name, ask for one
			if ( ! d.advancedSearchStore[ document.advancedSearchForm.__currentTermsIndex.value ]['__termsName']  ) {
					// get a name
					var termsName = prompt('please choose a name for this set of search terms')
					if ( ! termsName ) { return }		
					var termSet = parseInt(document.advancedSearchForm.__currentTermsIndex.value)
					d.advancedSearchStore[ termSet ].__termsName = termsName
					// work out a summary for us
					d.advancedSearchStore[ termSet ].__termsSummary = d.createAdvancedSearchTermsSummary( termSet )
					d.advancedSearchSyncAllTerms()
					d.advancedSearchFormTermSetsChangedCallback('searchCriteriaDiv')
					document.advancedSearchForm.save.style.display='none'
					d.advancedSearchAddNewTerms(1)
			} else {
				d.advancedSearchSyncAllTerms()
				var termSet = parseInt(document.advancedSearchForm.__currentTermsIndex.value)
				d.advancedSearchStore[ termSet ].__termsSummary = d.createAdvancedSearchTermsSummary( termSet )
				document.advancedSearchForm.save.style.display='none'
				d.advancedSearchAddNewTerms(1)
			}

		},
		
		advancedSearchSyncAllTerms : function() {
			// check we have a store for this index
			var termSet = parseInt(document.advancedSearchForm.__currentTermsIndex.value)
			if ( ! d.advancedSearchStore[ termSet ] ) {  d.advancedSearchStore[ termSet ] = new Object() }
			// sync
			d.advancedSearchReadForm()
			d.advancedSearchBoxKeywordPickerChangeCallback( document.getElementById('keywordPicker') )
			d.advancedSearchStore[ termSet ].__termsSummary = d.createAdvancedSearchTermsSummary( termSet )

		},
		
		advancedSearchClearForm : function() {
			d.clearFormTextFields( document.advancedSearchForm )
			d.clearSelectedItems( document.getElementById('keywordPicker') )
		},
		
		advancedSearchBoxStringStringChangeCallback : function( changedObject ) {
			d.advancedSearchReadForm(changedObject);
		},
		
		advancedSearchBoxKeywordPickerChangeCallback : function( object ) {
			var termSet = parseInt(document.advancedSearchForm.__currentTermsIndex.value)
			if ( ! d.advancedSearchStore[ termSet ] ) {  d.advancedSearchStore[ termSet ] = new Object() }		
			var selected = d.getSelectedIndexes( object )
			if ( selected.length > 1 ) {
				// this just stops people selecting more than one thing at once, whilst keeping the list ui
				object.selectedIndex = selected[0]
				selected = new Array( selected[0] )
			}
			d.advancedSearchStore[ termSet ][ '_keywords' ] = 	d.getSelectedIndexes( object )
		},
			
		advancedSearchReadForm : function( field ) {
					
			var form = document.advancedSearchForm
			
			var termSet = parseInt(document.advancedSearchForm.__currentTermsIndex.value)
			
			if ( ! d.advancedSearchStore[ termSet ] ) {  d.advancedSearchStore[ termSet ] = new Object() }
						
			if ( field ) {
				// were just reading a specific element	
				d.advancedSearchStore[ termSet ][ field.name ] = field.value	
				d.advancedSearchStore[ termSet ].__termsSummary = d.createAdvancedSearchTermsSummary( termSet )
				return
			}
			
			// were reading the whole form
			for ( i=0; i<form.elements.length; i++ ) {
				if  ( form.elements[i].type == "text" ) {
					d.advancedSearchStore[ termSet ][ form.elements[i].name ] =  form.elements[i].value
				}
			}			
			d.advancedSearchStore[ termSet ].__termsSummary = d.createAdvancedSearchTermsSummary( termSet )
		},
		
		// redraws the listing of search criteria
		advancedSearchFormTermSetsChangedCallback : function( divId ) {
			
			if ( d.advancedSearchStore.length == 0 ) {
				document.getElementById( divId ).innerHTML = ''
				// document.getElementById( 'addCriteriaButton' ).style.display = 'none';
				return
			}
		
			
			var htmlString = '<h3>Your search is also using the following criteria:</h3><ul class="savedCriteriaList">'
			
			for (var i=0; i<d.advancedSearchStore.length; i++ ) {
				var summary = d.advancedSearchStore[i].__termsSummary;
				if ( summary.length > 75 ) {
					summary = summary.substring(0, 74) + "..."
				}
				htmlString = htmlString + '<li><a href="#" class="button" id="deleteButton" onClick="d.advancedSeatchDeleteSearchTerms(' + i + '); return false">remove</a> <a href="#" class="button" id="editButton" onClick="d.advancedSeatchSwichToSearchTerms(' + i + '); return false">edit</a>' + d.advancedSearchStore[i].__termsName + '<span class="termsSummary">( ' + summary + ' )</span></li>'
			} 
			
			htmlString = htmlString + '</ul>'
			
			document.getElementById( divId ).innerHTML = htmlString
			// document.getElementById( 'addCriteriaButton' ).style.display = 'inline';

		},
		
		advancedSeatchSwichToSearchTerms : function( termID ) {
	
			d.advancedSearchSaveTerms()
				
			// resetUI
			d.setSelectedIndexes( document.getElementById('keywordPicker'), d.advancedSearchStore[ termID ]._keywords )
			for ( var thisProperty in d.advancedSearchStore[ termID ] ) {
				if ( document.advancedSearchForm[thisProperty] ) {
					document.advancedSearchForm[thisProperty].value = d.advancedSearchStore[ termID ][ thisProperty ]
				}
			}
			document.advancedSearchForm.__currentTermsIndex.value = termID
			
			document.getElementById('editingStatusDiv').innerHTML = '(editing "' + d.advancedSearchStore[ document.advancedSearchForm.__currentTermsIndex.value ]['__termsName'] + '")'
			d.advancedSearchFormTermSetsChangedCallback('searchCriteriaDiv')
		},
		
		advancedSeatchDeleteSearchTerms : function( termID ) {
			
			var termSet = parseInt(document.advancedSearchForm.__currentTermsIndex.value)
			d.advancedSearchStore.splice( termID, 1 )
			if ( termID == termSet ) {
				// if we delte the current one, then we need to switch or go to a blank one
				if (  d.advancedSearchStore.length ) {
					d.advancedSeatchSwichToSearchTerms( 0 )
					d.advancedSearchFormTermSetsChangedCallback('searchCriteriaDiv')
				} else {
					// add new not saving
					d.advancedSearchAddNewTerms( 1 )
					d.advancedSearchFormTermSetsChangedCallback('searchCriteriaDiv')
				}
			} else {
				d.advancedSearchFormTermSetsChangedCallback('searchCriteriaDiv')
			}
			
			d.advancedSearchSubmitQuery()
			
		},
		
		
		deleteSavedSearch : function( id ) {
			
			if ( ! id ) {
				return
			}
			
			if ( ! confirm("Are you sure you want to delete this delivery group? This cannot be undone") ) {
				return
			}
		
			d.dispatchAjaxRequest( "_innards/d.ajax.search.php?action=deleteAdvancesSearch&id=" + id, 'deleteSavedSearch_handler( response )' )
		},
		
		deleteSavedSearch_handler : function( response ) {
		
			document.getElementById("savedSearchList").innerHTML = response
		
		},
	
		//creates a string with a summary of a set of terms
		createAdvancedSearchTermsSummary : function( termID ) {
			
			var summary = ""
		
			for ( var thisParam in d.advancedSearchStore[termID] ) {
				if ( thisParam != "" ) {
					
					if ( thisParam.match("__") ) { continue }
					
					var paramToPrint
					if ( thisParam == "_emailAddress" ) {
						paramToPrint = "email"
					} else {
						paramToPrint = thisParam
					}
								
					paramType = typeof d.advancedSearchStore[termID][thisParam]
					
					if (  paramType == "string" ) {
						if ( d.advancedSearchStore[termID][thisParam] != "" ) {
							summary +=  paramToPrint + ": "  + d.advancedSearchStore[termID][thisParam] + ", "
						}
					}										
				}
			}
			
			// keywords
			if ( d.advancedSearchStore[termID]["_keywords"] && d.advancedSearchStore[termID]["_keywords"].length > 0 ) {
			
				summary += "keywords: "
				
				for ( var i=0; i<d.advancedSearchStore[termID]["_keywords"].length; i++ ) {
					summary += document.getElementById('keywordPicker').options[ d.advancedSearchStore[termID]._keywords[i]-1 ].text + ", "
				}
			
			}
			
			summary = summary.replace(/, $/, "" )	
			
			return summary
		},
		
		
		serializeAdvancedSearchObject : function( termID ) {
								
				var flattenedSearchObject = ""
				var paramType
				
				for ( var i =0; i < d.advancedSearchStore.length; i++ ) {
										
					if ( termID &&  (i != termID) ) {
						continue
					}
									 	
					for ( var thisParam in d.advancedSearchStore[i] ) {
						if ( thisParam != "" ) {
						
							paramType = typeof d.advancedSearchStore[i][thisParam]
							
							if (  paramType == "string" ) {
								if ( d.advancedSearchStore[i][thisParam] != "" ) {
									flattenedSearchObject +=  paramType  + "||" + thisParam + "||" + d.advancedSearchStore[i][thisParam] + "|p|"
								}
							} else if ( paramType == "object" ) {
								flattenedSearchObject +=  paramType  + "||" + thisParam + "||" + d.advancedSearchStore[i][thisParam].join(",") + "|p|"
							}											
						}
					}
					
					flattenedSearchObject += "|t|";
					
				}
				
				flattenedSearchObject = flattenedSearchObject.replace(/#t#$/, "" )
				d.advancedSearchSerializedString = flattenedSearchObject
		},
		
		
		deserializeAdvancedSearchObject : function() {
			
			var deSerialized = new Array()
			
			if ( d.advancedSearchSerializedString == "" ) { return }
			
			var terms = d.advancedSearchSerializedString.split("|t|")

			for ( var i =0; i < terms.length; i++ ) {
				
				if ( ! deSerialized[i] ) { deSerialized[i] = new Object() }
				
				var paramsRaw = terms[i].split("|p|")
				
				for ( var paramIndex in  paramsRaw  ) {
									
					var paramData = paramsRaw[ paramIndex ].split("||")
					
					if ( paramData.length == 3 ) {		
						if ( paramData[0] == "string" ) {
							if ( paramData[2] != "" ) { deSerialized[i][paramData[1]] = paramData[2] }
						} else if ( paramData[0] == "object" ) {
							deSerialized[i][paramData[1]] = paramData[2].split(",")
						}
					}
				
				}
			
			}	
		
			if ( deSerialized.length > 0 ) {
				d.advancedSearchStore = deSerialized
			}
		
		},
		
		
		advancedSearchSubmitQuery : function( termID ) {
		
			document.getElementById( 'searchResultsDiv' ).innerHTML = '<i>Searching - wont be a moment...</i>';
		
			d.serializeAdvancedSearchObject( termID )
			if ( d.advancedSearchSerializedString == "" ) {
				return
			}
				
			d.dispatchAjaxRequest( "_innards/d.ajax.search.php?action=getAdvancedSearch&object=" +  encodeURI(d.advancedSearchSerializedString), "advancedSearchSubmitQuery_handler( response, 'searchResultsDiv')" )		
		},
		
		
		advancedSearchSubmitQuery_handler : function( response, drawDestination ) {
		
			if ( drawDestination == '' ) { return false }
		
			var drawDiv = document.getElementById( drawDestination )
			
			if ( response != ''  ) {
				drawDiv.innerHTML = response;
				document.getElementById('saveAsDeliveryGroupButton').enable = true
			} else {
				document.getElementById('saveAsDeliveryGroupButton').enable = false
				drawDiv.innerHTML = 'No members match.';
			}
		},
		
		// gets the selected vlues from a select
		getSelectedIndexes : function( object ) {
				var indexes = new Array()
				for ( var i=0; i<object.options.length; i++ ) {
					if ( object.options[i].selected ) { indexes.push( object.options[i].value ) }
				}
				return indexes
		},
		
		// sets the selected vlues from a select
		setSelectedIndexes : function( object, values ) {
				object.selectedIndex = -1
				if ( ! values ) { return }
				var allValues = '#' + values.join('#') + '#'
				for ( var i=0; i<object.options.length; i++ ) {
					if ( allValues.match( '#' + object.options[ i ].value + '#' ) ) { 
						object.options[i].selected = true
					}
				}
		},
		
		clearFormTextFields : function( form ) {
			// were reading the whole form
			for ( var i=0; i<form.elements.length; i++ ) {
				if  ( form.elements[i].type == "text" ) {
					form.elements[i].value = '';
				}
			}	
		},
		
		clearSelectedItems : function( select ) {
			select.selectedIndex = -1
		},
		
		previewDelivery : function() {
		
			document.deliveryForm.target="_blank"
			document.deliveryForm.action="delivery.preview.php"
			document.deliveryForm.submit()
		
		},
		
		sendDelivery  : function() {
		
			// first check we have all we need
			var subject = document.getElementById('subject').value
			if ( subject == '' ) {
				alert("Missing subject line")
				return
			}	
			
					
			var recipients = d.getSelectedIndexes( document.getElementById('savedSearchPicker') )
			if ( recipients.length == 0 ) {
				alert("Please choose some recipients" )
				return
			}
			
			var plain = document.getElementById('plainTextAlternative').value
			if ( document.getElementById('d_editMode').value == 'template' && plain == '' ) {
				alert("Missing plain text alternative content")
				return
			}
			
			// pleasing, we have all we need.
			document.getElementById('messageMain').innerHTML = "Submitting delivery, this may take a moment..."
			document.getElementById('messageAside').innerHTML = "Don't close this window, ortherwise the submission will be cancelled."

			// we needd to set the special mode if weve come out of an edit
			if ( document.deliveryForm.d_pageMode.value ==  'edit' ) {
				document.deliveryForm.d_pageMode.value = 'editandsend'
			}
			
			document.deliveryForm.d_testMode.value = 0
			document.deliveryForm.target="_self"
			
			document.deliveryForm.action = "delivery.submit.php"
			if ( d.confirmSpool() ) {
				d.showStatusMessage()
				document.deliveryForm.submit()
			}
		},
		
		sendTest : function( existingEmails ) {
			
			// first check we have all we need
			var subject = document.getElementById('subject').value
			if ( subject == '' ) {
				alert("Missing subject line")
				return
			}	
			
			
			var plain = document.getElementById('plainTextAlternative').value
			if ( document.getElementById('d_editMode').value == 'template' && plain == '' ) {
				alert("Missing plain text alternative content")
				return
			}
			
			// pleasing, we have all we need.
			
			var extraEmails = prompt("Your test delivery will be sent to:\n" + existingEmails + "\nenter any other addresses here:", " ")
			if ( ! extraEmails ) { return }	
			
			// insert the extra emails and test
			document.getElementById('d_extraTestEmails').value = extraEmails
			document.deliveryForm.d_testMode.value = 1	
			document.deliveryForm.target="_self"
			document.deliveryForm.action="delivery.submit.php"
			document.deliveryForm.submit()
		
		},
	
		saveDelivery  : function() {
					
			if ( document.deliveryForm.d_templatePicker.options[ document.deliveryForm.d_templatePicker.selectedIndex ].value == '' ) {
				return false;
			}
			
			document.getElementById('messageMain').innerHTML = "Saving, this may take a moment..."
			document.getElementById('messageAside').innerHTML = "Don't close this window, ortherwise the message wont be saved."
			
			d.showStatusMessage()
			
			// pleasing, we have all we need.
			document.deliveryForm.d_testMode.value = 0	
			document.deliveryForm.d_pageMode.value = 'draft'
			document.deliveryForm.action = "delivery.submit.php"
			document.deliveryForm.target="_self"
			document.deliveryForm.submit()
		
		},
		
		cancelDelivery : function( id ) {
		
			var sure = confirm("Are you sure you wish to delete this delivery? It cant be undone.");
			
			if ( ! sure ) {
				return false;
			}
		
			var id = parseInt(id);
			
			d.dispatchAjaxRequest( "_innards/d.ajax.delivery.php?action=cancelDelivery&id=" + id, "cancelDelivery_handler( response )" )		
		
		},
		
		cancelDelivery_handler : function( response ) {
			
			if ( response != "" ) {
				alert( response )
			} else {
				location.reload(true)
			}
			
		},
		
		deliveryTypeChangeCallback : function( radio ) {
				
				if ( radio.checked ) {
					if ( radio.value == 1) {
						// upload
						document.getElementById( 'uploadForm' ).style.display = 'block'
						document.getElementById( 'templateForm' ).style.display = 'none'
						document.getElementById( 'saveAsDraft' ).style.display = 'none'
						document.getElementById('d_editMode').value = 'upload'
					} else {
						// tempalte
						document.getElementById( 'uploadForm' ).style.display = 'none'
						document.getElementById( 'templateForm' ).style.display = 'block'
						if ( document.deliveryForm.d_templatePicker.options[ document.deliveryForm.d_templatePicker.selectedIndex ].value != '' ) {
							document.getElementById( 'saveAsDraft' ).style.display = 'inline'
						}
						document.getElementById('d_editMode').value = 'template'
					}
				}
				
				
		},
		
		templatePickerChangeCallback : function( menu ) {
			
			var templateFile = menu.options[ menu.selectedIndex ].value
			if ( templateFile == '' ) {
				document.getElementById( 'saveAsDraft' ).style.display = 'none'
				var editorDiv = document.getElementById( 'templateEditorDiv' );
				editorDiv.innerHTML = ''
				return
			} 
					
			var thisID = document.deliveryForm.d_id.value;
						
			d.dispatchAjaxRequest( "_innards/d.ajax.template.php?action=getEditor&id=" + thisID + "&template=" +  encodeURI( templateFile ), "templateChange_handler( response );" )		
		
		},
		
		templateChange_handler : function( response ) {
		
				var editorDiv = document.getElementById( 'templateEditorDiv' );
				var responseBits = response.split("+++")
				editorDiv.innerHTML = responseBits[0]
				if ( responseBits[1] ) { eval( responseBits[1] ) }
				document.getElementById( 'saveAsDraft' ).style.display = 'inline'
		},
		
		validateDate : function( field ) {
			
			var date = field.value
			
			// now is ok
			if ( date.match("today") ) {
				field.value = "today"
				return true
			}
			
			var currentDate	= new Date()
			var thisDay		= currentDate.getDate()
			var thisMonth	= currentDate.getMonth() + 1
			var thisYear	= currentDate.getFullYear()
			
			var day = month = year = null;
			
			// hunt months
			var parts = date.split('/')
			
			if ( parts.length == 3 ) {
			
				// d/m/y
				day 	= parseInt(parts[0])
				month	= parseInt(parts[1])
				year	= parseInt(parts[2])
				
				// whey a y3k bug!
				if ( year < 100 ) { year = parseInt(year) + 2000 }
				
			} else if ( parts.length == 2 ) {
			
				// d/m
				day 	= parseInt(parts[0])
				month	= parseInt(parts[1])
				year	= thisYear
			
			} else {
			
				// human matching
				if ( date.match("jan") ) {
					month = 1
				} else if ( date.match("feb") ) {
					month = 2
				} else if ( date.match("mar") ) {
					month = 3
				} else if ( date.match("apr") ) {
					month = 4
				} else if ( date.match("may") ) {
					month = 5
				} else if ( date.match("jun") ) {
					month = 6
				} else if ( date.match("jul") ) {
					month = 7
				} else if ( date.match("aug") ) {
					month = 8
				} else if ( date.match("sep") ) {
					month = 9
				} else if ( date.match("oct") ) {
					month = 10
				} else if ( date.match("nov") ) {
					month = 11
				} else if ( date.match("dec") ) {
					month = 12
				} else {
					month = 0
				}
				
				// hunt for a 20xx year, or get the current one
				var foundYear = date.match( /(20[0-9]{2})/ )
				if ( foundYear == null ) {
					year = thisYear
				} else {
					year = foundYear[0]
				}
				
				// try and find a two didgit number not surrounded by other numbers
				var foundDay = date.match( /[^0-2]([1-9]{1}[0-9]?)[^0-9]/ )
				// ok we missed that, lets have a look at the end for one without a 20 infront
				if ( foundDay == null ) {
					foundDay = date.match( /[^0-2]([1-9]{1}[0-9]?)$/ )
				}
				// ok, we missed htat, look for one with an ordinal suffix
				if ( foundDay == null ) {
					foundDay = date.match( /^([1-9]{1}[0-9]?)[rd|st|nd|th]*/ )
				}
				
				//incase some types 'june7', which parseInt gives 'e7' from
				if (  foundDay && foundDay[0].match("e") ) { 
					foundDay[0] = foundDay[0].replace("e", '')
				}
				
				if ( foundDay != null ) {
					day = parseInt(foundDay[0])
				}

			}
			
			// see if were in a vlid range for days months etc...
			var badDate = 0
			
			if ( month == 0 || month > 13 ) {
				badDate = 1
			}
			
			if ( day == 0 || day > 31 ) {
				badDate = 1
			}
			
			if ( year < 2000 || year > 2200 ) {
				badDate = 1
			}
			
			if ( badDate == 1 ) {
				alert("Sorry, which date that is, you can enter dates like this:\nApril 5th\n22/7\n1/3/08")
				return false
			}
			
			// check 'days in the month'
			if ( (month == 9 || month == 4 || month == 6 || month == 11) && day > 30 ) {
				day = 30
			}	

			if ( month == 2 && day > 28 ) {
				day = 28
			}				
									
			// check were in the future				
			if ( year < thisYear || ( month < thisMonth && year == thisYear ) || ( day < thisDay && month == thisMonth && year == thisYear )  ) {
				field.value = "today"
				return false
			}
			
			// were all good, put it back in the 'required' format
			if ( year == thisYear && month == thisMonth && day == thisDay ) {
				field.value = "today"
			} else {
				field.value = day + "/" + month + "/" + year
			}
			
			return true
			
		},
		
		// will look for the named fields, and check theyre not empty
		validatSubscribeForm :  function( theForm, required ) {
		
			var checkAll = false		
		
			if ( (! required) || (! required.length) ) {
				// weve not been given a nya required fields, so we assume they all are
				required = theForm.elements
				checkAll = true
		
			}
			
			if ( theForm._emailAddress ) {
				
				// check email fist
				if (theForm._emailAddress.value == "" ) {
					alert( "Sorry, an email address is rquired" )
					return false
				}
				
				// chack its a valid email
				var regEx = /[\w-\.]{2,}@[\w-\.]{2,}\.[\w]{2,}/
				var matches = regEx.exec( theForm._emailAddress.value )
				if ( matches ) {
					theForm._emailAddress.value = matches[0]
				} else {
					alert("Sorry, that email address doesnt seem to be valid")
					return false
				}
			}
				
			for ( var i=0; i<theForm.elements.length; i++ ) {
			
				var thisInput = theForm.elements[i]
											
				if ( thisInput.type == "text" || thisInput.type == "select-one") {
					if ( thisInput.value == "" && thisInput.name != "_emailAddress" && ( checkAll == true || required.match(thisInput.name) ) ) {
						alert( "Sorry, " + thisInput.name + " must be completed" )
						return false
					}
				} else if ( thisInput.type == "select-one" ) {
			
				
				}
							
			}
			
			return true
		
		},
		
		validateTime : function( field ) {
			
			var time = field.value
			
			if ( time.match("now") ) {
				field.value = "now"
				return true
			}
		
		
			var currentTime	= new Date()		
			var thisHour	= currentTime.getHours()
			var thisMinute	= currentTime.getMinutes()
			
			var hour = minute = -1
		
			var parts = time.split(":")
		
			if ( parts.length == 2 ) {
				
				hour = parseInt(parts[0])
				minute = parseInt(parts[1])
				
				// do 12hr->24hr conversion
				var twelveHour = parts[1].match(/[ap]m/)
				if ( twelveHour && twelveHour == "pm" ) {
					hour = parseInt(hour) + 12
				}
					
			} else {
				
				// look for atleat 3 digits
				var rawTimeMatch = time.match(/^[0-9]{3,4}/)
				if ( rawTimeMatch ) {
					var rawTime = rawTimeMatch[0]
					digits = rawTime.length  
					minute = parseInt( rawTime.substr( ( digits - 2), 2 ) )
					hour = parseInt( rawTime.substr( 0, digits - 2 ) )					
					
					var twelveHour = time.match(/[ap]m/)
					if ( twelveHour && twelveHour == "pm" ) {
						hour = parseInt(hour) + 12
					}
					
				} else {
					// just hours this time
					rawTimeMatch = time.match(/^[0-9]{1,2}/)
					if ( rawTimeMatch ) {
						hour = parseInt(rawTimeMatch[0])
						var twelveHour = time.match(/[ap]m/)
						if ( twelveHour && twelveHour == "pm" ) {
							hour = parseInt(hour) + 12
						}
						minute = 0
					}
				}

				
			}
			
			if ( hour == -1 || minute == -1 ) {
				alert("Sorry, couldnt work out that time, you can enter times as:\n8:15\n9pm\n10:15pm")
				return false
			}	
			
			badTime = 0
		
			if ( hour < 0 || hour > 23 ) {
				badTime = 1
			}
			
			if ( minute < 0 || minute > 59 ) {
				badTime = 1
			}
			
			if ( badTime == 1 ) {
				alert("Sorry, couldnt work out that time, you can enter times as:\n8:15\n9pm\n10:15pm")
				return false
			}	
			
			// check 
			if ( document.getElementById('sendDate') && document.getElementById('sendDate').value == "today" ) {
				if ( hour < thisHour || ( hour == thisHour && minute < thisMinute ) ) {
					field.value = "now"
					return true
				}
			}
			
			if ( hour < 10 ) { hour = "0" + hour }
			if ( minute < 10 ) { minute = "0" + minute }
			
			field.value = hour + ":" + minute
			return true
		
		},
		
		
		confirmSpool : function() {
			return confirm("Are you sure you wish to submit this newsletter for delivery?");
		},
		
		updatePlainTextField : function( text ) {
			
			var field = document.getElementById('plainTextAlternative')
			if ( ! field ) { return }
				
			var unescaped = unescape(text)
			var regex = /<br \/>/g
			unescaped = unescaped.replace(regex, "\n")
	
			field.value = unescape(unescaped)
			
		},
		
		
		hideStatusMessage : function() {
				
			var div = document.getElementById('divulgeStatusMsg');
			
			if ( div ) {
				div.style.display = "none";	
			}
		},
		
		
		showStatusMessage : function() {
		
			if ( document.documentElement.scrollTop ) {
				newPos = eval(document.documentElement.scrollTop);
			} else {
				newPos = eval(document.body.scrollTop);
			}
			offset = 150 - eval(newPos);
			if (offset > 0) { newPos = eval(newPos) + eval(offset); }
			newPos = eval(newPos) + 150;
		
			var div = document.getElementById('divulgeStatusMsg');
			if ( div ) {
				div.style.display = "block";
				div.style.top = newPos + "px";
			}
		}
				
}