
// Super class: Place
//    just the location (lat,lng)
//    and a name
//    subclasess are CampusPlace and StreetPlace
function Place( lat, lng, name, desc )
{
    this.lat = lat;
    this.lng = lng ;
    this.name = name;
    this.desc = desc
}

Place.prototype.isLocationKnown = function()
{
    return ( this.lat && this.lng )
}

Place.prototype.hasFeature = function( featureType )
{
    return ( this.tabbedInfo && this.tabbedInfo[featureType] && (this.tabbedInfo[featureType] != null ) )
//           && (this.tabbedInfo[featureType] != "No food at this location."));
          return this.tabbedInfo.available[featureType];
}

Place.prototype.getGLatLng = function()
{
    if ( this.isLocationKnown() )
    {
        return new GLatLng( this.lat, this.lng );
    } else {
        alert("Trying to get GLatLng when we don't know the coordinates!"); // TODO remove this after done testing
        return null;
    }
}

Place.prototype.centerOnMe = function()
{
    if ( this.isLocationKnown() )
    {
        map.panTo( this.getGLatLng() );
    }
}

// TODO need other parameters here maybe?
//      text
//      icon settings
Place.prototype.addMeToGMap = function( gmap, extraPopupText, placeType )
{
    if ( ! this.isLocationKnown() )
    {
        return null ;
    }
    if (! this.marker )
    {
//         placeType = (placeType && placeType != "" ) ? placeType : "building";
        this.marker = new GMarker( this.getGLatLng(), {icon:(new GIcon(G_DEFAULT_ICON, this.hasFeature('food') ? allPlaceTypes['food'].icon : allPlaceTypes[placeType].icon))} );
    }

    // TODO need some kind of code to manage the markers that have been added to map
    // so that we don't add another marker with exactly the same lat/long
    // note: this is now taken care of by attaching the markers to the objects
    // in the allPlaces array ( allPlaces[i].marker = new blah blah blah )
//     var popupText  = extraPopupText;
//     if (this.type == "building")
//     {
//         popupText += 
//             this.code 
//                 ? ( 
//                     '<br/>Building information: <a href="' 
//                     + "http://www.utexas.edu/maps/main/buildings/" 
//                     + this.code.toLowerCase()
//                     +".html" 
//                     + '" target="_new">' + this.code.toUpperCase() + '</a>'
//                 ) 
//                 : "";
//     }
//     popupText += this.desc ? ( "<br/>" + this.desc ) : "";
        
    var handler = createMarkerClickHandler(  this, extraPopupText, placeType );

    GEvent.clearListeners( this.marker, "click" );
    GEvent.addListener(this.marker, "click", handler );

    map.addOverlay( this.marker );
}

// subclass of Place
//    extra properties: 
//      buildingcode
// CampusPlace.prototype = new Place();
subclass( CampusPlace, Place );

