//* **************************************************************************************
// * 
// * Main CONTROL class 
//*
//* **************************************************************************************	

this.autoCompleteClass = function() {
	var englishSeparator = ",&nbsp;"; // First instance will be preceding Prefecture name, ie Not needed ...	var japaneseSeparator = "&nbsp;"; 	 //	... initialize() below for on loading of each subsequent address-set
	
	// Initialize subList Object to handle drop-down address list
	this.subListObj = new SubListClass();



	//*** Initialise control for each new address set loaded (longestString provided by addressClass::buildArrays	)
	this.initialize = function() {
   	var longestString = addressData.buildArrays();
		input.style.width = (longestString*10) + "px";

		/* Set this flag for helpDisplay */
   	this._isResult = (addressData.linkArray[0]=="srch");

		document.getElementById("helpBox").style.left = document.getElementById('titleBoxTable').offsetLeft + document.getElementById('titleBoxTable').offsetWidth - 20;	
		setHelpText( helpText .helpNewPage, this._isResult );
		
		input.value = "";	
		this.subListSelected = -1;

		// *** Set ',' or '-' separators for title elements 
		lastCharIsLetter = addressData.englishArray[0].search( /[a-z]$/i ); // last char before closing </a> IFF alpha 
		if (lastCharIsLetter >= 0) { //if not yet numeric/chome part of address, separate with comma and space
				englishSeparator = ",&nbsp;";
				japaneseSeparator = "&nbsp;";
				}
			else {
				englishSeparator = "-";
				japaneseSeparator = "-";
				}			
		//When done, focus to inputBox
		input.focus();
		}
	
	//* **************************************************************************************
	// * 
	// * EVENT CONTROL 
	//*
	//* **************************************************************************************	
	this.keyboardNavigation = function(event) {
		switch (event.keyCode) {
			case 9: //TAB keyup
					if (event.shiftKey) this.subListObj.selectPrevious(); else this.subListObj.selectNext(); 
					return false;
			case 16: //ignore lifting of SHIFT key
					return false; 
			case 13: //EnterKey handled by enterKeyPressed() from onSubmit
				 	return true; 
			
			case 27: //ESC
					input.value=""; 
					document.getElementById('japanesePreview').innerHTML = "";
					this.subListObj.clearDropDown(); 
					disableNextButton(); 
					break; 
			case 38: // upArrow
					this.subListObj.selectPrevious(); break; 
			case 40: // downArrow
					this.subListObj.selectNext(); break; 
			case 191:  // '/' move focus to search box
					setSearch(); input.value=""; break;

			default: 
					disableNextButton(); 	
					this.processDropDown();
			}		
			
		return false; //disable BackSpace=>navigator history command etc
		}
		
	this.enterKeyPressed = function() {
		if ( this.subListObj.isVisible() ) {
				this.itemSelected( this.subListObj.getSelected() );
				return false;
				}
		else
			return this.gone( this.subListObj.getSelected() );
		}
		
	this.tabKeyDown = function() { //TAB key moves focus off input box before keyUp is triggered so must return false if TAB response needed in dropdown
		return ( !this.subListObj.isVisible() ); //if no sublist to navigate with TAB, then return true and move off
		}

	this.backSpacePress = function() {
		if ( input.value == "")
			this.goHistory(-1);
		}



	//* **************************************************************************************
	// * 
	// * process dropdown for matching results (on each keypress)  
	//*
	//* **************************************************************************************				
	this.processDropDown = function()
		{
		if (addressData.englishArray.length==0) 
				return;
		input.style.color="black";
		
		if (input.value.charAt(0)>='a') // => lowercase first letter, make UpperCase
				input.value = input.value.charAt(0).toUpperCase() + input.value.substr(1);

		// Repeated key-press cycles through current subArray
		if (input.value.length==2 && input.value.charAt(0)==input.value.charAt(1).toUpperCase()) { 
				input.value = input.value.charAt(0);
				this.subListObj.selectNext();
				return;
				}
		 // elseif SubItem already selected: 
		else if ( !this.subListObj.isVisible()	&& this.subListObj.getSelected()>=0 ) {
				//  if now adding extra text - address numbers etc, de-activate selection (ie. enter will now take search string straight to google maps)		
				var selectedItemLength = addressData.englishArray[ this.subListObj.getSelected() ].length;
				if ( input.value.length > selectedItemLength ) {
						input.style.color="gray";
						disableNextButton();
						document.getElementById("japanesePreview").innerHTML = addressData.kanjiArray[this.subListObj.getSelected()] + input.value.substr( selectedItemLength );
						setHelpText( helpText .helpExtraInput, this._isResult );
						return; 
						} 
		}
				
				
		document.getElementById('japanesePreview').innerHTML = "";
		// *** If all else fails, process keypress and display/update drop down accordingly 
		var hits = this.subListObj.populateSubArray();
		if ( hits <= 0 ) { //no matches 
				if ( hits == 0 ) { //special case, following on from previous exactMatch 				
						var temp = input.value;
						this.itemSelected( this.subListObj.getSelected() );
						input.value = temp;
						}
				input.style.color="gray";
				disableNextButton();
				this.subListObj.hide();
				}
				
		} // end of processDropDown() 
		
	
	// Set last history entry NOT hyperlinked!	
	this.setTitle = function( selIndex ) {
		var historyEntry = addressData.pushHistory(selIndex);
	
		if (!document.getElementById('ehistory' + historyEntry)) {
			document.getElementById("englishTitle").innerHTML += "<span id='ehistory" + historyEntry + "'></span>";
			document.getElementById("japaneseTitle").innerHTML += "<span id='jhistory" + historyEntry + "'></span>";
			}
		// New history titles added de-activated (as they point at the current page anyway) 	
		document.getElementById('ehistory' + historyEntry).innerHTML = "<!--a href='#' onclick=\"obj.goHistory(" + historyEntry + ")\"-->"  + addressData.englishArray[selIndex] + "<!--/a-->" + englishSeparator ;
		document.getElementById('jhistory' + historyEntry).innerHTML = addressData.kanjiArray[selIndex] +  japaneseSeparator;
		// Activate previous history link	 by removing HTML comment entities 
		if (historyEntry > 1)	
				document.getElementById('ehistory' + (historyEntry-1)).innerHTML = document.getElementById('ehistory' + (historyEntry-1)).innerHTML.replace(/!?--/g, "" );
	
		document.getElementById('japanesePreview').innerHTML = "";
		input.value = "";
		}
			
	this.resetTitle = function() {
		addressData.historyArray.length = 0;
		document.getElementById("englishTitle").innerHTML = "";
		document.getElementById("japaneseTitle").innerHTML = "";
		document.getElementById('japanesePreview').innerHTML = "";
		input.value = "";
		this.subListObj.clearDropDown();

		}



	//* **************************************************************************************	// * 	// * Sublist item selected:	//*	//* **************************************************************************************	

	// *** item chosen from subList => fill out title input-box, and activate 'next' button	
	this.itemSelected = function( selIndex ) {
		input.value = addressData.englishArray[selIndex];
		if ( this._isResult ) { // Search result				this.processDropDown();
				input.focus();		
				disableNextButton();
				}
		else
				enableNextButton();
		
		document.getElementById('japanesePreview').innerHTML = addressData.kanjiArray[selIndex]; 
		this.subListObj.hide();
		input.style.color = "black";
		}
	
	// mouseclick selection event called from either table items or dropdown list:
	// 		update display (itemSelected), and then gone() to process next url (unless item is from search result) 
	this.mouseSelection = function(selIndex) {
		this.itemSelected(selIndex);
		if ( !this._isResult ) {
				this.gone(selIndex);
				}
		}
		
	// Show selection
	this.searchResultSelected = function(selIndex) { /* dead for now? */  }
	
	

	//* **************************************************************************************
	// * 
	// * Progress actions
	//*
	//* **************************************************************************************	
	this.gone = function(selIndex) {
		if (selIndex<0)
			return false;

		if ( addressData.linkArray[selIndex]=="#" // => final link, pointing to map address
		  || !nextButtonEnabled() ) {// => extra text added after selection => take straight to map
				//				this.subListSelected=selIndex;
				return this.toMap();
				}
		this.setTitle( selIndex );
		document.getElementById("mapLayer").style.display = "none";
		
		//processAddressURL = AJAX get next address set 
 		this.processAddressURL( addressData.linkArray[selIndex] ); // + "&ecomposite=" + document.getElementById("englishTitle").innerHTML.replace(/\<[^\>]*\>/g, "") );		

		disableNextButton();
		this.subListObj.clearDropDown();
		
		return false; //disable form submit this time
		}	


	// *** Will become much bigger function if AJAX used, will take up all of fopen.php output display 
	this.processAddressURL = function( url ) {
		document.getElementById('loadingPleaseWait').style.display = "block";
		ajaxFunction("fopen.php?url=" + url, this.ajaxAddressHandler); 	
		}

	this.ajaxAddressHandler = function( responseText ) {
		document.getElementById('loadingPleaseWait').style.display = 'none'; 
		//onMouseMove="if (!mouseOverEnabled) mouseOverEnabled = true"		    
 
   	document.getElementById('resultsFrame').innerHTML = responseText;
		obj.initialize();
		
   	document.getElementById('resultsFrame').scrollTop = 0;
   	input.focus();
		}




	// *** accepts relative, or absolute histIndex value: -1 => relative = go back one; absolute = reload specific history instance		
	this.goHistory = function( histIndex ) {
		input.value = "";
		input.focus();		
		this.subListObj.hide();
		document.getElementById('japanesePreview').innerHTML = "";
		
		// If looking at map, first step return to table results for current adddress depth	 		
		if ( document.getElementById("mapLayer").style.display == "block" ) { 
				document.getElementById("mapLayer").style.display = "none";
				if (histIndex == -1) 
						return; //for backspace, first time just hide the map layer						
		}


		if (histIndex == -1) { // histIndex of -1 => call from backSpacePress
				histIndex = addressData.historyArray.length - 1;
				if (histIndex < 0) 
						histIndex = 0;
		}
			
		var pop;
		//Remove subsequent entries in history list
		for ( var j=addressData.historyArray.length; j > histIndex; j-- ) {
			addressData.popHistory(); // no return value required 
			document.getElementById('ehistory' + j).innerHTML = "";
			document.getElementById('jhistory' + j).innerHTML = "";
			}
	
		//Back to beginning 				// document.location="index.html";		
		if (histIndex == 0) {  				document.getElementById("resultsFrame").style.display = "none";			
				obj = new ZenkokuControl();	
				zenkoku.resetAll();
				return;
				}
 
		//De-activate last history title in chain by HTML-commenting out the link (the one now pointing at the current page)
		document.getElementById('ehistory' + histIndex).innerHTML = document.getElementById('ehistory' + histIndex).innerHTML.replace(/\<(\/)?a([^\>]*)\>/ig, "<!--$1a$2-->"); 

		// re-load historyArray address 
		this.processAddressURL( addressData.getHistoryCurrent() ); 
		}
		
	
	this.toMap = function() {
		// *** Compose 	query 
		var query = document.getElementById("japaneseTitle").innerHTML.replace( /<[^>]*>|\&nbsp\;/ig, "" );
		if (this.subListObj.getSelected()>=0) //ADD any extra text (ie numbers) AFTER the sub-list selection text
				query += addressData.kanjiArray[ this.subListObj.getSelected() ] 
								+ input.value.substr( addressData.englishArray[ this.subListObj.getSelected() ].length ); 
		else if (input.value != "") //otherwise add whatever text is in there, only USEFUL would be NUMBERS, so we need to add JAPANESE SEPARATOR
				query += input.value; 
	
		// *** Check if external map site has been selected from Maps dropdown
		if (document.getElementById("mapsRadioButtons1").checked) 
				document.forms['toMapForm'].map.value = "mapion";
		else if (document.getElementById("mapsRadioButtons2").checked) 
				document.forms['toMapForm'].map.value = "mapfan";
		else {
				// *** **************************************
				// *** Embed the google map! (DEFAULT)
				// *** **************************************
				var english = document.getElementById("englishTitle").innerHTML.replace( /<[^>]*>/ig, "" ).replace(/(,[^,]*),/g, "$1,<br>") + input.value;				
				this.embeddedGoogleMap( query, english );		
				showHelp(false);	
				return false;					
				}

				
		// *** if selected, submit form to outside maps (via ToMap.php)
		document.forms['toMapForm'].query.value = query.replace(/ /g, ""); //Remove all spaces for submission to map sites		
		document.forms['toMapForm'].submit(); 

		// Would like to return true; but need to submit() for mouseClicks from links - seems to work fine ...
 		return false; //don't allow form submit
		}
		
	this.embeddedGoogleMap = function(jquery, englishquery) {
			var embedFn = this;

			if (GBrowserIsCompatible()) {
					document.getElementById("mapLayer").style.display = "block";
					
					if (!this.map) {
							this.map = new GMap2(document.getElementById("mapLayer"));
							this.map.addControl(new GLargeMapControl());
							
							var mapControl = new GHierarchicalMapTypeControl();
									mapControl.clearRelationships();
									mapControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, "Labels", false);
				
						        // Add control after you've specified the relationships
							      this.map.addControl(mapControl);
							      this.map.enableScrollWheelZoom();
							      
									this.geocoder = new GClientGeocoder();
					} // endof map ctr 
						
								
					// *** Geocode Japanese address and center map 
					function geoCallback(point) {
						      if (point) {
										if ( embedFn.marker ) {	// Map being re-panned to a revised location 
												embedFn.map.removeOverlay( embedFn.marker );
												embedFn.map.panTo( point );												
										}								      
										else {		// New marker first	use						
												embedFn.map.setCenter(point, 15);
										}
										embedFn.marker = new GMarker(point);
										embedFn.map.addOverlay(embedFn.marker);
										
										var markerText = "<center><span style='padding-right: 15px'>" + jquery + "</span><br>" 
												+ englishquery + "</center><br>"
												+ "<a href='http://maps.google.com/maps?q=" + encodeURI( jquery.replace(/\&nbsp\;/g, "") ) + "' target='mapWindow' style='font-size: 10; float: right'>View in external map</a>";
//							 			embedFn.marker.bindInfoWindowHtml(markerText);	// so to reopen if marker subsequently clicked 
										embedFn.marker.openInfoWindowHtml(markerText);			
										
										GEvent.addListener( embedFn.marker, "click", function() {
												infoWindow =  embedFn.map.getInfoWindow();
												if (infoWindow.isHidden()) 
														embedFn.marker.openInfoWindowHtml(markerText);			
												else
														infoWindow.hide();
								      }); 

													        
								}
								else {
											alert(jquery + " not found");
						      } 
					} 					
					this.geocoder.getLatLng( jquery.replace(/ /g, ""), geoCallback );	//Some of google maps does not like spaces in address 
	



			        				        
		/*			var img = document.createElement('img');
						img.setAttribute('src', 'sabiya/Images/Find_us1.gif');
						img.setAttribute('width', '100');
						img.setAttribute('height', '100');
				        map.openInfoWindow(map.getCenter(), img);
		 
					var html = "<div style='text-align: center'> \
												<strong>Welcome to sabiya</strong><br> \
												<img src='sabiya/Images/Find_us1.gif' height='100' width='100' style='border: solid 1px black'> \
												</div>";
						map.openInfoWindowHtml( map.getCenter(), html );
		
		  
																		// Interesting ???            map.showMapBlowup(map.getCenter());
			        GEvent.addListener(map, "moveend", function() {
				          var center = map.getCenter();
				          document.getElementById("message").innerHTML = center.toString();
				       	 });
		*/																		
					} //endif 
		
		
		}//end embeddedGoogleMap

	/* *** ********************************************************************************* *** */

} //End of autoCompleteClass








