package openlayer.google.client.spatial;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import org.gwtopenmaps.openlayers.client.LonLat;
import org.gwtopenmaps.openlayers.client.Map;
import org.gwtopenmaps.openlayers.client.MapOptions;
import org.gwtopenmaps.openlayers.client.MapWidget;
import org.gwtopenmaps.openlayers.client.control.LayerSwitcher;
import org.gwtopenmaps.openlayers.client.control.MouseDefaults;
import org.gwtopenmaps.openlayers.client.control.PanZoomBar;
import org.gwtopenmaps.openlayers.client.event.MapClickListener;
import org.gwtopenmaps.openlayers.client.layer.GMapType;
import org.gwtopenmaps.openlayers.client.layer.Google;
import org.gwtopenmaps.openlayers.client.layer.GoogleOptions;
import org.gwtopenmaps.openlayers.client.layer.Layer;
import org.gwtopenmaps.openlayers.client.layer.TransitionEffect;
import org.gwtopenmaps.openlayers.client.layer.WMS;
import org.gwtopenmaps.openlayers.client.layer.WMSOptions;
import org.gwtopenmaps.openlayers.client.layer.WMSParams;
import org.gwtopenmaps.openlayers.client.util.JObjectArray;
import org.gwtopenmaps.openlayers.client.util.JSObjectWrapper;

public class SpatialDbTips implements EntryPoint {
  private static double lon = -122.8450;
  private static double lat = 42.3438;
  private static int zoom = 18;
  public static final String WMS_URL = "http://localhost:8080/geoserver/wms";
  
  private HorizontalPanel horizontalPanel = new HorizontalPanel();
  private MapWidget mapWidget = null;
  private WMS wms0 = null;
  private WMS clickQueryWMS = null;
  
  private HorizontalPanel queryTablePanel = null;
  private ListBox queryTableListBox = null;
  private SimplePanel queryResultPanel = null;
  //private IFrameElement frameElement = null;
  private MapClickListener mapClickListener = null;
  private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
  
  public void onModuleLoad() {
//    frameElement = IFrameElement.as(RootPanel.get("query").getElement());
//    final com.google.gwt.dom.client.Document document = frameElement.getOwnerDocument();
//    final Style style = frameElement.getStyle();
//    String value = style.getProperty("display");
    queryResultPanel = new SimplePanel();
    queryResultPanel.setVisible(false);
    
    mapWidget = getMapWidget();
    wms0 = getWMS0();
    
    ShowcaseMenuItem showcaseMenuItem = new ShowcaseMenuItem("Next", "Click Query");
    InlineHTML inlineHTML = showcaseMenuItem.getLabel();
    
    Label previousLabel = new Label("Previous");
    horizontalPanel.add(previousLabel);
    horizontalPanel.add(inlineHTML);
    
    final VerticalPanel verticalPanel = new VerticalPanel();
    verticalPanel.add(horizontalPanel);
    verticalPanel.add(mapWidget);
    
    final Map map = mapWidget.getMap();
    map.addLayers(new Layer[] {wms0});
    
    RootPanel.get("map").add(verticalPanel);

    inlineHTML.addClickHandler(new ClickHandler() {

      public void onClick(ClickEvent event) {
        queryResultPanel.setVisible(true);
        
        map.removeLayer(wms0);
        
        clickQueryWMS = getClickQueryWMS();
        final Map map = mapWidget.getMap();
        map.addLayers(new Layer[] {clickQueryWMS});
        
        queryTablePanel = getQueryTablePanel();
        verticalPanel.add(queryTablePanel);
        verticalPanel.add(queryResultPanel);
        
        mapClickListener = new MapClickListener() {

          public void onClick(MapClickEvent mapClickEvent) {
              // Read the map coordinates from the click event
              LonLat lonlat = mapClickEvent.getLonLat();
              String table = queryTableListBox.getValue(queryTableListBox.getSelectedIndex());
              
//              // Construct the query URL
              String url = "01-click-query.jsp";
              url += "?lon=" + lonlat.lon();
              url += "&lat=" + lonlat.lat();
              url += "&table=" + table;
              
              greetingService.greetServer(url, new AsyncCallback<String>() {

                public void onFailure(Throwable caught) {
                  Widget widget = queryResultPanel.getWidget();
                  if (widget != null) {
                    queryResultPanel.remove(widget);
                  }
                  queryResultPanel.add(new HTML(caught.toString()));
                }

                public void onSuccess(String result) {
                  Widget widget = queryResultPanel.getWidget();
                  if (widget != null) {
                    queryResultPanel.remove(widget);
                  }
                  queryResultPanel.add(new HTML(result));
                }
       
              });
            }
        };
        
        map.addMapClickListener(mapClickListener);
      }

    });
  }

