var markersArray = [];
var z = [];
var faces = [];
var marker = new google.maps.Marker();
var zoomLevel = 16;
//var sfLocation = {lat:37.7835, lng:-122.4222};
var sfLocation = {lat:37.7835, lng:-122.4222};
var map, jsonFeed, availpercent, usedpercent, dataTimeStamp;
var circlemarker = new google.maps.Circle();
var currentlyShowing = 'availability';
var citySections = {
	mission:       {position:new google.maps.LatLng(37.76026,-122.42044),zoom:15},
	fillmore:      {position:new google.maps.LatLng(37.78600,-122.43357),zoom:15},
	marina:        {position:new google.maps.LatLng(37.79974,-122.43850),zoom:16},
	fisherman:     {position:new google.maps.LatLng(37.80700,-122.41780),zoom:16},
	soma:          {position:new google.maps.LatLng(37.78533,-122.39323),zoom:15},
	financialdist: {position:new google.maps.LatLng(37.79315,-122.40300),zoom:15},
	civiccenter:   {position:new google.maps.LatLng(37.77800,-122.42050),zoom:16},
	city:          {position:new google.maps.LatLng(sfLocation['lat'],sfLocation['lng']),zoom:13}
}
var introMessage = "<span id='intromsg'><span class='line'>1) Choose a pilot neighborhood above</span>"+
"<span class='line'>2) Click a blockface or garage icon for rates</span>"+
"<span class='line'>3) Click $ for a comparative pricing map</span>"+
"<span class='line'><br /></span>"+
"<span class='introHeader'><div class='introHeaderAvailability'>Availability</div>   <div class='introHeaderPricing'>Pricing</div></span>"+
"<span class='line'><span class='itemRange'>low</span> <div class='itemRangePercent'>0-15%</div>  <div class='itemRangeRate'>$0 - $2.00 / hr</div></span>"+
"<span class='line'><span class='itemRange'>med</span> <div class='itemRangePercent'>15-30%</div>  <div class='itemRangeRate'>$2.01 - $4.00 / hr</div></span>"+
"<span class='line'><span class='itemRange'>high</span> <div class='itemRangePercent'>30%+</div>  <div class='itemRangeRate'>$4.01+ / hr</div></span>"+
"<span class='line'><br />Use + and - to zoom in manually</span>"+
"<span class='line'><a href='/sfpark-org-terms-of-use/'>Terms of Use</a></span></span>"+
"<span class='line'><br /></span>";