//* **************************************************************************************
// * 
// * SubListClass - displays and controls drop down SubList 
//*
//* **************************************************************************************	
SubListClass = function() {
	// Constructing:
	this.subListSelected = -1;
	this.subArray = new Array();
	var subList = document.getElementById('dropdown');
	
	this.getSelected = function() {
		return this.subArray[this.subListSelected];
		}
		
	this.show = function () {
		subList.style.display = "block";
		// Update help text automatically (if showing)		
			setHelpText( helpText.helpDropDownVisible, obj._isResult );// helpDropDownVisible;		
		}
	this.hide = function () { // SubList is not necessarily cleared everytime it is hidden, ie on sub item Selected, subListSelected is retained!  
		subList.style.display = "none";	
		// Update help text automatically (if showing)		
			setHelpText( this.subListSelected>=0? helpText.helpSubListSelected :helpText.helpNewPage, obj._isResult );
		}
	this.clearDropDown = function() {
		this.subArray.length = 0;
		this.subListSelected=-1;
		subList.innerHTML = "";
		this.hide();
		}
	this.isVisible = function() {
		return (subList.style.display == "block");
		}
	
	//*** Isolate/recalculate matching strings from englishArray to display in dropdown	
	this.populateSubArray = function() {
		var previousMatch = this.subArray[ this.subListSelected ];
		this.subListSelected=-1;
		
		if (!input.value.length)
			return -1; //No keypress/searchstring to match	
		
		//Cycle thru englishArray for autocomplete matches 
		this.subArray.length=0;
		for ( var i in addressData.englishArray ) {
				if ( addressData.englishArray[i].indexOf(input.value) == 0 ) {
					this.subArray.push( i );
					if (this.subArray.length >= 20) 
							break;		//LIMIT clause 
					}
		}

		if (this.subArray.length == 0) {
				// if empty, check previousMatch to see if we're following on, thus we need to keep previousMatch in subArray!  
						if ( input.value.indexOf( addressData.englishArray[previousMatch] ) == 0 ) {
								this.subListSelected = 0;						
								this.subArray[ this.subListSelected ] = previousMatch;
								return 0;								
						}
						else 
							return -1;
				}
							
		this.subListSelected = 0; // first entry in subArray
		subList.innerHTML = "";
		for (var x in this.subArray) {
			var item = this.subArray[x];
			subList.innerHTML += "<a id='subitem" +item+ "' href='#' onmouseover='obj.subListObj.selectSub(" +x+ ")' onclick='obj.mouseSelection(" +item+ ")'>" 
							  + "<strong>" + addressData.englishArray[item].substr(0,input.value.length) + "</strong>" 
							  + "<span class='selectedText'>" + addressData.englishArray[item].substr(input.value.length) + "</span></a>";
			}
		if (this.subArray.length == 20) //Hit the limit clause
				subList.innerHTML += "<p style='font-size: small; color: gray'>&nbsp;&lt; More than 20 matches ... &gt;</p>";		
							  
		this.show();//			subList.style.display = >0?"block":"none";
		this.selectSub( this.subListSelected );
		return true;
		}
		
	//*** Highlight currently selected item in dropdown (un-highlight previous)
	this.selectSub = function(subItem) {		
		if (this.subListSelected >= 0) 
			document.getElementById("subitem" + this.subArray[this.subListSelected]).style.background = "white";//"#ffffdd"; //Deselect previous subListSelected in anycase

		if (subItem<0 || subItem>=this.subArray.length) {
			//document.getElementById("inputCover").innerHTML = /*englishSeparator + */"<strong>" + addressString + "</strong>";
			return;
			}		document.getElementById("subitem" + this.subArray[subItem]).style.background = "#ffffbb"; 
		this.subListSelected = subItem;
		}
				
	//*** Iterators 
	this.selectNext = function() {
		this.selectSub( (this.subListSelected + 1 >= this.subArray.length)?0:this.subListSelected+1 )
		}
	this.selectPrevious = function() {
		this.selectSub( (this.subListSelected - 1 < 0)?this.subArray.length-1:this.subListSelected-1 )
		}
		
} // *** end of SubListClass	----------------------------------------------------------





	//********************************************************************
	//* 		
	//* Decouple ajax xmlHttp from gone() process 
	//* 		utilise ajaxFunction( url, onreadystatechangehandler ) 
	//*		and have gone() and search() both provide their own callback functions
	//* 		
	//* 	Also we don't need to create new XMLHttpRequest object each time. ONE will do.	
	//* 		
	//********************************************************************
	ajaxFunction = function(url, callbackfn) {
			var xmlHttp;
			
			try {  // Firefox, Opera 8.0+, Safari
					xmlHttp=new XMLHttpRequest(); 
					}
			catch (e)  {  // Internet Explorer x2:
					try { 
						    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
						    }
				   catch (e) {
						    try {
							      xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
							      }
						    catch (e)  {
							      alert("Your browser does not support AJAX!");
							      return false;
							      }
			    			 }
			  		}
	
		// *** onreadystatechange 		  
		  xmlHttp.onreadystatechange = function() {
			    if(xmlHttp.readyState==4) {
							callbackfn( xmlHttp.responseText );
				      	}
			    }

		xmlHttp.open("GET", url, true);
		xmlHttp.send(null);	
	} //end of ajaxFunction *************************************************************************************************** 






/* *** ********************************************************************************* *** */
//Global functions


function toggleMapsRadioLayer() {
	 if ( document.getElementById('mapsRadioLayer').style.display != 'block') {
		document.getElementById('mapsRadioLayer').style.display = 'block';
		document.getElementById('mapsRadioButtons1').focus();
		}
	else
		document.getElementById('mapsRadioLayer').style.display = 'none';
		input.focus();
	 }

function mapsRadioButtonsClick( button ) {	
	document.getElementById("googleButton").style.display = (button==0)?"block":"none";
	document.getElementById("mapionButton").style.display = (button==1)?"block":"none";
	document.getElementById("mapfanButton").style.display = (button==2)?"block":"none";

	document.getElementById("mapsRadioButtons" + button ).checked = "checked";
	document.getElementById('mapsRadioLayer').style.display="none";
	input.focus();
	}

function disableNextButton() { document.getElementById("nextButtonPreload").style.display = "block"; }
function enableNextButton() { document.getElementById("nextButtonPreload").style.display = "none"; } 
function nextButtonEnabled() { return document.getElementById("nextButtonPreload").style.display =="none"; }
	