// CampusPlace.prototype.superclass = Place;
// function CampusPlace( buildingCode )
// {
// }
// 
function CampusPlace( point )
{
    // we have a name and a location
    // create the Place from the info in point (
    if ( point.name && point.lat && point.lng  )
    {
        if (!point.desc) { point.desc = ""; }
        this.tabbedInfo = { 
            "building" : "" ,
//             "food" : "",
//             available:{"food":false},
           
        };
        if (!point.tabbedInfo || !point.tabbedInfo["food"] )
        {
//             if ( point.type != "garage" )
//                 this.tabbedInfo["food"] = "No food at this location";
        }
        else
        {
//             this.tabbedInfo.available["food"] = true;
            this.tabbedInfo["food"] = point.tabbedInfo["food"];
        }
//         this.tabbedInfo["food"] += '<br/><a href="javascript:showNearbyPlaces(' 
//              + point.lat + ',' + point.lng 
//              + ', maxNearbyDist, \'food\');">'
//              + 'Show nearby food</a>';

        this.tabbedInfo["building"] = '<h3>' + point.name + '</h3>';
        if (point.code) {
            this.tabbedInfo["building"]  +=
                 '<a href="' 
                + "http://www.utexas.edu/maps/main/buildings/" 
                + point.code.toLowerCase()
                +".html" 
                + '" target="_new">' 
                + '<img width="174" height="152" src="bldgPics/' + point.code.toLowerCase() + '.gif" >'
                + '</a>'
                + '<br/>';
        }

        if ( point.tabbedInfo && point.tabbedInfo["building"] )
        {
//             this.tabbedInfo["building"] = point.tabbedInfo["building"];
        }

        if (point.desc)
        {
            this.tabbedInfo["building"] += 
                '</br>' 
                + point.desc
                + '</br>';
                + '</br>';
        }

        if (point.code) {
            this.tabbedInfo["building"] += 
                          '<a href="' 
                        + "http://www.utexas.edu/maps/main/buildings/" 
                        + point.code.toLowerCase()
                        +".html" 
                        + '" target="_new">' 
                        + 'Official page for ' + point.code 
                        + '</a>';
        }

        this.tabbedInfo["building"] += 
            '<br/><a href="javascript:showNearbyPlaces(' 
            + point.lat + ',' + point.lng 
            + ', maxNearbyDist, \'building\');">'
            + 'Identify nearby buildings</a>' ;


        Place.call( this, point.lat, point.lng, point.name, point.desc );
        this.code = point.code  ? point.code : null;
        this.type = point.type  ? point.type : "building";
    } 
    // has name, no location
    else if ( point.name && (!point.lat || !point.lng) )
    {
        return null;
    }
    // search allPlaces by code
    else if (point.code && point.code != null && point.code != "") 
    {
        // search through list of buildings for the given code
        //  then take that buildings lat, lng, other data and initialize this objects instance variables
        for (var i=0; i< allPlaces.length; i++)
        {
            if (allPlaces[i].code == point.code)
            {
//             if (( buildingCode != "") && (buildingCode != null ) && (allPlaces[i].code == buildingCode ) )
                if ( false )
                {
                    var name = allPlaces[i].name;
                    var lat  = allPlaces[i].lat;
                    var lng  = allPlaces[i].lng;
                    var desc = allPlaces[i].desc;
                    Place.call( this, lat, lng, name, desc );
                    this.code = point.code;
                    this.type = allPlaces[i].type;
                } else {
                    return allPlaces[i];
                }
                break;
            }
        }
    }
//     else // TODO
//     {
//     }
}

// subclass of Place
//    extra properties: 
//      street address
subclass( StreetPlace, Place );
function StreetPlace( name, streetAddress )
{
    // TODO use GMaps api to figure out lat and lng of this place
    // 
    Place.call( this, lat, lng, name )
}
 

function showSearchedBldg( )
{
    var searchStr = document.getElementById("searchbox").value;
    var found =false;
    for (var i=0; i<allPlaces.length; i++)
    {
        var code = allPlaces[i].code;
        var re = new RegExp( "^" + code , "i" );
        var results = re.exec( searchStr );
        if (results != null)
        {
            var foundPlace = allPlaces[i] ;
            if (foundPlace.isLocationKnown() ) 
            {
                foundPlace.centerOnMe();
                foundPlace.addMeToGMap(map,"", foundPlace.type );
                GEvent.trigger( foundPlace.marker, "click" );
            }
            else
            {
                softAlert("Location unknown for \"" + searchStr + "\"" );
            }
            found = true;
            break;
        }

    }
    if (!found) softAlert("Couldn't find building - " + searchStr );

}

function showNearbyPlaces( lat, lng, maxDist, type )
{

    clearAllMarkers();
    // for now, we determine "nearby" by drawing a square around the central point
    var startingPt =  new GLatLng( lat, lng );
    var nearbyPlaces = [];

    for (var i=0; i<allPlaces.length; i++)
    {
        //softAlert( "checking place #" + i );
        if ( allPlaces[i].isLocationKnown() )
        {
            var dist = startingPt.distanceFrom( allPlaces[i].getGLatLng() );

            if ( ((dist  < maxDist) && (dist > 0))
              && ( (type && (type == allPlaces[i].type))  
                 || allPlaces[i].hasFeature( type )  
               )
            )
            {
    //                 allPlaces[i].addMeToGMap(map, "" );
                nearbyPlaces.push( allPlaces[i] );
            } else if (dist == 0) {
                // remove then re-add the marker that's the center of our search
                // doing this to get the info window off the screen ... 
                // probably a better way, but this does the trick
                map.removeOverlay( allPlaces[i].marker );
                map.addOverlay( allPlaces[i].marker );
                allPlaces[i].centerOnMe();
    //                 GEvent.trigger( new GPoint( 0,0), /* allPlaces[i].marker, */ "click" );
            }
        }
    }
    // TODO remove this debug message .. or convert to something friendlier
    var message = "Found " + nearbyPlaces.length + " nearby places: "
    for (var i=0; i<nearbyPlaces.length; i++) { message += nearbyPlaces[i].code + " : " ; }

    softAlert( message );
    for (nearbyIndex=0; nearbyIndex<nearbyPlaces.length; nearbyIndex++)
    {
        nearbyPlaces[nearbyIndex].addMeToGMap( map, "" , type);
    }
}