$(function(){
	//$('.scroll-pane').jScrollPane();
	initialize();
	$("#f").html("<div class='map_loader'><img src='/wp-content/themes/sfpark/images/sfpark_loader.gif' /></div>");
	var jsonFeed = "http://sfpark.org:1337/sfpark/rest/availabilityservice";


	//Sample query below:
	//'/SFpark/REST/AvailabilityService?lat=37.792275&long=-122.397089&radius=5&uom=mile&response=json&method=availability&jsoncallback=jsondata&pricing=yes';
	$.jsonp({
		url: jsonFeed,
		data: { 'lat'     : sfLocation['lat'],
						'long'    : sfLocation['lng'],
						'radius'  : '5',
						'uom'     : 'mile',
						'pricing' : 'yes',
						'response': 'json'
		},
		dataType: 'jsonp',
		callbackParameter: 'jsoncallback',
		timeout: 9000,
		success: function(data, status){
			prepareData(data,status);
		},
		error: function(XHR, textStatus, errorThrown){
			//c('Data loading error: ' + errorThrown + textStatus);
			c('Error fetching the parking information. Please try reloading.');
		}
	});
	

	
	/*
	$("#reset").click(function() {
		clearOverlays({});
	});
	*/

	// Change the display to show availability information.
	$('#availbutton').click(function(){
		if(currentlyShowing == 'availability'){
			return;
		}
		currentlyShowing = 'availability';
		clearOverlays({});
		$('#pricebutton').removeClass('selected');
		$('#availbutton').addClass('selected');
		$('#legend').html('<img src="/wp-content/uploads/icons/availabilitylegend.png" alt="availability legend" />');
		fillMap(currentlyShowing);
	});

	// Change the display to show price information.
	$('#pricebutton').click(function(){
		if(currentlyShowing == 'price'){
			return;
		}
		currentlyShowing = 'price';
		clearOverlays({});
		$('#availbutton').removeClass('selected');
		$('#pricebutton').addClass('selected');
		$('#legend').html('<img src="/wp-content/uploads/icons/pricinglegend.png" alt="price legend" />');
		clearOverlays({});
		fillMap(currentlyShowing);


	});

	// Watch and change the area displayed based on the choice from the select box.
	$('select#neighborhood').change(pilotAreaJumper);
	pilotAreaJumper();

	// This handles the click on results.  Highlight clicked item, and pan the map over to the marker they selected.
	$('.results').live('click', function() {
		var pointIndex = $(this).attr('index');
		var location = getSpotLocation(markersArray[pointIndex]['marker']);
		// Looking at a highlighting option...
		if(circlemarker){
			circlemarker.setMap(null);
		}
		map.panTo(location);
		if(map.getZoom() < zoomLevel){
			map.setZoom(zoomLevel);
		}
		var idToScroll = '#i-' + pointIndex;
		//c(z[pointIndex]);
		$('#f div').removeClass('activeDetails');
		$(idToScroll).addClass('activeDetails');
		$('#f').scrollTo(idToScroll,{duration:750,easing:'swing'});
		//c($('#f' + idToScroll).text());
		circlemarker  = new google.maps.Circle({
			center: location,
			map:map,
			radius:5,
			strokeColor:'#008CDF',
			strokeOpacity:0.6,
			strokeWeight:1,
			fillColor:'#008CDF',
			fillOpacity:0.2
		});
	});
	
	google.maps.event.addListener(map, 'zoom_changed', function() {
		// Make sure the garage's markers are properly sized.
		clearOverlays({eraseCircle:true});
		fillMap(currentlyShowing);
  });
});

// Scroll the map to the selected pilot area
function pilotAreaJumper() {
	var jumpLocation = $('#neighborhood').val();
	map.panTo(citySections[jumpLocation]['position']);
	map.setZoom(citySections[jumpLocation]['zoom']);
	if(jumpLocation == 'city'){
		$('#f').scrollTo(0,{duration:750,easing:'swing'});//scrollTo top here. The top of the div should have the intro/howto language.
	} 
}

// Populate structures with returned parking information.
function prepareData(data,status){
	//var status = data['STATUS'];
	var numberOfItems = data['NUM_RECORDS'];
	var availlist = data['AVL'];
	var locations = [];
	var nw = [];
	var se = [];
	var details;
	var dataArea = [];
	dataTimeStamp = data['AVAILABILITY_UPDATED_TIMESTAMP'];
	$('#f').empty();
	var listLen = data['AVL'].length;
	var item = 0;
	for(; item < listLen; item++){
		locations = data['AVL'][item]['LOC'].split(',');
		if(data['AVL'][item]['TYPE'] == 'ON'){
			nw = [locations[1],locations[0]];
			se = [locations[3],locations[2]];
		}else{
			nw = [locations[1],locations[0]]; // Garages return only one point, the main entrance.
			se = nw;
		}
		dataArea.push(new google.maps.LatLng(nw[0],nw[1]));
		dataArea.push(new google.maps.LatLng(se[0],se[1]));
		var used =  parseInt(data['AVL'][item]['OCC']);
		var capacity = parseInt(data['AVL'][item]['OPER']);
		var avail = capacity - used;
		if(capacity == 0 || isNaN(capacity)){
			availpercent = 0;
		}else{
			availpercent = Math.round(((avail/capacity) * 100) * 10)/10;
		}

		usedpercent = 100 - availpercent;

		if(avail < 2 && avail > 0 && !isNaN(avail) && availpercent != 0 && capacity <= 3){
			if(availpercent <= 15){
				usedpercent = -57; // less than 15 percent available. hack
			} else{
				usedpercent = -58; // more than 15 percent available. hack
			}
		} else if(capacity == 0  && used == 0 && data['AVL'][item]['TYPE'] == 'ON'){
			usedpercent = -42; // On street parking, force it to red as capacity is zero
		}
		if (used > capacity && data['AVL'][item]['TYPE'] == 'OFF'){ // Indication that the garage's icon should be grey.
			usedpercent = -1;
		}
		if(isNaN(capacity) || used < 0 || capacity < 0){
			usedpercent = -1;  //flag for grey
		}
		details = buildinfo(data['AVL'][item],item);
		z.push({
			details:details,
			dataArea:dataArea,
			capacity:capacity,
			availability:avail,
			usedpercent:usedpercent,
			rates:data['AVL'][item]['RATES'],
			type:data['AVL'][item]['TYPE']
		});
		dataArea = [];
	}
	fillDetails();
	fillMap('availability');
}

