<?php
class Geocode
{
	const BING_KEY = 'AnH7JQs8drNx1p1eQBjoJ6xvq88LQ0uz1j2EN1enpMyX-61wxDxAHuB54prd7BI5';
	const GMAPS_GEOCODE_API = 'http://maps.google.com/maps/api/geocode/json?';
	const BING_GEOCODE_API = 'http://dev.virtualearth.net/REST/v1/Locations?CountryRegion=AR';
	
	private static function make_address($name)
	{
		$s=preg_replace("/[^a-zA-Z0-9,\s]/", '', $name); //removes symbols
		return urlencode(strtolower($s));
	}
	
	public static function GetBingLatLong($address, $location, &$status )
	{
		$url = self::BING_GEOCODE_API .	'&locality=' . self::make_address($location) . 
										( isset( $address ) && !empty($address) ? '&addressLine=' . self::make_address($address) : '' ) . 
										'&key=' . self::BING_KEY;
		
		$cinit = curl_init();
		curl_setopt($cinit, CURLOPT_URL, $url);
		curl_setopt($cinit, CURLOPT_HEADER,0);
		curl_setopt($cinit, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
		curl_setopt($cinit, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($cinit, CURLOPT_RETURNTRANSFER, 1);
		$response = curl_exec($cinit);
		curl_close($cinit);
		
		$res = json_decode($response);
		
		if ( isset( $res ) && isset( $res->statusCode ) )
		{
			if($res->statusDescription == 'OK')
			{
				if(isset($res->resourceSets[0]->resources[0]->point->coordinates))
				{
					$arrres = $res->resourceSets[0]->resources[0]->point->coordinates;
					
					$rres = new stdClass;
					$rres->lat = $arrres[0];
					$rres->lng = $arrres[1];
					$rres->resolver = 'bing';
					
					return $rres;
				}
				else
				{
					return FALSE;
				}
				
			}
			else
			{
				$status = $res->statusDescription;
				return FALSE;
			}
		}
		else
		{
			$status = 'geocode not responding';
			return FALSE;
		}
	}

	public static function GetGMapsLatLong($address, $location, &$status)
	{
		$url = ( isset($address) && !empty($address) ? 'address='.self::make_address($address.', '.$location) : 'address='.self::make_address($location) ) ;
		$url .= '&region=ar&sensor=false';
		
		$cinit = curl_init();
		curl_setopt($cinit, CURLOPT_URL, self::GMAPS_GEOCODE_API.$url);
		curl_setopt($cinit, CURLOPT_HEADER,0);
		curl_setopt($cinit, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
		curl_setopt($cinit, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($cinit, CURLOPT_RETURNTRANSFER, 1);
		$response = curl_exec($cinit);
		curl_close($cinit);
		
		$res = json_decode($response);
		
		if ( isset( $res ) && isset( $res->status ) )
		{
			if($res->status == 'OK')
			{
				if($res->results[0]->formatted_address)
				{
					return $res->results[0]->geometry->location;
				}
				else
				{
					return FALSE;
				}
				
			}
			else
			{
				$status = $res->status;
				return FALSE;
			}
		}
		else
		{
			$status = 'geocode not responding';
			return FALSE;
		}
	}
	
	public static function GetLatLong($address,$location, &$status)
	{
		$result = self::GetGMapsLatLong($address, $location, $status);
		
		if ( FALSE !== $result )
		{
			return $result;
		}
		else
		{
			$result = self::GetBingLatLong($address,$location, $status);
			
			if ( FALSE !== $result )
			{
				return $result;
			}
			else
			{
				$result = self::GetGMapsLatLong(NULL, $location, $status);
				
				if ( FALSE !== $result )
				{
					return $result;
				}
				else
				{
					return self::GetBingLatLong($address,$location, $status);
				}
			}
		}
	}
}
