<?php

require_once('View.interface.php');
class View implements iView
{
	private $output;

	public function getInputPage($error = false)
	{
		$this->output = $this->buildHeadOpen();
		$this->output .= $this->buildHeadClose();
		$this->output .= $this->buildBodyOpen();
		$this->output .= $this->buildBodyForm(true);
		$this->output .= $error;
		$this->output .= $this->buildBodyClose();

		return $this->output;
	}	

	public function getMapPage($range, $coordinates, $polyline, $statistics, $mean, $variance, $addresses, $radius, 
		$timeperiod, $daytype, $weathertype, $mintrafficseverity)
	{
		$this->output = $this->buildHeadOpen();
		$this->output .= $this->buildHeadIEFix();

		if(isset($coordinates[1]))
		{
			$this->output .= $this->buildHeadJS($range,
				(float)($range['Min_lat'] + ($range['Max_lat'] - $range['Min_lat'])/2.0), 
				(float)($range['Min_lon'] + ($range['Max_lon'] - $range['Min_lon'])/2.0),
				$statistics, $mean, $variance, $coordinates);
		}
		else
		{
			$this->output .= $this->buildHeadJS($range, $coordinates[0]['lat'], 
				$coordinates[0]['lon'], $statistics, $mean, $variance);
		}
		$this->output .= $this->buildHeadClose();
		$this->output .= $this->buildBodyOpenJS();
		$this->output .= $this->buildBodyJS(DEFAULT_MAP_HEIGHT, DEFAULT_MAP_WIDTH);
		$this->output .= $this->buildBodyLegend($mean, $variance, $addresses, $radius, $timeperiod,
			$daytype, $weathertype, $mintrafficseverity);
		$this->output .= $this->buildBodyClose();

		return $this->output;
	}

	private function buildHeadOpen()
	{
		return '
			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
			"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
			<html xmlns="http://www.w3.org/1999/xhtml">
			<head>
			<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
			<title>'.BROWSER_TITLE.'</title>';
	}