// Display the detailed descriptions into the console (#f) area.
function fillDetails(){
	var i = z.length;
	var longstring=[];
	while(i--){
		//$("#f").append(z[i]["details"]); // That is really slow.
		// Prefer +=, but joining an array is fast for IE.
		// http://stackoverflow.com/questions/153381/javascript-string-concatenation-faster-than-this-example
		longstring[longstring.length] = (z[i]["details"]);
	}
	$("#f").html(introMessage + longstring.join(""));
}

//Fill the map's contents with polylines, markers, etc.
function fillMap(typeOfMap){
	var details,dataArea,usedpercent,typeOfData,segment,color,marker,image;
	var numItems,i;
	if(typeof typeOfMap === 'undefined'){
		typeOfMap = 'availability';
	}
	numItems = z.length ? z.length : 0;
	for(i = 0; i < numItems;i++){
		details = z[i]['details'];
		dataArea = z[i]['dataArea'];
		usedpercent = z[i]['usedpercent'];
		typeOfData = z[i]['type'];
		segment = usedpercent;
		//c(usedpercent);
		//c(z[i]);

		if(typeOfData == 'ON'){
			// On street parking. Create a polyline.
			if(typeOfMap == 'price'){
				if(typeof z[i]['rates'] === 'undefined'){
					segment = -1;
				}else{
					segment = rateFinder(z[i]['rates'],z[i]);
				}
			} else if(typeOfMap == 'availability'){
				if(isNaN(segment)){
					segment = -42;
				} else if(segment > 100){
					segment = -1;
				}
			}
			color = segmentColorizer(segment,typeOfMap);
			marker  = new google.maps.Polyline({
				path: dataArea,
				map:map,
				strokeColor:color,
				strokeOpacity:0.8,
				strokeWeight:(map.getZoom() < 14) ? 4 : 7,
				fillColor:color,
				fillOpacity:0.8
			});
		}else{
			// Parking garage. Create a marker.
			image = garageIcon(segment,typeOfMap,z[i]['rates']);
			marker = new google.maps.Marker({
				position: dataArea[0],
				map: map,
				//title:availpercent.toString(),
				icon:image
			});
		}
		markersArray.push({marker:marker,index:i});
		selectionPanListener(marker,i,details);
	}
}

// return a lat/long to panTo.  Different based on whether the datastructure represents a garage single point or on street two points.
function getSpotLocation(location){
	var n,m;
	var theLocation;
	try{
		// Find the midpoint of the two given points for a blockface.
		m =  location.getPath()['b'][0];
		n =  location.getPath()['b'][1];
		theLocation = new google.maps.LatLng((m.lat() + n.lat()) / 2.0, (m.lng() + n.lng()) / 2.0);
	} catch(e){
		theLocation =  location['position'];
	}
	return theLocation;
}

