package util;

import visad.*;
import visad.data.hdfeos.LambertAzimuthalEqualArea;
import visad.georef.MapProjection;
import java.awt.geom.Rectangle2D;
import java.lang.Math;


public class MapProjectionAdapter extends CoordinateSystem
{
   private MapProjection mapProjection;
   Rectangle2D rect    = null;
   float scaleX;
   float scaleY;
   float offsetX;
   float offsetY;

   int lon_idx = 0;
   int lat_idx = 1;

   public MapProjectionAdapter(MapProjection mapProjection)
          throws Exception
   {
     super(Display.DisplaySpatialCartesianTuple, new Unit[] {CommonUnit.degree, CommonUnit.degree, null});

     this.mapProjection = mapProjection;
     this.rect = mapProjection.getDefaultMapArea();

     scaleX  = (float) rect.getWidth()/2.0f;
     scaleY  = (float) rect.getHeight()/2.0f;
     offsetX = (float) rect.getX() + scaleX;
     offsetY = (float) rect.getY() + scaleY;
   }

   public boolean equals(Object cs) {
     return false;
   }

   public MapProjection getMapProjection() {
     return mapProjection;
   }

   public float[][] fromRefernece(float[][] values) 
          throws VisADException {
     float[][] values_2D = new float[2][values[0].length];
     for (int i = 0; i < values[0].length; i++) {
        values_2D[0][i] = values[0][i]*scaleX + offsetX;
        values_2D[1][i] = values[1][i]*scaleY + offsetY;
     }
     values_2D = mapProjection.toReference(new float[][] {values_2D[lon_idx], values_2D[lat_idx]});
     return new float[][] {values_2D[lon_idx], values_2D[lat_idx], values[2]};
   }
 
   public float[][] toReference(float[][] values)
          throws VisADException {
     float[][] values_2D = mapProjection.fromReference(new float[][] {values[lon_idx], values[lat_idx]});
     for (int i = 0; i < values[0].length; i++) {
        values_2D[lon_idx][i] = (values_2D[lon_idx][i]-offsetX)/scaleX;
        values_2D[lat_idx][i] = (values_2D[lat_idx][i]-offsetY)/scaleY;
     }
     return new float[][] {values_2D[lon_idx], values_2D[lat_idx], values[2]};
   }

   public double[][] fromReference(double[][] values) 
          throws VisADException {
     double[][] values_2D = new double[2][values[0].length];
     for (int i = 0; i < values[0].length; i++) {
        values_2D[0][i] = values[0][i]*scaleX + offsetX;
        values_2D[1][i] = values[1][i]*scaleY + offsetY;
     }
     values_2D = mapProjection.toReference(new double[][] {values_2D[lon_idx], values_2D[lat_idx]});
     return new double[][] {values_2D[lon_idx], values_2D[lat_idx], values[2]};
   }

   public double[][] toReference(double[][] values) 
          throws VisADException {
     double[][] values_2D = mapProjection.fromReference(new double[][] {values[lon_idx], values[lat_idx]});
     for (int i = 0; i < values[0].length; i++) {
        values_2D[lon_idx][i] = (values_2D[lon_idx][i]-offsetX)/scaleX;
        values_2D[lat_idx][i] = (values_2D[lat_idx][i]-offsetY)/scaleY;
     }
     return new double[][] {values_2D[lon_idx], values_2D[lat_idx], values[2]};
   }
}
