// Google Maps 1.0 Class - Requires prototype //
// Author: James Beattie //

var Gmaps = Class.create();
Gmaps.prototype = {
  
  initialize: function( containerName ){
    
      // some default settings
      this.width = 500;
      this.height = 400;
      this.zoomLevel = 15;
      this.container = $(containerName);
      this.latitude = -33.83209212904;
      this.longitude = 151.184994183803;
      
      // other variables
      this.returnPoint = "";
      this.markerImg = "";
      this.markerWidth = 12;
      this.markerHeight = 20;
      this.markerShadow = "";
      this.markerShadowWidth = 22;
      this.markerShadowHeight = 20;
      this.avgLat = 0;
      this.avgLon = 0;
      
      // default options
      this.latlng = new google.maps.LatLng(this.latitude,this.longitude);
      this.options = {zoom: this.zoomLevel, center: this.latlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
  }, 
  
  
  showMap: function(){
    
      // prepares the container and loads a new instance of the map into it
      this.container.style.width = this.width+"px";
      this.container.style.height = this.height+"px";
      this.map = new google.maps.Map(this.container, this.options);
      //this.centerMap();
  },
  
  
  centerMap: function( gGLatLng ){
    
      // centers the map to the specified longitude and latitude
      if (gGLatLng != null) {
        this.map.setCenter(gGLatLng);
        this.map.setZoom(this.zoomLevel);
      } else {
        this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude));
        this.map.setZoom(this.zoomLevel);
      }   
  },
  
  centerByAveragePoint: function(){
      this.map.setCenter(new google.maps.LatLng(this.avgLat, this.avgLon)); 
      this.map.setZoom(this.zoomLevel);
  },
  
  geocode: function( address, functionName ){
      geocoder = new google.maps.Geocoder();
      geocoder.geocode({ 'address': address}, functionName);
  },  
  
  addMarker: function( lat, lon, html, triggerEvent, centre ){
    
      // adds a marker to the selected point and returns a reference to the marker
      var icon;
      var shadow;
      var point = new google.maps.LatLng(lat,lon);
      var marker;
      
      // store the long and lat in the overall average lon lat variables
      this.addToAvgCoords( lat, lon );
      
      // if the variable centre is set to true, we centre to the point
      if ( centre ) {
          this.map.setCenter(point);  
          this.map.setZoom(this.zoomLevel);
      }
      
      // if there is a custom icon specified, create the icon
      if ( this.markerImg.length > 0 ) {
          icon = new google.maps.MarkerImage(this.markerImg,
                                        new google.maps.Size(this.markerWidth, this.markerHeight),
                                        new google.maps.Point(0,0),
                                        new google.maps.Point(6, 20));
      
          if (this.markerShadow.length > 0) {
            shadow = new google.maps.MarkerImage(this.markerShadow,
                                              new google.maps.Size(this.markerShadowWidth, this.markerShadowHeight),
                                              new google.maps.Point(0,0),
                                              new google.maps.Point(0, 32));
          }
          
          marker = new google.maps.Marker({
            position: point,
            map: map,
            shadow: shadow,
            icon: icon
          });
      } else {
          marker = new google.maps.Marker(point);
      } 
      
      // create the infowindow for this marker
      var infowindow = new google.maps.InfoWindow({
        content: html
      });
      
      if ( triggerEvent != null ) {
          if ( triggerEvent == "now" ) {
              infowindow.open(map,marker);
          } else {
              google.maps.event.addListener(marker, triggerEvent, function() {
                infowindow.open(map,marker);
              }); 
          }
      } else {
          google.maps.event.addListener(marker, "mouseover", function() {
            infowindow.open(map,marker);
          }); 
      }
      
      return marker;
  },
    
  addMarkerWithStreetView: function( lat, lon, html, triggerEvent, centre, title ){
        
            if($("panorama") && $("panorama").up() && $("panorama").up().previous() && $("panorama").up().previous().previous())
                $("panorama").up().previous().previous().hide();
    
      // adds a marker to the selected point and returns a reference to the marker
      var icon;
      var point = new google.maps.LatLng(lat,lon);
      var marker;
            $this = this;
      
      // store the long and lat in the overall average lon lat variables
      this.addToAvgCoords( lat, lon );
      
      // if the variable centre is set to true, we centre to the point
      if ( centre ) {
          this.map.setCenter(point);  
          this.map.setZoom(this.zoomLevel);
      }
      
      // if there is a custom icon specified, create the icon
      if ( this.markerImg.length > 0 ) {
          icon = new google.maps.MarkerImage(this.markerImg,
                                        new google.maps.Size(this.markerWidth, this.markerHeight),
                                        new google.maps.Point(0,0),
                                        new google.maps.Point(6, 20));
      
          if (this.markerShadow.length > 0) {
            shadow = new google.maps.MarkerImage(this.markerShadow,
                                              new google.maps.Size(this.markerShadowWidth, this.markerShadowHeight),
                                              new google.maps.Point(0,0),
                                              new google.maps.Point(0, 32));
          }
          
          marker = new google.maps.Marker({
            position: point,
            map: map,
            shadow: shadow,
            icon: icon,
            title: title
          });
      } else {
          marker = new google.maps.Marker({
            position: point,
            map: this.map,
            title: title
          });
      }

      // create the infowindow for this marker
      var infowindow = new google.maps.InfoWindow({
        content: html
      });
      
      if ( triggerEvent != null ) {
          if ( triggerEvent == "now" ) {
              infowindow.open(this.map,marker);
          } else {
              google.maps.event.addListener(marker, 'click', function() {
                infowindow.open(this.map,marker);
              }); 
          }
      } else {
          google.maps.event.addListener(marker, "mouseover", function() {
            infowindow.open(this.map,marker);
          }); 
      }
            
      /*      // create two tabs, one for the hotel and one for the streetview
            var div = document.createElement('div');
            div.id = 'panorama';
            div.style.width = '300px';
            div.style.height = '160px';
            div.style.overflow = 'hidden';
            var tabList = [
                new google.maps.InfoWindow("Hotel Info", html),
                new google.maps.InfoWindow("Street View", div)
            ]
      
      if ( triggerEvent != null ) {
          if ( triggerEvent == "now" ) {
              this.addStreetView(marker,tabList,point);
          } else {
            google.maps.event.addListener(marker, triggerEvent, function() {
                $this.addStreetView(marker,tabList,point);
            }); 
          }
      } else {
          google.maps.event.addListener(marker, "mouseover", function() {
              $this.addStreetView(marker,tabList,point);
          }); 
      }*/
      
      return marker;
  },
  
  addToAvgCoords: function( lat, lon ){
      if ( this.avgLat == 0 ) {
          this.avgLat = lat;
      } else {
          this.avgLat = ( parseFloat(this.avgLat) + parseFloat(lat) ) /2;
      }
      if ( this.avgLon == 0 ) {
          this.avgLon = lon;
      } else {
          this.avgLon = ( parseFloat(this.avgLon) + parseFloat(lon) ) /2;
      }
  },  
  
  addGeoMarker: function( address, html, triggerEvent, centre ){
    
      geocoder = new GClientGeocoder();
      var sself = this;
      geocoder.getLatLng(address, function(point){
                         
          if (!point)
              return false;
    
          // adds a marker to the selected point and returns a reference to the marker
          var icon;
          var marker;
          
          // store the long and lat in the overall average lon lat variables
          sself.addToAvgCoords( point );
          
          // if the variable centre is set to true, we centre to the point
          if ( centre ) {
              sself.map.setCenter(point); 
              sself.map.setZoom(this.zoomLevel);
          }
          
          // if there is a custom icon specified, create the icon
          if ( sself.markerImg.length > 0 ) {
              icon = new GIcon();
              icon.image = sself.markerImg;
              if ( sself.markerShadow.length > 0 )
                  icon.shadow = sself.markerShadow;
              icon.iconSize = new GSize(sself.markerWidth, sself.markerHeight);
              icon.shadowSize = new GSize(sself.markerShadowWidth, sself.markerShadowHeight);
              icon.iconAnchor = new GPoint(6, 20);
              icon.infoWindowAnchor = new GPoint(5, 1);
              marker = new google.maps.Marker(point, icon);
              sself.map.addOverlay(marker);
          } else {
              marker = new google.maps.Marker(point);
              sself.map.addOverlay(marker);
          } 
          
          if ( triggerEvent != null ) {
              if ( triggerEvent == "now" ) {
                  marker.openInfoWindowHtml(html);
              } else {
                  google.maps.event.addListener(marker, triggerEvent, function() {
                    marker.openInfoWindowHtml(html);
                  }); 
              }
          } else {
              google.maps.event.addListener(marker, "mouseover", function() {
                marker.openInfoWindowHtml(html);
              }); 
          }
          
          return marker;
      
      });
  },
    
  addGeoMarkerWithStreetView: function( address, html, triggerEvent, centre ){
        
            if($("panorama") && $("panorama").up() && $("panorama").up().previous() && $("panorama").up().previous().previous())
                $("panorama").up().previous().previous().hide();
    
      geocoder = new GClientGeocoder();
      var sself = this;
            $this = this;
      geocoder.getLatLng(address, function(point){
                         
          if (!point)
              return false;
    
          // adds a marker to the selected point and returns a reference to the marker
          var icon;
          var marker;
          
          // store the long and lat in the overall average lon lat variables
          sself.addToAvgCoords( point );
          
          // if the variable centre is set to true, we centre to the point
          if ( centre ) {
              sself.map.setCenter(point);
              sself.map.setZoom(this.zoomLevel);  
          }
          
          // if there is a custom icon specified, create the icon
          if ( sself.markerImg.length > 0 ) {
              icon = new GIcon();
              icon.image = sself.markerImg;
              if ( sself.markerShadow.length > 0 )
                  icon.shadow = sself.markerShadow;
              icon.iconSize = new GSize(sself.markerWidth, sself.markerHeight);
              icon.shadowSize = new GSize(sself.markerShadowWidth, sself.markerShadowHeight);
              icon.iconAnchor = new GPoint(6, 20);
              icon.infoWindowAnchor = new GPoint(5, 1);
              marker = new google.maps.Marker(point, icon);
              sself.map.addOverlay(marker);
          } else {
              marker = new google.maps.Marker(point);
              sself.map.addOverlay(marker);
          } 
                    
                    // create two tabs, one for the hotel and one for the streetview
                    var div = document.createElement('div');
                    div.id = 'panorama';
                    div.style.width = '300px';
                    div.style.height = '160px';
                    div.style.overflow = 'hidden';
                    var tabList = [
                        new GInfoWindowTab("Hotel Info", html),
                        new GInfoWindowTab("Street View", div)
                    ]
          
          /*if ( triggerEvent != null ) {
              if ( triggerEvent == "now" ) {
                      this.addStreetView(marker,tabList,point);
              } else {
                google.maps.event.addListener(marker, triggerEvent, function() {
                            $this.addStreetView(marker,tabList,point);
                }); 
              }
          } else {
              google.maps.event.addListener(marker, "mouseover", function() {
                        $this.addStreetView(marker,tabList,point);
              }); 
          }*/
          
          return marker;
      
      });
  },
  
  addMarkerMgr: function( padding, zoom, track ){
    
      var sBorderPadding;
      var sMaxZoom;
      var bTrackMarkers = false;
      
      // use variables if they have been supplied, or set some defaults if not
      if ( padding != null )
          sBorderPadding =  padding;
      else
          sBorderPadding =  50;
          
      if ( zoom != null )
          sMaxZoom =  zoom;
      else
          sMaxZoom =  15;
          
      if ( track != null )
          bTrackMarkers =  track;
      
      var mgrOptions = { borderPadding: sBorderPadding, maxZoom: sMaxZoom, trackMarkers: bTrackMarkers };
      this.markerMgr = new google.maps.MarkerManager(this.map, mgrOptions);
    
      return this.markerMgr;
  },
  
  getCurrentZoomLevel: function(){
      return this.map.getZoom();
  },
  
  getBounds: function(){
      return this.map.getBounds();
  },
  
  getCentre: function(){
      return this.map.getCenter()
  },
  
  setBounds: function( bounds ){
      // centers the map to the specified longitude and latitude using bounds setting
      this.map.setCenter(new GLatLng(bounds));  
      this.map.setZoom(this.zoomLevel);
      
      if ( this.showControls )
            this.showControl();
          
      if ( this.showTypeSelect )
          this.showMapTypeSelect();
  },
  
  listenZoom: function( functionName ){
      return google.maps.event.addListener(this.map, "zoomend", functionName);
  },
  
  listen: function( theEvent, functionName ){
      return google.maps.event.addListener(this.map, theEvent, functionName);
  },
  
  setType: function( type ){
      // changes the view type of the map
      if ( type == "default" || type == "map" )
          this.map.setMapType(G_MAP_TYPE);
      if ( type == "sat" )
          this.map.setMapType(G_SATELLITE_TYPE);
      if ( type == "hybrid" )
          this.map.setMapType(G_HYBRID_TYPE);
  },
  
  setZoom: function( level ){
      this.map.setZoom( level )
  },
  
  customControl: function( text, functionRef, x, y ) {
    
      var control = new GControl();
      var theMap = this.map;
      var zoomInDiv;
      
      control.initialize = function( theMap ) {
          var container = document.createElement("div");
          zoomInDiv = document.createElement("div");
          container.appendChild(zoomInDiv);
          zoomInDiv.appendChild(document.createTextNode(text));
          google.maps.event.addDomListener(zoomInDiv, "click", functionRef );     
          theMap.getContainer().appendChild(container);
          return container;
      };
      
      control.getDefaultPosition = function() {
          if ( !x && x != null && x.length > 0 && !isNaN(x) )
              x = 7;
          if ( !y && y != null && y.length > 0 && !isNaN(y) )
              x = 7;
          return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x, y));
      };
      
      this.map.addControl( control );
      
      // add some rudimentary styles
      zoomInDiv.style.background = "#fff";
      zoomInDiv.style.color = "#000";
      zoomInDiv.style.fontWeight = "bold";
      zoomInDiv.style.cursor = "pointer";
      zoomInDiv.style.font = "small Arial";
      zoomInDiv.style.border = "1px solid black";
      zoomInDiv.style.padding = "2px";
      zoomInDiv.style.marginBottom = "3px";
      zoomInDiv.style.textAlign = "center";
      
      return zoomInDiv;
    
  },  
  
  clear: function(){
      this.map.clearOverlays();
  },
  
  unload: function(){
      GUnload();
  },
    
    addStreetView: function(marker,tabList,point) {
        if($("panorama") && $("panorama").up() && $("panorama").up().previous() && $("panorama").up().previous().previous())
            $("panorama").up().previous().previous().hide();
        $this = this;
        
        //marker.openInfoWindowTabsHtml(tabList);
        setTimeout(function(){
            $("panorama").up().previous().previous().hide();
            var myPano = new GStreetviewPanorama(document.getElementById("panorama"), {latlng:point});
            var timeout = setTimeout(function(){
                $("panorama").up().previous().previous().show().addClassName('show');
            }, 2000);
            google.maps.event.addListener(myPano, "error", function(){
                clearTimeout(timeout);
                $("panorama").up().previous().previous().remove();
            });
        },500);
    }
};  