// get rid of all markers
function clearOverlays(opts){
	var i;
	var erase;
	if(markersArray){
		i = markersArray.length;
		while(i--){
			markersArray[i]['marker'].setMap(null);
		}
	}
	//opts = typeof(opts) == 'undefined' ? opts : null;
	//var erase = (opts.hasOwnProperty('eraseCircle')) ? opts['eraseCircle'] : false;
	erase = (typeof opts['eraseCircle'] == 'boolean') ? opts['eraseCircle'] : false;
	if(erase && circlemarker){
		circlemarker.setMap(null);
	}
}

//Create listener for map markers
function selectionPanListener(marker, number, message) {
	google.maps.event.addListener(marker, 'click', function() {
		$('#i-' + number).click(); // trigger the map panTo, and results highlighting
	});
}

// console log function.
function c(f){
	//console.error(f); // error to have it show up on iphone/iphad
	try { console.log(f) } catch (e) { alert(f) }
}

//join convience method.
function S() {
	return Array.prototype.join.call( arguments, '' );
}

// Return a url to an appropriate icon image based upon availability bucket.
function garageIcon(amount,iconType,details){
	//amount is 'amount available'
	iconType = iconType.toLowerCase();
	var location = '/wp-content/uploads/icons/';
	var useTiny = (map.getZoom() <= (zoomLevel - 2)) ? true : false;
	if(iconType == 'availability'){
		// lookup code: mapping availability % to specific icon name.
		if(amount > 85){
			location += 'p_red';
		} else if(amount <= 85 && amount >= 70){
			location += 'p_lightblue';
		} else if(amount < 70 && amount >= 0){
			location += 'p_darkblue';
		} else if(amount == -1 || amount == -2){
			location += 'p_grey';
		} else {//dead branch ?
			location += 'p_grey';
		}
	}else if(iconType == 'pricing' || iconType == 'price'){
		//price = rateFinder(z[i]['rates']);
		price = rateFinder(details);
		//c('Found garage price is: '+ price );
		//c(details);
		if(price >= 4.01){
			location += 'p_darkgreen';
		} else if(price >= 2.01 && price < 4.01){
			location += 'p_midgreen';
		} else if(price < 2.01 && price >= 0.00){
			location += 'p_lightgreen';
		} else {
			location += 'p_grey';
		}
	}
	if(useTiny){
		location += '_tiny.png';
	} else {
		location += '_small.png';
	}
	return location;
}

// Format the time information.
function timeParse(data){
//	return data.hasOwnProperty('TO') ? S('From: ',data['FROM'],' to ',data['TO'],' ',data['BEG'],' - ',data['END'],'<br />') :S('On: ',data['FROM'],' ',data['BEG'],' - ',data['END'],'<br />');
	return (typeof data['TO'] == 'string') ? S('',data['FROM'],' to ',data['TO'],' ',data['BEG'],' - ',data['END'],'<br />') :S('',data['FROM'],' ',data['BEG'],' - ',data['END'],'<br />');

}