	private function buildHeadIEFix()
	{
		return '
			<style type="text/css">
			v\:* {
				behavior:url(#default#VML);
			}
			</style>';
	}

	private function buildHeadJS($range, $lat, $lon, $statistics, $mean, $variance, $coordinates = "")
	{
		$output = sprintf('<script src="http://maps.google.com/maps?file=api&v=2&key=%s"
			type="text/javascript"></script>', GOOGLE_KEY);
		$output .= '
				<script type="text/javascript">
				//<![CDATA[

				function load() {
					if (GBrowserIsCompatible()) {
						var map = new GMap2(document.getElementById("map"));
				';
		$output .= $this->buildHeadCenterJS($lat, $lon, $range);
		$output .= $this->buildHeadControlJS();

		if(!empty($coordinates))
		{
			$output .= $this->buildHeadPolyLineJS($coordinates);
		}
		
		$output .= $this->buildHeadIconsJS();
		$output .= $this->buildHeadMarkersJS($statistics, $mean, $variance);		
		$output .= '
					}	
				}

				//]]>
				</script>';

		return $output;
	}

	private function buildHeadPolyLineJS($coordinates)
	{
		// encoded polylines don't work, have to use regular polylines
		/*
		return '
			var encodedPolyline = new GPolyline.fromEncoded({
				color: "#0000A0",
				weight: 10,
				points: "'.$polyline.'"
				levels: "BBB",
				zoomFactor: 32,
				numLevels: 4
			});
			map.addOverlay(encodedPolyline);
		';
		*/

		$output = '
			var polyline = new GPolyline([
		';

		for($i = 0; $i < count($coordinates); $i++)
		{
			$output .=  '
				new GLatLng('.$coordinates[$i]['lat'].', '.$coordinates[$i]['lon'].'),
			';
		}

		$output .= '
			], "#0000F0", 10);
			map.addOverlay(polyline);
		';

		return $output;
	}

	private function buildHeadIconsJS()
	{
		return '
			var baseIcon = new GIcon();
			baseIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
			baseIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
			baseIcon.iconSize = new GSize(12, 20);
			baseIcon.shadowSize = new GSize(22, 20);
			baseIcon.iconAnchor = new GPoint(6, 20);
			baseIcon.infoWindowAnchor = new GPoint(5, 1);
			baseIcon.infoShadowAnchor = new GPoint(18, 25);
		';
	}
	
	private function buildHeadMarkersJS($statistics, $mean, $variance)
	{
		$output = '
			function createMarker(point, number, color, width, height)
			{
				var icon = new GIcon(baseIcon);
				icon.image = "http://labs.google.com/ridefinder/images/mm_20_" + color + ".png";
				icon.iconSize = new GSize(width, height);
				var marker = new GMarker(point, icon);
					GEvent.addListener(marker, "click", function() {
						marker.openInfoWindowHtml("Weight = " + number);
					});
				return marker;
			}
			';

		foreach ($statistics as &$value)
		{
			$height = "20";
			$width = "12";

			if($value[2] < $mean)
				$color = "yellow";
			else if($value[2] < 2*$mean)
				$color = "orange";
			else
				$color = "red";

			
			if($value[2] < 0.5*sqrt($variance))
			{
			}
			else
			{
				(int)$height = $height + 3*$value[2]/sqrt($variance);
				(int)$width = $width + (3/2)*$value[2]/sqrt($variance);
			}
	
			$output .= '
					var point = new GLatLng('.$value[0].','.$value[1].');
					map.addOverlay(createMarker(point, '.$value[2].',
					"'.$color.'", "'.$width.'", "'.$height.'"));
			';
		}

		return $output;
	}

	private function buildHeadControlJS()
	{
		return '
			map.addControl(new GScaleControl());
			map.addControl(new GMapTypeControl());
			map.addControl(new GSmallZoomControl());
			map.addControl(new GOverviewMapControl());
		';
	}

	private function buildHeadCenterJS($lat, $lon, $range)
	{
		return '
			map.setCenter(new GLatLng('.$lat.', '.$lon.'))
			var bounds = new GLatLngBounds(new GLatLng('.$range['Min_lat'].', '.$range['Min_lon'].'), 
				new GLatLng('.$range['Max_lat'].', '.$range['Max_lon'].'));
				map.setZoom(map.getBoundsZoomLevel(bounds));
			';
	}

	private function buildHeadClose()
	{
		return '
			</head>';
	}

	private function buildBodyOpen()
	{
		return '
			<body onLoad="javascript:enableWithinArea()">';
	}

	private function buildBodyOpenJS()
	{
		return '
			<body onLoad="load(), enableWithinArea()" onunload="GUnload()">';
	}

	private function buildBodyJS($height, $width)
	{
		return '
			<table bgcolor="lightgray">
			<tr>
			<td>
			<div id="map" style="width: '.$width.'px; height: '.$height.'px"></div>
			</td>
			<td align="right">
			'.$this->buildBodyForm().'
			</td>
			</tr>
			</table>';
	}
	
	private function buildBodyLegend($mean, $variance, $addresses, $radius, $timeperiod, $daytype, $weathertype, 
		$mintrafficseverity)
	{
		switch($timeperiod)
		{
			case "1":
				$timeperiod = "All";
				break;
			case "2":
				$timeperiod = "AM";
				break;
			case "3":
				$timeperiod = "PM";
				break;
		}
		switch($daytype)
		{				
			case "1":
				$daytype = "all days of the week";
				break;
			case "2":
				$daytype = "during weekdays";
				break;
			case "3":
				$daytype = "during weekends";
				break;
		}
		switch($weathertype)
		{				
			case "1":
				$weathertype = "all";
				break;
			case "2":
				$weathertype = "clear";
				break;
			case "3":
				$weathertype = "cloudy";
				break;
			case "4":
				$weathertype = "wet";
				break;
		}

		$output = "<br>This map shows historical traffic conditions";
		if(is_array($addresses))
			$output .= " between <b>$addresses[0]</b> and <b>$addresses[1]</b>.<br><br>";
		else
			$output .= " for a <b>$radius</b> mile radius around <b>$addresses</b>.<br><br>";
		$output .= "Search Criteria: $timeperiod hours, $daytype, $weathertype weather conditions and a minimum traffic severity of $mintrafficseverity out of 5.<br><br>";
		$output .= "Mean location weight: <b>$mean</b>, variance: <b>$variance</b>, standard deviation: <b>".sqrt($variance)."</b><br><br>";
		$output .= "Location markers are assigned weights which correspond to the combined severity ratings of all incidents at that location.<br>";
		$output .= "Marker size and color are proportional to the weight and relative dispersion (variance), respectively, of each location.";

		return $output;
	}

	private function buildBodyForm($new = false)
	{
		$output =			'
						<script type="text/javascript" language="javascript">

						function enableWithinArea()
						{
							document.input.address1.disabled=false;
							document.input.address2.disabled=true;
							document.input.address2.value = "";
							document.input.radius.disabled=false;
							document.input.timePeriod.disabled=false;
							document.input.dayType.disabled=false;
							document.input.weatherType.disabled=false;
							document.input.minTrafficSeverity.disabled=false;
						}
 
						function enableAlongRoute()
						{
							document.input.address1.disabled=false;
							document.input.address2.disabled=false;
							document.input.radius.disabled=true;
							document.input.radius.value="";
							document.input.timePeriod.disabled=false;
							document.input.dayType.disabled=false;
							document.input.weatherType.disabled=false;
							document.input.minTrafficSeverity.disabled=false;
						}
						</script>';
		if($new)
		{
			$output .=			'
							<center><br>Welcome to the Traffic Map System.<br>
							Historical traffic analysis is available:';
		}
		else
		{
			$output .=			'New search: ';
		}
		$output .=			'
						<a href="javascript:enableWithinArea()">Within an Area</a>
						or <a href="javascript:enableAlongRoute()">Along a Route</a>
						<br><br>
						<form name="input" action="" method="POST">
						<table>
						<tr>
		<td align="right">Address:</td>	<td><input type="text" name="address1"></td>
						</tr><tr>
		<td align="right">Destination Address:</td>	<td><input type="text" name="address2"></td>
						</tr><tr>
		<td align="right">Radius:</td>	<td><input type="text" name="radius" size="3"> (miles)</td>
						</tr><tr>
		<td align="right">Time Period:</td>	<td><input type="radio" name="timePeriod" value="1" checked="checked">All 
						<input type="radio" name="timePeriod" value="2">AM
						<input type="radio" name="timePeriod" value="3">PM</td>
						</tr><tr>
		<td align="right">Day Type:</td>	<td><input type="radio" name="dayType" value="1" checked="checked">All 
						<input type="radio" name="dayType" value="2">Weekday
						<input type="radio" name="dayType" value="3">Weekend</td>
						</tr><tr>
		<td align="right">Weather Type:</td>	<td><input type="radio" name="weatherType" value="1" checked="checked">All 
						<input type="radio" name="weatherType" value="2">Clear
						<input type="radio" name="weatherType" value="3">Cloudy
						<input type="radio" name="weatherType" value="4">Precipitation</td>
						</tr><tr>
		<td align="right">Min Traffic Severity:</td>	<td><input type="radio" name="minTrafficSeverity" value="1" checked="checked">1 
						<input type="radio" name="minTrafficSeverity" value="2">2
						<input type="radio" name="minTrafficSeverity" value="3">3
						<input type="radio" name="minTrafficSeverity" value="4">4
						<input type="radio" name="minTrafficSeverity" value="5">5</td>
						</tr><tr>
						<td></td><td><input type="submit" value="Submit"></td>
						</tr>
						</table>
						</form><br>';
		if($new)
		{
			$output .=			'
							</center>';
		}

		return $output;
	}

	private function buildBodyClose()
	{
		return '
			</body>
			</html>';
	}

}

?>
