/**
   * Adds a map to the catalog into the right Mapset.
   *
   * <p>Note: this doesn't add the file. The file adding has to be done separately
   *
   * @param locationPath the path to the Location folder.
   * @param mapsetName the name of the Mapset into which to put the map.
   * @param mapName the name of the map to add.
   * @param mapType the format of the map to add.
   * @return the resource that has been added.
   */
  public static synchronized JGrassMapGeoResource addMapToCatalog(
      String locationPath, String mapsetName, String mapName, String mapType) {
    // URL mapsetId = JGrassMapsetGeoResource.createId(locationPath, mapsetName);

    JGrassMapsetGeoResource mapset = null;
    try {
      File locationFile = new File(locationPath);

      ID locationId = new ID(locationFile.toURI().toURL());
      URL mapsetUrl = JGrassMapsetGeoResource.createId(locationFile.getAbsolutePath(), mapsetName);
      ID mapsetId = new ID(mapsetUrl);
      ICatalog localCatalog = CatalogPlugin.getDefault().getLocalCatalog();
      mapset =
          localCatalog.getById(
              JGrassMapsetGeoResource.class, mapsetId, ProgressManager.instance().get());
      if (mapset == null) {
        // try with the service
        // URL locationId = JGrassService.createId(locationPath);
        JGrassService locationService =
            localCatalog.getById(JGrassService.class, locationId, ProgressManager.instance().get());
        mapset = locationService.getMapsetGeoresourceByName(mapsetName);
      }
    } catch (MalformedURLException e) {
      e.printStackTrace();
      String message = "An error occurred while adding the map to the catalog";
      ExceptionDetailsDialog.openError(null, message, IStatus.ERROR, JGrassPlugin.PLUGIN_ID, e);
    }
    if (mapset == null) return null;
    return mapset.addMap(mapName, mapType);
  }
  public Set<Range<Double>> getValidScaleRanges() {
    HashSet<Range<Double>> ranges = new HashSet<Range<Double>>();
    try {
      Layer layer = context.getGeoResource().resolve(Layer.class, ProgressManager.instance().get());
      double min = layer.getScaleDenominatorMin();
      double max = layer.getScaleDenominatorMax();
      if (invalidScale(min) && invalidScale(max)) {
        return ranges;
      }

      if (invalidScale(min)) {
        min = Double.MIN_VALUE;
      }
      if (invalidScale(max)) {
        max = Double.MAX_VALUE;
      }
      if (min < max) {
        ranges.add(new Range<Double>(Double.class, min, max));
      } else {
        ranges.add(new Range<Double>(Double.class, max, min));
      }
    } catch (IOException e) {
      throw (RuntimeException) new RuntimeException().initCause(e);
    }
    return ranges;
  }
  @Override
  public void run(boolean fork, boolean cancelable, final IRunnableWithProgress request)
      throws InvocationTargetException, InterruptedException {
    if (headless && Display.getCurrent() == null) {
      PlatformGIS.run(request);
      return;
    }

    if (getProgressMonitor() instanceof ProgressMonitorPart) {
      ProgressMonitorPart part = (ProgressMonitorPart) getProgressMonitor();
      if (Display.getCurrent() != null) part.setVisible(true);

      try {
        setEnablement(buttonBar, false);
        if (fork) {
          PlatformGIS.run(request, part);
        } else {
          PlatformGIS.runBlockingOperation(request, part);
        }
      } finally {
        setEnablement(buttonBar, true);
        if (Display.getCurrent() != null && !part.isDisposed()) part.setVisible(false);
      }
    } else {
      if (fork) {
        PlatformGIS.run(request);
      } else {
        PlatformGIS.runBlockingOperation(request, ProgressManager.instance().get());
      }
    }
  }
  /** Performs the initialization of the workflow. */
  protected void initWorkflow() {
    // start the workflow
    // TODO: This can potentially freeze up the ui if the fist state
    // does alot of work in the #init(IProgressMonitor) method. Perhaps
    // it should be made part of the contract of the dialog that the pipe
    // already be started before open is called.
    final Workflow pipe = getWizard().getWorkflow();
    final IRunnableWithProgress runnable =
        new IRunnableWithProgress() {
          public void run(IProgressMonitor monitor)
              throws InvocationTargetException, InterruptedException {
            if (!pipe.started) pipe.start(monitor);
          }
        };

    if (Display.getCurrent() != null) {
      try {
        runnable.run(ProgressManager.instance().get());
      } catch (Exception e) {
        throw (RuntimeException) new RuntimeException().initCause(e);
      }
    } else {
      PlatformGIS.syncInDisplayThread(
          new Runnable() {
            public void run() {
              try {
                PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(false, false, runnable);
              } catch (Throwable e) {
                throw new RuntimeException(e);
              }
            }
          });
    }
  }
  /**
   * Remove a map from the mapset in the catalog.
   *
   * <p>Note: this doesn't remove the file. The file removal has to be done separately
   *
   * @param locationPath the path to the Location folder.
   * @param mapsetName the name of the Mapset from which to remove the map.
   * @param mapName the name of the map to remove.
   * @param mapType the format of the map to remove.
   */
  public static synchronized void removeMapFromCatalog(
      String locationPath, String mapsetName, String mapName, String mapType) {
    // URL mapsetId = JGrassMapsetGeoResource.createId(locationPath, mapsetName);
    File locationFile = new File(locationPath);
    URL mapsetUrl = JGrassMapsetGeoResource.createId(locationFile.getAbsolutePath(), mapsetName);
    ID mapsetId = new ID(mapsetUrl);

    JGrassMapsetGeoResource mapset =
        CatalogPlugin.getDefault()
            .getLocalCatalog()
            .getById(JGrassMapsetGeoResource.class, mapsetId, ProgressManager.instance().get());
    mapset.removeMap(mapName, mapType);
  }
 /**
  * Remove a mapset from a Location in the catalog.
  *
  * <p>Note: this doesn't remove the file. The file removal has to be done separately
  *
  * @param locationPath path to the location from which the mapset has to be removed.
  * @param mapsetName the name of the mapset to remove
  */
 public static synchronized void removeMapsetFromCatalog(String locationPath, String mapsetName) {
   // URL locationId = JGrassService.createId(locationPath);
   try {
     File locationFile = new File(locationPath);
     ID locationId = new ID(locationFile.toURI().toURL());
     JGrassService location =
         CatalogPlugin.getDefault()
             .getLocalCatalog()
             .getById(JGrassService.class, locationId, ProgressManager.instance().get());
     location.removeMapset(mapsetName);
   } catch (MalformedURLException e) {
     e.printStackTrace();
     String message = "An error occurred while removing the mapset to the catalog";
     ExceptionDetailsDialog.openError(null, message, IStatus.ERROR, JGrassPlugin.PLUGIN_ID, e);
   }
 }
  // XXX: Consider doing more SLD when WMS post is a go
  public boolean canStyle(String SyleID, Object value) {
    if (value == null) return false;
    if (value instanceof Style) return !Double.isNaN(SLDs.rasterOpacity((Style) value));

    if (value instanceof StyleImpl && getRenderContext().getGeoResource().canResolve(Layer.class)) {
      try {
        Layer layer =
            getRenderContext()
                .getGeoResource()
                .resolve(Layer.class, ProgressManager.instance().get());
        if (layer.getStyles().contains(value)) {
          return true;
        } else {
          return false;
        }
      } catch (IOException e) {
        return false;
      }
    }

    return false;
  }
  public boolean canAddLayer(ILayer layer) {

    if (!layer.hasResource(Layer.class)) return false;

    try {
      if (!layer
          .findGeoResource(Layer.class)
          .parent(ProgressManager.instance().get())
          .equals(getRenderContext().getGeoResource().parent(ProgressManager.instance().get())))
        return false;
    } catch (IOException e2) {
      return false;
    }

    double opacity = Double.NaN;

    ICompositeRenderContext context1 = (ICompositeRenderContext) context;

    IRenderContext[] contexts =
        context1.getContexts().toArray(new IRenderContext[context1.getContexts().size()]);
    Arrays.sort(contexts);
    List<Layer> owsLayers = new ArrayList<Layer>();
    IService currentService;
    try {
      owsLayers.add(layer.getResource(Layer.class, new NullProgressMonitor()));
      currentService = layer.getResource(IService.class, null);
    } catch (IOException e1) {
      WMSPlugin.log("", e1); // $NON-NLS-1$
      return false;
    }
    for (IRenderContext renderContext : contexts) {
      ILayer previousLayer = renderContext.getLayer();

      try {
        owsLayers.add(previousLayer.getResource(Layer.class, new NullProgressMonitor()));
        IService previousService = previousLayer.getResource(IService.class, null);
        if (currentService != previousService) {
          return false;
        }
      } catch (IOException e) {
        WMSPlugin.log("Error while retrieving service.", e); // $NON-NLS-1$
        return false;
      }

      if (BasicWMSRenderer2.findRequestCRS(owsLayers, context.getCRS(), context.getMap()) == null)
        return false;

      Style style = (Style) previousLayer.getStyleBlackboard().get(SLDContent.ID);
      if (style != null) {
        opacity = SLDs.rasterOpacity(SLDs.rasterSymbolizer(style));
      }
    }

    Style style = (Style) layer.getStyleBlackboard().get(SLDContent.ID);
    if (style == null && Double.isNaN(opacity)) {
      return true;
    }

    double result = SLDs.rasterOpacity(SLDs.rasterSymbolizer(style));

    if (result == opacity) {
      return true;
    }
    return false;
  }