//
// SafeFoodFinder script, v3.0
// Copyright 2006-2008 FinderDevelopment
//

function getCookie(cName) {
	var plainCookie = unescape(document.cookie);
	if (plainCookie.length > 0) {
		cStart = plainCookie.indexOf(cName + "=");
		if (cStart != -1) {
			cStart += cName.length + 1;
			cEnd = plainCookie.indexOf("|", cStart);
			if (cEnd == -1) {
				cEnd = plainCookie.length;
			}
			return plainCookie.substring(cStart, cEnd);
		}
	}
	return null;
}


////////////////////////////////////////////////////////////////////////////
// Creates the UI for SafeFoodFinder
////////////////////////////////////////////////////////////////////////////
var SafeFoodFinder = SafeFoodFinder || {};

// blank image
Ext.BLANK_IMAGE_URL = 'ext-2.0.1/resources/images/default/s.gif';


SafeFoodFinder.app = function() {
	
	//--------------------------------------------------------------------------
	// private variables
	//--------------------------------------------------------------------------
	var viewport;
	var comboBox;

	// public stuff
	return {

		//--------------------------------------------------------------------------
		// public function for initializing app
		//--------------------------------------------------------------------------
		init : function(){
			
			viewport = new Ext.Viewport({
		    layout:'border',
		    items: [{
	    		region: 'north',
	    		contentEl: 'north',
	    		split: false,
	    		height: 68
		    },{
	    		region: 'east',
	    		id: 'eastPanel',
	    		split: true,
	    		width: 162,
	    		minSize: 162,
	    		maxSize: 400,
	    		collapsible: true,
          items:
	          new Ext.TabPanel({
	          	id: 'eastTabPanel',
							border: false,
							enableTabScroll: true,
							activeTab: 0,
							items:[{
								contentEl: 'googAds',
							  title: 'Ads',
							  closable: false
							},
							{
								contentEl: 'legendBrief',
								title: 'Legend',
								closeable: false
							}]
            })
		    },{
	        region: 'south',
	        contentEl: 'south',
	        height: 40,
	        minSize: 40,
	        maxSize: 80
		    },{
	        region:'center',
	        id: 'centerPanel',
	        layout: 'fit',
	        items:
	        	new Ext.TabPanel({
	        		id: 'centerTabPanel',
	        		border: false,
	        		activeTab: 0,
	        		items: {
	        			title: 'Map',
	        			id: 'map',
	        			contentEl: 'nomap',
	        			closable: false
	        		}
	        	})
		    }]
			});
			
			// Create map
			this.rfMap = new RFMap();

			// Create request for news
			/*
			Ext.Ajax.request({
		  	scope: this,
		  	url: "news.php",
		  	method: "GET",
		  	callback: function(options, success, response){
		  		// 'this' points to app
		  		
		  		if (!success) {
		  			return;
		  		}
		  		
					var result = Ext.util.JSON.decode('(' + response.responseText + ')');
					if (result.num > 0){
						var newsWindow = new Ext.Window({
							title: 'News',
							height: 300,							
							width: 400,
							autoScroll: true,
							model: true,
							resizable: false,
							html: result.news,
							buttons:[{
							  text: 'Ok',
							  scope: this,
								handler: function(){
									newsWindow.hide();
									this.comboBox.focus(true);
								}
							}]
						});
						newsWindow.show();
					}
		  	}
		  });
			*/
			
			// Add toolbar
			var tb = new Ext.Toolbar('toolbar');
			tb.add(
		    {
	        text: 'About',
					tooltip: 'Show info about this web site',
	        scope: this,
	        handler: function(){
	        	this.showCenterTab('static', 'about', 'About');
	        }
		    },
		    {
	        text: 'News',
					tooltip: 'Show news about this web site',
	        scope: this,
	        handler: function(){
	        	this.showCenterTab('static', 'news', 'News');
	        }
		    },
		    {
	        text: 'Show Link',
	        tooltip: 'Show link to map',
	        scope: this,
	        handler: function(){
	        	this.showMap();
	        	this.rfMap.showLink();
	        }
		    }
			);
    				
			var ds = new Ext.data.Store({
				proxy: new Ext.data.HttpProxy({
					url: 'entry.php'
				}),
				reader: new Ext.data.JsonReader({
						root: 'results',
						id: 'abbr'
					}, [
						{name: 'abbr'},
						{name: 'fullname'}
				])
			});
			
			// Custom rendering Template
			var resultTpl = new Ext.XTemplate(
				'<tpl for=".">',
					'<div class="x-combo-list-item">',
						'{fullname}',
					'</div>',
				'</tpl>');

			this.comboBox = new Ext.form.ComboBox({
				forceSelection: true,
				minChars: 3,
				store: ds,
				width: 250,
				listWidth: 400,
				hideTrigger:true,
				tpl: resultTpl,
				displayField: 'fullname',
				hiddenName: 'facilityId',
				emptyText: 'Enter establishment name',
				loadingText: 'Searching...',
				listeners: {
					select: {
						fn:this.rfMap.setLocation,
						scope:this.rfMap
					},
					focus: function(cb){
						// When user shifts input focus back to restaurant field, do drop down
						cb.onTriggerClick();
					}
				}
			});
			
			// Firefox needs this for the comboBox:
			this.comboBox.on('submit', this.rfMap.setLocation, this.rfMap, { stopEvent: true });

			// IE7 uses this:
			Ext.get('locationForm').on('submit', this.rfMap.setLocation, this.rfMap, { stopEvent: true });
			
			// Apply it to the search box
			this.comboBox.applyToMarkup('restaurant');
			
			// Select all contents in search box.
			//this.comboBox.focus(true);
			
			// Clicking "Find" button causes setLocation
			Ext.get('findButton').on('click', this.rfMap.setLocation, this.rfMap, { stopEvent: true });
			
			Ext.QuickTips.init();

		},
		
		//--------------------------------------------------------------------------
		// public variables
		//--------------------------------------------------------------------------
		rfMap : null,

		//--------------------------------------------------------------------------
		// public function for selecting map tab
		//--------------------------------------------------------------------------
		showMap : function(){
			Ext.getCmp('map').show();
		},
		
		//--------------------------------------------------------------------------
		// public function for finding or creating a new tab in the center region
		//--------------------------------------------------------------------------
		showCenterTab : function(type, id, visId){
			var showTab = Ext.getCmp(id);
			if (!showTab){
				showTab = Ext.getCmp('centerTabPanel').add({
					title: visId,
					id: id,
					autoLoad: {url: 'getinfo.php', method: 'GET', params: type + '=' + id},
					text: "Loading information for " + visId + "...",
					autoScroll: true,
					closable: true
				});
			}
			showTab.show();
		},

		//--------------------------------------------------------------------------
		// public function for collapsing comboBox and cancelling any outstanding
		// transactions
		//--------------------------------------------------------------------------
		collapseComboBox : function(){
			this.comboBox.store.rejectChanges();  // This should cancel transactions, but doesn't seem to
			this.comboBox.collapse();
		}
		
	};
}();


