/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.dnetlib.espas.spatial;

import eu.dnetlib.espas.util.CRSMapping;
import eu.dnetlib.espas.util.GeometryMetadataHandler;
import eu.dnetlib.espas.util.MetadataHandler;
import eu.dnetlib.espas.util.PointCoordinateEditor;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author gathanas
 */
public class CircularQShape extends QShape{
   private double circleRadious;
   
   public CircularQShape(Point centerPoint, double radious) {
      super(Arrays.asList(centerPoint));
      this.circleRadious = radious;
   }

   
   @Override
   public String getQueryString() {
      int sridCode = GeometryMetadataHandler.getSupportedCRSMapping(this.espasCRS).getSrid();
      String queryConstraint = "st_SetSRID(location::geometry, "+sridCode+")";
      double maxZ = 0.0, minZ = Double.MAX_VALUE;
      String constraintShape = "st_SetSRID(st_MakePoint(";
      Point p = this.shapePoints.get(0);
        boolean inverted = GeometryMetadataHandler.getSupportedCRSMapping(this.espasCRS).isInvertedXY();
        if(!inverted){
            constraintShape+= ""+(p.getCoordinate(Point.PolarCoord.LON_Cord.name())==null? p.getCoordinate(Point.CartesianCoord.X_Cord.name()): p.getCoordinate(Point.PolarCoord.LON_Cord.name()))+", ";
            constraintShape+= ""+(p.getCoordinate(Point.PolarCoord.LAT_Cord.name())==null?p.getCoordinate(Point.CartesianCoord.Y_Cord.name()):p.getCoordinate(Point.PolarCoord.LAT_Cord.name()))+" ";
        }
        else {
            constraintShape+= ""+(p.getCoordinate(Point.PolarCoord.LAT_Cord.name())==null?p.getCoordinate(Point.CartesianCoord.Y_Cord.name()):p.getCoordinate(Point.PolarCoord.LAT_Cord.name()))+", ";
            constraintShape+= ""+(p.getCoordinate(Point.PolarCoord.LON_Cord.name())==null? p.getCoordinate(Point.CartesianCoord.X_Cord.name()): p.getCoordinate(Point.PolarCoord.LON_Cord.name()))+" ";
        }   

      if (p.getCoordinateSize() > 2)
         constraintShape += ", " + (p.getCoordinate(Point.PolarCoord.R_Cord.name()) == null ? p.getCoordinate(Point.CartesianCoord.Z_Cord.name()) : p.getCoordinate(Point.PolarCoord.R_Cord.name()));

      constraintShape += ")," + sridCode + ")::geometry";

      queryConstraint = "ST_Distance_Sphere(" + queryConstraint +" , "+ constraintShape+")<="+updatedRadious();
      return queryConstraint;
   }

   @Override
   public void transformToCRS(QueryCRS toCRS) {
       if (GeometryMetadataHandler.getSupportedCRSMapping(this.espasCRS).isCartesian()||!this.espasCRS.equalsIgnoreCase(toCRS.espasValue())) {
           List<Point> transformedPoints = new LinkedList<Point>();
           PointCoordinateEditor pEditor = new PointCoordinateEditor(GeometryMetadataHandler.getSupportedCRSMapping(this.espasCRS), PointCoordinateEditor.SUPPORTED_GEOMETRY._3D);
           for (Point p : this.shapePoints) {
               double[] coordinates = new double[]{
                  p.getCoordinate(Point.PolarCoord.LON_Cord.name())==null? p.getCoordinate(Point.CartesianCoord.X_Cord.name()): p.getCoordinate(Point.PolarCoord.LON_Cord.name()), 
                  p.getCoordinate(Point.PolarCoord.LAT_Cord.name())==null?p.getCoordinate(Point.CartesianCoord.Y_Cord.name()):p.getCoordinate(Point.PolarCoord.LAT_Cord.name()), 
                  p.getCoordinateSize()<3?0.0:p.getCoordinate(Point.PolarCoord.R_Cord.name())==null?p.getCoordinate(Point.CartesianCoord.Z_Cord.name()):p.getCoordinate(Point.PolarCoord.R_Cord.name())};

               coordinates = pEditor.transformCRS(new Date(), coordinates,
                       GeometryMetadataHandler.getSupportedCRSMapping(this.espasCRS),
                       GeometryMetadataHandler.getSupportedCRSMapping(toCRS.espasValue()));
               Point tPoint = new Point();
               tPoint.setCoordinate(Point.PolarCoord.LAT_Cord.name(), coordinates[0]);
               tPoint.setCoordinate(Point.PolarCoord.LON_Cord.name(), coordinates[1]);
               
               if(p.getCoordinateSize()>2)
                  tPoint.setCoordinate(Point.PolarCoord.R_Cord.name(), coordinates[2]);
               
               transformedPoints.add(tPoint);
           }
           this.espasCRS = toCRS.espasValue();
           this.shapePoints = transformedPoints;
       }
      
   }
   
   protected double updatedRadious(){
//      if(super.espasCRS!=null && !super.espasCRS.isEmpty()){
//         CRSMapping crsMapping = GeometryMetadataHandler.getSupportedCRSMapping(espasCRS);
//         return crsMapping.getzScaleFactor()*circleRadious;
//      }
      return circleRadious;
   }
   
}
