// vc_id = "$Id: listingMap.js 11366 2008-03-14 21:50:50Z robert $"
// This library represents specific mapping functions for the
// listings map.
// @author Robert D. Rice

var LISTING_MAP = "Listing Map";
var LISTING_EARTH = "Listing Earth";

// method to initialize the Listing Map
// @param GeoRectangle representing the map in map coords, or a map object
// @param GeoRectangle representing the map in earth coords, or a map object
// @param GeoRectangle representing the map in screen coords
// @param integer representing the zoom level
function initializeListingMap( mapExtent,
                               mapEarth,
                               mapScreen,
                               zoomLevel,
                               position ) {
    if ( mapExtent.id && mapEarth.id ) {
	mapExtent.id = LISTING_MAP;
	mapEarth.id = LISTING_EARTH;
	addMap( mapExtent );
	addMap( mapEarth );
    } else {
	saveMap( LISTING_MAP,
		 mapExtent,
		 null,
		 mapScreen,
		 zoomLevel );
	saveMap( LISTING_EARTH,
		 mapEarth,
		 null,
		 mapScreen,
		 zoomLevel );
    }
}

// method to initialize the Listing Map Bounds
// @param event, now optional, internal will be looked up otherwise
// @param an html element that represents this bounds.
//  this will be the element to draw upon.
// @param optional offset, added to position, 
//  used to translate bounding box to underlying map
function initializeListingMapBounds( e, html, offset ) {
    if ( e == null ) {
      initializeBounds( LISTING_MAP, 
                      null, 
                      html );
      initializeBounds( LISTING_EARTH, 
                      null, 
                      html );
    } else {
      var screen = ScreenCoordinatesOnElementFromEvent( e );
      if ( offset ) { screen = GeoPointSum( screen, offset ); }
      initializeBounds( LISTING_MAP, 
                        screen, 
                        html );
      initializeBounds( LISTING_EARTH, 
                        screen, 
                        html );
    }
 }

// method to update the Listing Map Bounds
// @param event
function updateListingMapBounds( e ) {
     updateBounds( LISTING_MAP, 
                   ScreenCoordinatesOnElementFromEvent( e ) );
     updateBounds( LISTING_EARTH, 
                   ScreenCoordinatesOnElementFromEvent( e ) );
}

// method to determine if the Listing Map Bounds 
// have been initialized.  this is simply a convenience method
// for implementations that want to know if we are 
// drawing a box.
// @return true if the bounds have been initialized, meaning 
//   we are drawing a box
function areListingMapBoundsInitialized( ) {
      return retrieveMap( LISTING_MAP ).bounds == null ? false : true;
}

// method to update the Listing Map Bounds, utilized by the box
// @param event
function updateListingMapBoundsBox( e ) {
     updateBounds( LISTING_MAP, 
                   GeoPointSum( ScreenCoordinatesOnElementFromEvent( e ),
                                retrieveMap( LISTING_MAP ).bounds.start ) );
     updateBounds( LISTING_EARTH, 
                   GeoPointSum( ScreenCoordinatesOnElementFromEvent( e ),
                                retrieveMap( LISTING_EARTH ).bounds.start ) );
}

// method to finalize the Listing Map Bounds
// @param top extent html object
// @param left extent html object
// @param bottom extent html object
// @param right extent html object
// @param x center html object
// @param y center html object
// @param north lat extent html object
// @param west long extent html object
// @param south lat extent html object
// @param east long extent html object
// @param long center html object
// @param lat center html object
// @param zoom level html object
// @param action to take on re-center
function finalizeListingMapBounds( top, left, bottom, right, x, y, 
                                   north, west, south, east, lon, lat,
                                   zoom, centerAction ) {
   finalizeListingMapBoundsByName( LISTING_MAP, top, left, bottom, right, x, y, zoom, centerAction );
   finalizeListingMapBoundsByName( LISTING_EARTH, north, west, south, east, lon, lat, zoom, centerAction );
}