  protected HorizontalPanel getQueryTablePanel() {
    HorizontalPanel horizontalPanel = new HorizontalPanel();
    horizontalPanel.add(new HTML("<b>Query Table</b>&nbsp;&nbsp;&nbsp;"));
    
    queryTableListBox = new ListBox();
    queryTableListBox.addItem("medford.buildings", "medford.buildings");
    queryTableListBox.addItem("medford.taxlots", "medford.taxlots");
    queryTableListBox.addItem("medford.wards", "medford.wards");
    queryTableListBox.addItem("medford.zoning", "medford.zoning");
    
    queryTableListBox.setSelectedIndex(0);

    horizontalPanel.add(queryTableListBox);
    
    return horizontalPanel;
  }

  private WMS getClickQueryWMS() {
    try {
      //Defining a WMSLayer and adding it to a Map
      WMSParams wmsParams = new WMSParams();
      wmsParams.setFormat("image/png");
      wmsParams.setLayers("medford:taxlots,medford:buildings");
      wmsParams.setIsTransparent(true);
      wmsParams.setStyles("");
  
      WMSOptions wmsLayerParams = new WMSOptions();
      wmsLayerParams.setUntiled();
      wmsLayerParams.setTransitionEffect(TransitionEffect.RESIZE);
      wmsLayerParams.getJSObject().setProperty("reproject", true);
  
      WMS wmsLayer = new WMS("Medford Buildings", WMS_URL, wmsParams, wmsLayerParams);
  
      return wmsLayer;
    } catch (RuntimeException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      return null;
    }
  }
  
  private MapWidget getMapWidget() {
    try {
      MouseDefaults mouseDefaults = new MouseDefaults();
      
      MapOptions mapOptions = new MapOptions();
      //In OL, the map gets PanZoom, Navigation, ArgParser, and Attribution Controls
      //by default. Do setControls below to start with a map without Controls.
      mapOptions.setControls(new JObjectArray(new JSObjectWrapper[] {new PanZoomBar(), mouseDefaults, new LayerSwitcher()}));
      mapOptions.setNumZoomLevels(20);
//      mapOptions.setProjection("EPSG:4326");

      MapWidget mapWidget = new MapWidget("600px", "450px", mapOptions);
      Map map = mapWidget.getMap();
      
      GoogleOptions googleOptions = new GoogleOptions();
      GMapType gmapType = GMapType.G_NORMAL_MAP;
      googleOptions.setType(gmapType);
      googleOptions.setIsBaseLayer(true);
      googleOptions.setTransitionEffect(TransitionEffect.RESIZE);
      googleOptions.setSmoothDragPan(true);
      
      Google google = new Google("Google Streets", googleOptions);

      GoogleOptions googleSatOptions = new GoogleOptions();
      GMapType satelliteMap = GMapType.G_SATELLITE_MAP;
      googleSatOptions.setType(satelliteMap);
      googleSatOptions.setIsBaseLayer(true);
      googleSatOptions.setTransitionEffect(TransitionEffect.RESIZE);
      
      Google googleSat = new Google("Google Satellite", googleSatOptions);
      
      map.addLayers(new Layer[] {google, googleSat});
      map.setCenter(new LonLat(lon, lat), zoom);
      
      return mapWidget;
    } catch (RuntimeException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      return null;
    }
  }
    
    private WMS getWMS0() {
      try {
        //Defining a WMSLayer and adding it to a Map
        WMSParams wmsParams = new WMSParams();
        wmsParams.setFormat("image/png");
        wmsParams.setLayers("medford:buildings");
        wmsParams.setIsTransparent(true);
        wmsParams.setStyles("");
    
        WMSOptions wmsLayerParams = new WMSOptions();
        wmsLayerParams.setUntiled();
        wmsLayerParams.setTransitionEffect(TransitionEffect.RESIZE);
        wmsLayerParams.getJSObject().setProperty("reproject", true);
        
        WMS wmsLayer = new WMS("Map With WMS", WMS_URL, wmsParams, wmsLayerParams);
    
        return wmsLayer;
      } catch (RuntimeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
      }
  }
}