// Setup google maps.
function initialize() {
	var latlng = new google.maps.LatLng(sfLocation['lat'], sfLocation['lng']); // "centered" on SF
	var opts = {
		zoom: 14,
		center: latlng,
		streetViewControl: false,
		zoomControl: true,
		zoomControlOptions: {
			style: google.maps.ZoomControlStyle.SMALL,
			position: google.maps.ControlPosition.TOP_LEFT
		},
		panControl: false,
		mapTypeControl: false,
		scaleControl: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	map = new google.maps.Map(document.getElementById("map_canvas"),opts);
}

// parse rate data and match it to an array of hours of the day filled with the price for that hour.
function rateFinder(therates,meta){
	var theRate = -2;
	var rates  = (typeof therates['RS'] == 'object') ? therates['RS'] : [];
	var ratesLength = rates.length;
	var currentDate = new Date();
	// Safari can't make a valid date from the returnedDate string
	//var returnedDate = new Date(dataTimeStamp);
	var startDate,endDate;
	var hours, minutes;
	var seconds = 0;
	var index = 0;
	if(typeof rates['RQ'] == 'string'){
		if(rates['RQ'].toLowerCase().search('see meter') != -1){
			// No pricing information returned.
			return theRate;
		}
	}
	// Certain garages don't send hourly rates. Handle this.

	rate = (typeof rates[0]['DESC'] == 'string') ? rates[0]['DESC'] : '';
	//	if(rates[0].hasOwnProperty('DESC')){
		//if(rates[0]['DESC'].toLowerCase().search('incremental') != -1){
		if(rate.toLowerCase().search('incremental') != -1){
			rate = typeof rates[0]['RATE'] =='string' ? rates[0]['RATE'] : '-1';
			return parseFloat(rate);
		}
	//	}
	while(index < ratesLength){

		start = 	typeof rates[index]['BEG']  =='string' ? rates[index]['BEG']  : '0:0';
		finish = 	typeof rates[index]['END']  =='string' ? rates[index]['END']  : '0:0';
		rate = 		typeof rates[index]['RATE'] =='string' ? rates[index]['RATE'] : '0:0';

		if(start.search('AM') != -1){
			hours = start.split(':')[0];
			minutes = start.split(':')[1].split(' ')[0];
			if(hours == 12){
				hours -= 12;
			}
		} else {
			hours = Number(start.split(':')[0]);
			if(hours != 12){
				hours += 12; // Add 12 for 24 hour time
}
			minutes = start.split(':')[1].split(' ')[0];
		}
		startDate = new Date(currentDate.getFullYear(),currentDate.getMonth(),currentDate.getDate(),hours,minutes,seconds,0);


		if(finish.search('AM') != -1){
			hours = finish.split(':')[0];
			minutes = finish.split(':')[1].split(' ')[0];
			if(Number(hours) == 12){
				// Server-side return data bug. Rather than returning '11:59 PM' it returns '12:00 AM' which is in the past.
				hours = 23;
				minutes = 59;
				seconds = 59;
			}
		} else {
			hours = Number(finish.split(':')[0]);
			if(hours != 12){
				hours += 12; // Add 12 for 24 hour time since we're in PM.
			}
			minutes = finish.split(':')[1].split(' ')[0];

	    endDate = new Date(currentDate.getFullYear(),currentDate.getMonth(),currentDate.getDate(),hours,minutes,seconds,0);
		}

		if(currentDate >= startDate && currentDate <= endDate){
			// In the current time band, so return the rate for this time period.
			if(rates[index]['RQ'].toLowerCase().search('per hour') != -1){
				theRate =  parseFloat(rate);
				return theRate;
			}else if(rates[index]['RQ'].toLowerCase().search('no charge') != -1){
				theRate =  0;
			}else{
				theRate = -1;
			}
		}else{
			// The currentDate isn't between the start and end dates.
		}
		index++;
	}

	return theRate;
}

// parse rate data and build a textual representation of it.
function parseRates(data){
	var ratelist = '';
	var ratestructure,items,len,notes,rate,startTime,endTime,amount;
	if(typeof data['RATES'] === 'object'){
		ratestructure = data['RATES'];
		if(typeof ratestructure['RS'] === 'object'){
			items = ratestructure['RS'];
			len = items.length;
			if(data['TYPE'] == 'ON' && items['RQ'] == 'See Meter'){ // On street parking, special data format...
				return S('<span class="rateQualifier">',items['RQ'],'</span><div style="clear:both;"></div>');
			}
			for(i = 0; i < len; i++ ){
				notes;
				rate;
				startTime='';
				endTime='';
				if(typeof items[i]['DESC'] === 'string'){ 
					notes = S('<span class="rateQualifier">',items[i]['DESC'],'</span> '); 
				} else{
					notes = '';
				}
				if(items[i]['RATE'] == 0){
					rate = S("<span class='rateQualifier'>",items[i]['RQ'], "</span><div class='clear'></div>"); // if the Rate is 0, display the rate qualifier (RQ) as the message. It will be something like, "See meter", "No charge", etc.
				} else {
					amount = prettifyRate(items[i]['RATE']);
					rate = S("<span class='rateQualifier'>", amount," ",items[i]["RQ"],"</span><div class='clear'></div>");
				}
				if(typeof items[i]['BEG'] == "string"){
					startTime = S("<span class='rateTimes'>",items[i]['BEG']," - ");
				}else{
					startTime = '';
				}
				if(typeof items[i]['END'] == 'string'){
					endTime = S(items[i]['END'],'</span> ');
				}else{
					endTime = '';
				}
				ratelist += S(startTime, endTime, notes, rate);
			}
		}
	}
	return ratelist;
}

// Add nicer currency formatting to the given value.
function prettifyRate(uglyRate){
	var i = parseFloat(uglyRate);
	if(isNaN(i)) {
		i = 0.00;
	}
	i = Math.abs(i);
	i = parseInt((i + 0.005) * 100);
	i = i / 100;
	s = new String(i);
	if(s.indexOf('.') < 0){
		s += '.00';
	}
	if(s.indexOf('.') == (s.length - 2)){
		s += '0';
	}
	return "$ " + s;
}

// Gradient style color lookup. (Obselete, switched to bucket type coloring.)
function colorFinder(amountUsed) {
	var r,g,fill;
	r = Math.round((amountUsed/150)*254).toString(16);
	g = Math.round(Math.abs(220 - (amountUsed*2.55))).toString(16);
	if(r.length == 1){ r = '0'+r;}
	if(g.length == 1){ g = '0'+g;}
	fill = '#'+r+g+'00';
	return fill;
}

// Determine and return the proper bucket color (rgb) for the inputs...
function segmentColorizer(amountUsed,typeOfColoring) {
	var r,g,b,fill;
	r = '8D';
	b = '8D';
	g = '8D';
	
	//Default typeOfColoring to availability.
	if(typeOfColoring.toLowerCase() == 'availability'){
		if(amountUsed > 85  || amountUsed == -42){
			//Full | low availability 
			r = 'fd';
			g = '2c';
			b = '27';
		} else if(amountUsed <= 85 && amountUsed >= 70){
			//middle usage 
			r = '00';
			g = '3c';
			b = '58';
		} else if(amountUsed < 70 && amountUsed >=0){
			//low usage  | high availability 
			r = '10';
			g = 'ca';
			b = 'fb';
		}
		// YUCK!
		if(amountUsed == -57){
			// less than 15% available
			//red
			r = 'fd';
			g = '2c';
			b = '27';
		}else if(amountUsed == -58){
			//light blue
			//force medium availability coloring mode
			r = '00';
			g = '3c';
			b = '58';
		}
	}else if(typeOfColoring.toLowerCase() == 'price' || typeOfColoring.toLowerCase() == 'pricing'){ 
		// Return color scheme for the pricing legend color set.
		if(amountUsed > 4){
			// 'expensive' price
			r = '1f';
			g = '4a';
			b = '1f';
		} else if(amountUsed <= 4 && amountUsed > 2.0){
			// "mid-range" price band
			r = '1c';
			g = '74';
			b = '1e';
		} else if(amountUsed <= 2.0 && amountUsed >= 0){
			// "cheap" price band
			r = '00';
			g = 'da';
			b = '02';
		}
	}
	if(amountUsed == -1){ //grey...
		fill = '#8d8d8d';
	}else{
		fill = '#'+r+g+b;
	}
	return fill;
}

// Parse through data and build a textual representation of it.
function buildinfo(theData,index){

	var address = '';
	var intersection = '';
	var telephoneLine,workingtel,blockface,parkingtype,used,capacity;
	var availabilityMessage,image,avail,usedpercent,rates,hours,hourDetails;
	var operationalhours,len,namesplit,name,locations;
	locations = theData["LOC"].split(",");
	if(typeof theData["DESC"] == "string"){
//		address = S("<span class='itemHeading itemHeadingAddress'>Address:</span> ", theData["DESC"], "<div class='clear'></div>");
		address = S(theData["DESC"], "<div class='clear'></div>");
	}
	if(typeof theData["INTER"] == "string"){
		intersection = S("(", theData["INTER"] , ")" , "<div class='clear'></div>");
	}
	if(typeof theData["TEL"] == "string"){
		telephone = theData["TEL"];
		workingtel = telephone.replace("(","");
		workingtel = workingtel.replace(")","");
		workingtel = workingtel.replace(" ","");
		workingtel = workingtel.replace("-","");
//		telephoneLine = S("<span class='itemHeading itemHeadingTelephone'>Telephone:</span><a href=tel:'",workingtel,"'>", telephone,"</a><div class='clear'></div>");
		telephoneLine = S("<a href=tel:'",workingtel,"'>", telephone,"</a><div class='clear'></div>");
	} else{
		telephoneLine = '';
	}
	blockface = theData['BFID'];
	parkingtype = theData['TYPE'];
	used =  theData['OCC'];
	capacity = theData['OPER'];
	avail = capacity - used;
	if(capacity == 0 || capacity < 0){
		availpercent = 0;
		avail = 0;
	}else{
		availpercent = Math.round(((avail/capacity) * 100) * 10)/10;
	}
	usedpercent = 100 - availpercent;
	rates = S("<div class='rates' >",parseRates(theData),"</div>");
	hours = '';
	hourDetails = '';
	
	if(typeof theData["OPHRS"] == "object" && typeof theData["OPHRS"]["OPS"] == "object"){
		operationalhours =  theData["OPHRS"]["OPS"];
		len = operationalhours.length;
		for(x=0; x < len;x++){
			hours += timeParse(operationalhours[x]);
		}
		if(hours == ""){
			hourDetails = '';
		} else {
			hourDetails = S("<span class='itemHeading itemHeadingHours'>Hours:</span>","<div class='hours'>",hours,"</div>");
		}
	}
	if(typeof used == "string" && typeof capacity == "string"){
		if((used == 0 && capacity == 0) || avail < 0){
			availabilityMessage = '';
			image = '';
		} else {
			availabilityMessage = "<div class='clear'></div><span class='itemHeading itemHeadingAvail'>Estimated Availability: </span>";
			availabilityMessage += S("<span class='availabilityNumber'>",avail," of ", capacity, " spaces</span><div class='clear'></div>");
			var dimensions = 48;
			//image = S("<img src='http://chart.apis.google.com/chart?cht=p&chs=",dimensions,"x",dimensions,"&chd=t:",usedpercent,",",availpercent,"&chco=FF0000|00FF00&chf=bg,s,00000000' alt='",usedpercent.toFixed(2),"' title='",usedpercent.toFixed(2),"% used' class='utilizationpie' />");
		}
	} else {
		availabilityMessage = '';
		//image = '';
	}
	namesplit = theData["NAME"].split("(");
	if(namesplit.length < 2){
		name = {street:namesplit[0],numbers:null};
	} else {
		name = {street:namesplit[0],numbers:namesplit[1].replace(")","")};
	}
	return S(
		"<div class='results' id='i-", index, "' index='",index,"' onclick=''>",
		"<span class='itemHeading itemHeadingStreet'>",name["street"], "</span><span class='blockNumbers'>", name["numbers"], "</span>",
		address,
		intersection,
		telephoneLine,
		availabilityMessage,
		//image, // Availability piechart.  This really slows down the page load.
		"<div class='clear'></div><span class='itemHeading itemHeadingRates'>Rates:</span>", rates,
		hourDetails,
		//"<span class='debug' style='text-decoration: line-through;'> [ Blockface ID] :", blockface,"</span>",
		//"<span class='debug' style='text-decoration: line-through;'> [ ", theData["OCC"],"]</span>",
		"</div>");
}

