<?php
require_once 'GeocodingHelper.php';
XN_Application::includeFile('alphacomponents','/Alpha/Services/Google/Maps.php');

/**
 * This class contains static methods that help with creating a Google Map.
 *
 * @author Jonathan Aquino
 */
class GoogleMapsHelper {

    /**
     * Outputs the HTML for a Google Map, with a marker for the given subject.
     * @param XN_Content $subject Content object with latitude and longitude attributes
     * @param integer $width width of the map; for example, 300px
     * @param integer $height height of the map; for example, 300px
     */    
    public static function displayGoogleMap($subject, $width, $height) {
        if (! GoogleMapsHelper::ensureLatitudeAndLongitudeSet($subject)) { return; }
        $map = GoogleMapsHelper::createMap($width, $height);
        $map->setMapLocation($subject->my->longitude, $subject->my->latitude);
        GoogleMapsHelper::addMarker($subject, $map);  
        $map->injectJavascript("map.setMapType(map.getMapTypes()[".Config::$mapType."]);");
        $map->display();         
    }

    /**
     * Outputs the HTML for a Google Map, with markers for the given array of subjects.
     * @param array $subjects XN_Content objects with latitude and longitude attributes
     * @param integer $width width of the map; for example, 300px
     * @param integer $height height of the map; for example, 300px
     * @param string $extentURL A Google Maps URL representing the bounding box of the map on the front page. Must contain "ll=".
     */    
    public static function displayGoogleMapForArray($subjects, $width, $height, $extentURL) {
        $map = GoogleMapsHelper::createMap($width, $height);
        $map->setFromUrl($extentURL);
        foreach ($subjects as $subject) {
            if (GoogleMapsHelper::ensureLatitudeAndLongitudeSet($subject)) {
                GoogleMapsHelper::addMarker($subject, $map);
            }
        }        
        $map->injectJavascript("map.setMapType(map.getMapTypes()[".Config::$mapType."]);");
        $map->display();
    }
    
    /**
     * Set the subject's latitude and longitude attributes based on its street address (description attribute)
     * and city and state (developer attributes). Caching the latitude and longitude in this way avoids unnecessary
     * lookups, which can be slow. 
     * @param XN_Content $content Content object to update
     * @return boolean whether the latitude and longitude was determined
     * @author Jonathan Aquino
     */
    public static function ensureLatitudeAndLongitudeSet($content) {
        if ($content->my->latitudeAndLongitudeFound == null) {
            try {
                $geocoderResult = GeocodingHelper::geocode($content->description.", ".$content->my->city.", ".$content->my->state);                
                $content->my->add('latitude', $geocoderResult['lat'], XN_Attribute::NUMBER);                  
                $content->my->add('longitude', $geocoderResult['long'], XN_Attribute::NUMBER);                  
                $content->my->latitudeAndLongitudeFound = 'Y';
            } catch (XMLRPCException $e) {   
                // Don't set latitudeAndLongitudeFound, so it gets tried again next time. [Jon Aquino 2005-09-08]             
                return false;
            } catch (Exception $e) {
                $content->my->latitudeAndLongitudeFound = 'N';
            }
            $content->save();
        }
        return $content->my->latitudeAndLongitudeFound == 'Y';
    }    

    private static function createMap($width, $height) {
        $map = new XNC_Alpha_Services_Google_Maps(Config::$googleMapsAPIKey, array(
            'mapWidth' => $width, 
            'mapHeight' => $height,            
            'controls' => 'SmallZoom,MapType'));
        return $map;
    }
    
    private static function addMarker($subject, $map) {
        $map->addMarker($subject->my->longitude, $subject->my->latitude, GoogleMapsHelper::bubble($subject));    
    }

    private static function bubble($subject) {
        $tags = XN_Query::create('Tag_ValueCount')
            ->filter('content.id','=',$subject->id)
            ->order('valuecount','desc')
            ->end(3)->execute();        
        $tagsHTML = HTMLHelper::tagLinkList($tags, 'list.php?tag=%s');
        $urlencodedContributorName = urlencode($subject->contributorName);
        $containerTypeName = ucfirst(Config::$container);
        $containerForHTML = $subject->my->h(Config::$container);
        $containerForURL = $subject->my->urlencode(Config::$container);
        $html =<<<_HTML_
            <a class="gmapsSubjectName" href="subject.php?SubjectID={$subject->id}">
			{$subject->h('title')}</a><br />
            {$subject->h('description')}<br />
            {$containerTypeName}: <a href="list.php?container={$containerForURL}">{$containerForHTML}</a><br />
            Tags: ${tagsHTML}<br />
            Contributed by <a class="user" href="list.php?user={$urlencodedContributorName}">{$subject->h('contributorName')}</a>    
_HTML_;
        return str_replace("\r", "", str_replace("\n", "", $html));
    }

}
