/*

  Note: the hidden markers used internally to store the coords are not stricly neccecary, 
        but in the future we might need to implement draggable anchors.

*/

jQuery.extend('datamarket.mapselect.plugins.polyselect', (function(){

  var dragMarkerS = null;
  var dragMarkerE = null;
  var dragging    = false;
  var lastpos     = null;

  var bounds      = null;
  var polygon     = null;

  var self = {

    clear: function( map ) {
      if ( dragMarkerS ) {
        dragMarkerS.hide();
      }
      if ( dragMarkerE ) {
        dragMarkerE.hide();
      }
      if ( polygon ) {
      	map.removeOverlay( polygon );
      	polygon = null;
      }
    },

    
    makeMarker: function( map, latlon ) {
      var marker = new GMarker( latlon, { 
        //icon : self.makeIcon( 'mm_20_red.png', 'mm_20_shadow.png' ),
        // draggable : false
      });
     	map.addOverlay( marker );
     	return marker;
    },
    
    latLonFromEvent: function ( ev ) {
      var co = new GPoint( ev.clientX, ev.clientY );
      return map.fromDivPixelToLatLng( co ); // fromContainerPixelToLatLng ??
    },
    
    
    updatePolygon: function ( map ) {
      if ( dragMarkerS && dragMarkerE && polygon ) {
     		
     		// construct a rectangle from lat/lon
     		bounds = new GLatLngBounds( 
     		    dragMarkerS.getLatLng(), 
     		    dragMarkerE.getLatLng()
     		  );
     		
     		var anchor = bounds.getSouthWest();
     		
     		polygon.deleteVertex( 0 );
     		polygon.insertVertex( 0, anchor );

     		polygon.deleteVertex( 1 );
     		polygon.insertVertex( 1, new GLatLng( bounds.getNorthEast().lat(), bounds.getSouthWest().lng() ) );

     		polygon.deleteVertex( 2 );
     		polygon.insertVertex( 2, bounds.getNorthEast() );

     		polygon.deleteVertex( 3 );
     		polygon.insertVertex( 3, new GLatLng( bounds.getSouthWest().lat(), bounds.getNorthEast().lng() ) );

     		polygon.deleteVertex( 4 );
     		polygon.insertVertex( 4, anchor );
     		
      }
    },
    
    init: function( map, parent ) {
      
      // add a poly-selection
      GEvent.addDomListener( map.getDragObject(), "mousedown", function( e ) {
        if ( e.shiftKey ) {

          // clear markers if they exist
          self.clear( map );

          // disable map dragging, but put polyselect into dragmode
          map.disableDragging();
          map.disableScrollWheelZoom();
          dragging = true;
          
          // current coords are now the selection anchor
          var latlon = lastpos || self.latLonFromEvent( e );

          // handle anchor marker 
          if ( dragMarkerS ) {
            dragMarkerS.setLatLng( latlon );
            dragMarkerS.hide();
          }
          else {
            dragMarkerS = self.makeMarker( map, latlon );
            dragMarkerS.hide();
          }

          // handle end point marker
          if ( dragMarkerE ) {
            dragMarkerE.setLatLng( latlon );
            dragMarkerE.hide();
          }
          else {
            dragMarkerE = self.makeMarker( map, latlon );
            dragMarkerE.hide();
          }

          // add a drag zone polygon
          polygon = new GPolygon([ latlon, latlon, latlon, latlon, latlon ],
                                    '#004', 0.5, 1, '#666', 0.4 );
        	map.addOverlay( polygon );
        	self.updatePolygon();   // make sure that bounds always exists

        }
      });
      
      GEvent.addListener(map, 'mousemove', function( latlon ){
        lastpos = latlon;
        if ( dragging ) {
          lastpos = dragMarkerE.setLatLng( latlon );
          self.updatePolygon( map );
        }
      });
      
      // attempt to niceify the cursor as possible
      var DO = map.getDragObject();
      jQuery( document ).bind( 'mouseup mousedown keydown keyup', function( e ) {
        if ( e.shiftKey ) {
          DO.setDraggingCursor('crosshair');
          DO.setDraggableCursor('crosshair');
        }
        else {
          // TODO : queue release if dragging == true
          DO.setDraggingCursor('move');
          DO.setDraggableCursor('move');
        }
      });

      GEvent.addDomListener( map.getDragObject(), 'mouseup', function( e ) {
        if ( dragging ) { // map.draggingEnabled()
          self.updatePolygon( map );
          map.enableDragging();
          dragging = false;
          
          // select all markers within the box
          if ( polygon ) {
            bounds = polygon.getBounds();
            for ( var id in parent.stations ) {
              // is this marker within selection
              var st = parent.stations[id];
              if ( st.marker ) {
                
                if ( bounds.containsLatLng( st.marker.getLatLng() ) ) {
                  parent.selectStation( id );
                }
              }
            }
            
            jQuery('#map').trigger('markerselect');
          }
          // clear
          self.clear( map );
          
        }
      });
    }

  };
  return self;


})() );