// method to finalize the Listing Map Bounds
// @param string name of map
// @param top extent html object
// @param left extent html object
// @param bottom extent html object
// @param right extent html object
// @param x center html object
// @param y center html object
// @param zoom level html object, this is likely an array of radio buttons, 
//   or a hidden/text input
// @param action to take on re-center
function finalizeListingMapBoundsByName( name, top, left, bottom, right, x, y, zoom, centerAction ) {
    var bounds = MapCoordinatesfromScreenCoordinates( name,
                  retrieveMap( name ).bounds );
    var nextZoomLevel = ( retrieveMap( name ).zoomLevel >=  retrieveMap( name ).zoomLevelMax ) ?
      retrieveMap( name ).zoomLevelMax : ( retrieveMap( name ).zoomLevel + 1 );

    if ( bounds.top != bounds.bottom &&
         bounds.left != bounds.right ) {
      top.value = bounds.top;
      right.value = bounds.right;
      left.value = bounds.left;
      bottom.value = bounds.bottom;
      if ( zoom.type == "radio" ) {
        zoom.checked = false;
      } else {
        zoom.value = '';
      }
    } else if ( centerAction &&
                centerAction.value == 'zoom' ) {
      if ( zoom.type == "radio" ) {
       zoom.form.elements[zoom.name][nextZoomLevel].checked = true;
     } else {
        zoom.value = nextZoomLevel;
      }
    }

    x.value = ( bounds.right + bounds.left ) / 2; 
    y.value = ( bounds.top + bounds.bottom ) / 2; 

    finalizeBounds( name );
}

// method to set the Listing Map Center
// @param GeoPoint representing the center in screen coordinates
// @param x center html object
// @param y center html object
// @param long center html object
// @param lat center html object
function setListingMapCenter( screen, x, y, lon, lat ) {
    var centerMap = MapCoordinatesfromScreenCoordinates( LISTING_MAP, screen );
    x.value = centerMap.x;
    y.value = centerMap.y;
    var centerEarth = MapCoordinatesfromScreenCoordinates( LISTING_EARTH, screen );
    lon.value = centerEarth.x;
    lat.value = centerEarth.y;
}

// method to set the Listing Map Center by screen percentage
// @param w representing the center in screen percentage of width
// @param h representing the height in screen percentage of height
// @param x center html object
// @param y center html object
// @param long center html object
// @param lat center html object
function setListingMapCenterByPercent( w, h, x, y, lon, lat ) {
    setListingMapCenter( new GeoPoint( getListingMapScreenWidth( ) * w, getListingMapScreenHeight( ) * h ), 
			 x, y, lon, lat );
}

// convenience method to retrieve the Listing Map Screen Width
// @return pixel width, integer
function getListingMapScreenWidth( ) {
    return retrieveMap( LISTING_EARTH ).screen.right;
}

// convenience method to retrieve the Listing Map Screen Height
// @return pixel heigth, integer
function getListingMapScreenHeight( ) {
    return retrieveMap( LISTING_EARTH ).screen.bottom;
}

// convenience method to retrieve the Listing Map Zoom Level
// @return zoom level, integer
function getListingMapZoomLevel( ) {
    return retrieveMap( LISTING_EARTH ).zoomLevel;
}

var MAP_ORIGIN = null;

// method to initialize a point, in screen coordinates
// this method will initialize a point based on the event.
// it keeps track of the first element origin found, and 
// translates all future coordinates to that element.  the
// first element should be the listing map, thus setting the
// origin to the map origin.  if an event occurs on the draw
// box, it too will be translated to the map.  this method 
// allows us to nest the css-p elements within a non css-p
// controled page.
// @param event
// @return a GeoPoint object ( in screen coordinates )
function ScreenCoordinatesFromEvent( e ) {
  if ( MAP_ORIGIN == null )
    MAP_ORIGIN = ScreenCoordinatesElementOriginFromEvent( e );
  var point = ScreenCoordinatesOnElementFromEvent( e, MAP_ORIGIN );
  return point;
}

// Register as a position change listener
// Requires the PositionChangeSupport class
function registerListingMap( ) {
  addPositionChangeListener( retrieveMap( LISTING_MAP ) );
  addPositionChangeListener( retrieveMap( LISTING_EARTH ) );
}

// Convenience method to fire PositionChangeEvents for the box
// Requires the PositionChangeSupport class
// @param event that triggered the position change
function firePositionChangeEventBox( e ) {
  firePositionChangeEvent( e, retrieveMap( LISTING_MAP ).bounds.start );
  // firePositionChangeEvent( e, retrieveMap( LISTING_EARTH ).bounds.start );
}