////////////////////////////////////////////////////////////////////////////
// Object that contains all of the SafeFoodFinder Map logic
////////////////////////////////////////////////////////////////////////////
function RFMap() {
	//
	// Map variables.
	//  x=-122.17655181884766&y=47.61530813042245&z=11
	this.xDefault = -122.176552;		// default longitude
	this.yDefault = 47.615308;			// default latitude
	this.zoomDefault = 10;				// default zoom
	this.addedMarkers = [];				// keeps track of which markers have been added to the map
	this.centerFacility = null;		// location to open balloon for when map moves
	this.baseUrl = '';						// base URL to the current page
	this.curLink = '';						// text of the link to the current map

	//--------------------------------------------------------------------------
	// Helper function for adding a marker
	//--------------------------------------------------------------------------
	this.createMarker = function(point, text, color, id) {
	
		var titleStr = id;
	
		var marker = new GMarker(point, {icon:this.icons[color], title:titleStr});
		marker.id = id;
		marker.marker = true;
		marker.bindInfoWindowHtml(text);
		
	  // Add it to the map
	  this.map.addOverlay(marker);
	
	  return marker;
	};
	
	//--------------------------------------------------------------------------
	// Finds a location on the map.
	//--------------------------------------------------------------------------
	this.setLocation = function(combo, record, index) {
		// 'this' points to the rfMap

		var searchString = '';		
		if (record.data){
			searchString = record.data.abbr;
		}
		else {
			searchString = Ext.get('location').getValue(false);
		}

		// Switch back to the map page
		SafeFoodFinder.app.showMap();
		
		// Set status indicator
		this.setStatusLoading(true);
		
		// Get lat/lon for new location via AJAX
	  Ext.Ajax.request( {
	  	scope: this,
	  	url: "name.php",
	  	params: {
	  		loc: searchString
	  	},
	  	method: "GET",
	  	callback: function(options, success, response){
	  		// 'this' points to main RFMap
	  		
	  		if (!success){
	  			this.setMsg('Error. Try updating map again.');
	  			this.setStatusLoading(false);
	  			return;
	  		}
	  		
	  		// Evaluate JSON response
				var result = Ext.util.JSON.decode('(' + response.responseText + ')');
	  		if (result.error){
	  			this.setMsg('Error: ' + result.error);
	  			this.setStatusLoading(false);
	  			return;
	  		}
				if (!result.lat){
	  			this.setMsg('Error. Try updating map again.');
	  			this.setStatusLoading(false);
					return;
				}

				var center = new GLatLng(result.lat, result.lon);
		
				this.centerFacility = result.centerFacility;
 				this.map.setCenter(center, result.zoom);
 		
 				if (result.placeMarker) {
					point = new GPoint(result.lon, result.lat);
					var newMarkerIdx = this.addedMarkers.length;
      		this.addedMarkers[newMarkerIdx] =
      			this.createMarker(point, result.loc,
      												result.placeMarker.color, result.loc);
    		}
    		
				// Collapse autocomplete drop down
				SafeFoodFinder.app.collapseComboBox();

				// Set current link URL
				this.setLink("?loc=" + result.loc);
		  	
		  	// Set indicator to done
				this.setStatusLoading(false);

			}  // callback: function
		});  // Ext.Ajax.request
		
		return false;
	};  // setLocation

	//--------------------------------------------------------------------------
	// This function is fired whenever the map moves. It sends an AJAX request to the server to get any
	// map overlays in the current view.
	//--------------------------------------------------------------------------
	this.viewChanged = function() {
		// 'this' will be set to the RFMap
	  var bounds = this.map.getBounds();
	  var sw = bounds.getSouthWest();
	  var ne = bounds.getNorthEast();
	  var zoomLevel = this.map.getZoom();
	
		// Set status indicator
		this.setStatusLoading(true);

		// Set the current link URL
	 	var locX = (ne.lng() + sw.lng()) / 2;
	 	var locY = (sw.lat() + ne.lat()) / 2;
	 	this.setLink("?x=" + locX + "&y=" + locY + "&z=" + zoomLevel);
	  
	  Ext.Ajax.request( {
	  	scope: this,
	  	url: "markers.php",
	  	params: zoomLevel <= 10 ?
	  	{
	  		zoom: zoomLevel
	  	} :
	  	{
	  		l: sw.lng(),
	  		r: ne.lng(),
	  		b: sw.lat(),
	  		t: ne.lat(),
	  		zoom: zoomLevel
	  	},
	  	method: "GET",
	  	callback: function(options, success, response){
	  		// 'this' points to main RFMap
	  		var point = null;
	  		var mapMarker = null;
	  		var markerId = null;
	  		
	  		if (!success){
	  			this.setMsg('Error. Try updating map again.');
	  			this.setStatusLoading(false);
	  			return;
	  		}

	  		// Evaluate JSON response
				var facilities = Ext.util.JSON.decode('(' + response.responseText + ')');
				var idx = 0;
				var id = '';
				
				// Add facility markers
	      for (idx = 0; idx < facilities.length; idx++) {
	      		var facility = facilities[idx];
	          id = facility.id;

						// Find the facility as either an added marker or highlighted marker	          
	          var marker = this.addedMarkers[id];
	          if (!marker) {
	          	// Add the new marker
		          point = new GPoint(facility.lon, facility.lat);		          
	            mapMarker = this.createMarker(point, facility.text, facility.color, facility.name);
            	this.addedMarkers[id] = mapMarker;
	          }
	      }
	
				var center = this.centerFacility;
	      if (center) {
					if (this.addedMarkers[center]) {
	        	GEvent.trigger(this.addedMarkers[center], 'click');
	        }
	        this.centerFacility = null;
	      }

				var msg;
  			if (facilities.length == 50){
					msg = '<b>Displaying top ' + facilities.length + ' eating establishments with the worst recent inspection scores. Zoom in to see more.</b>';
  			}
  			else {
					msg = '<b>Displaying all ' + facilities.length + ' eating establishments.</b>';
  			}
  			this.setMsg(msg);

				// Clear status indicator
				this.setStatusLoading(false);

	  	}  // callback: function
	  } );  // Ext.Ajax.request
	};  // viewChanged


	//--------------------------------------------------------------------------
	// Clear all the overlays from the map and then re-add route lines,
	// place markers, and range circles, if defined
	//--------------------------------------------------------------------------
	this.clearMostOverlays = function() {
		this.map.clearOverlays();
		this.addedMarkers = [];
	};

	//--------------------------------------------------------------------------
	// Utility function for opening airport information in a new tab
	//--------------------------------------------------------------------------
	this.displayInfo = function(type, id, visId) {
		SafeFoodFinder.app.showCenterTab(type, id, visId);
	};
	
	//--------------------------------------------------------------------------
	// Utility function for setting "Loading..." indicator in status area
	//--------------------------------------------------------------------------
	this.setStatusLoading = function(loading){
		var statusArea = Ext.get("status");
		if (loading){
			statusArea.update("Updating...");
			statusArea.addClass("loadingStatus");
		}
		else {
			statusArea.update("");
			statusArea.removeClass("loadingStatus");
		}
	};
	
	//--------------------------------------------------------------------------
	// Utility function for setting message in status area
	//--------------------------------------------------------------------------
	this.setMsg = function(msgText){
		var msgArea = Ext.get("msg");
		msgArea.update(msgText);
	};

	//--------------------------------------------------------------------------
	// Utility function for displaying a link to the current map
	//--------------------------------------------------------------------------
	this.showLink = function() {
		Ext.MessageBox.alert('Link', 'Link to current map: ' + this.curLink);
	};

	//--------------------------------------------------------------------------
	// Utility function for setting link to the current map
	//--------------------------------------------------------------------------
	this.setLink = function(restLink) {
		this.curLink = this.baseUrl + restLink;
	};

	//--------------------------------------------------------------------------
	// Main SafeFoodFinder Map constructor logic. Initializes Google Map.
	//--------------------------------------------------------------------------
  if (GBrowserIsCompatible()) {
  	// Create icons for all of the map markers

		// Create object to hold all markers
  	this.icons = {
  		green: new GIcon()
  	};
  	
  	// Flesh out green marker
		this.icons.green.image = "markers/mini_green.png";
		this.icons.green.shadow = "markers/mini_shadow.png";
		this.icons.green.iconSize = new GSize(12,20);
		this.icons.green.shadowSize = new GSize(22,20);
		this.icons.green.iconAnchor = new GPoint(6,20);
		this.icons.green.infoWindowAnchor = new GPoint(5,1);
		this.icons.green.imageMap = [5,0, 1,4, 1,8, 3,12, 5,20, 7,20, 8,12, 11,8, 11,4, 7,0];
		// todo: need transparent icon image
		//this.icons.green.transparent = "icontransparent.png";
	
		// Create more markers based on 'green'
		var otherIcons = ["yellow", "red"];
		for (var iconIdx = 0; iconIdx < otherIcons.length; iconIdx++){
			this.icons[otherIcons[iconIdx]] = new GIcon(this.icons.green, "markers/mini_" + otherIcons[iconIdx] + ".png");
		}
		
  	this.map = new GMap2(Ext.getCmp('map').body.dom);
		this.map.rfMap = this;		// reference back to RFMap inside the map
  	this.map.setCenter(new GLatLng(this.yDefault, this.xDefault), this.zoomDefault);

		// Add the new terrain type
		this.map.addMapType(G_PHYSICAL_MAP);
		
		// Add zoom, scale, and map type controls
  	this.map.addControl(new GLargeMapControl());
		var scalePos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(75,10));  // Position scale control at top left because of Local Search box
		this.map.addControl(new GScaleControl(), scalePos);
  	this.map.addControl(new GHierarchicalMapTypeControl());
  	this.ovcontrol = new GOverviewMapControl();
  	this.map.addControl(this.ovcontrol);
  	this.map.enableContinuousZoom();
  	this.map.enableScrollWheelZoom();
      	
    this.baseUrl = document.URL;

    // Process parameters
    var urlParts = document.URL.split('?', 2);
    this.baseUrl = urlParts[0];
    this.curLink = this.baseUrl;
    var urlParams = Ext.urlDecode(urlParts[1]);
    
    // Add map events
    if (!urlParams.nomarkers) {
    	GEvent.addListener(this.map, 'moveend', this.viewChanged.createDelegate(this));
    	GEvent.addListener(this.map, 'zoomend', function(oldZoomLevel, newZoomLevel){
		  	if (oldZoomLevel != newZoomLevel) {
					this.rfMap.clearMostOverlays();
				}
    	} );
    }
    
		if (urlParams.x){
			var xValue = parseFloat(urlParams.x) || this.xDefault;
			var yValue = parseFloat(urlParams.y) || this.yDefault;
			var zoomValue = parseInt(urlParams.z, 10) || this.zoomDefault;
			this.map.setCenter(new GLatLng(yValue, xValue), zoomValue);
		}
		else {
			this.map.setCenter(new GLatLng(this.yDefault, this.xDefault), this.zoomDefault);
		}
  }
}

// initialize the application
Ext.onReady(SafeFoodFinder.app.init, SafeFoodFinder.app, true);

