
import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Iterator;



class Dataset
{

   FormatResponseFilter.ObsCore obsCore;

   class Access
   {
      String accessFileUrl;
      String accessCutoutUrl;
      String accessMosaicUrl;
   }

   static class Vertices
   {
      final int VERT_COUNT = 4;
      double[] lon = new double[VERT_COUNT];
      double[] lat = new double[VERT_COUNT];
   }


   String subsurvey_id;
   int overlapCodeSky;
   int overlapCodeVel;
   int overlapCode;
   String dataType;
   String publisherDid;
   Access access;
   Vertices vertices_deg;

   Dataset()
   {
      access = new Access();
      vertices_deg = new Vertices();
   }


   // create merged dataset if possible


   public static boolean areDatasetsMergeable(List<Dataset> datasetList)
   {
      if(datasetList.size() > 1 )
      {
         String dataType = datasetList.get(0).dataType;
         for(Dataset ds : datasetList)
         {
            if(!ds.dataType.equals(dataType)) return false;
         }
      }
      return (datasetList.size() > 1) && (! hasFullOverlap(datasetList));
   }


   public Dataset(List<Dataset> datasetList, AuthPolicy auth, Coord coord, SubsurveyId subsurveyId, String mergeUrlRoot)
   {
      this.subsurvey_id = datasetList.get(0).subsurvey_id; // mergeabiity condition is more then 1 element in list
      this.overlapCode  = 5; // 5: exact match --> legacy used 0 here FIXME 5 will not be correct on edges of Subsurvey coverage
      this.publisherDid = mergePublisherDids(datasetList);
      this.dataType     = datasetList.get(0).dataType;

      this.access = new Access();
      this.access.accessFileUrl   = null;
      this.access.accessCutoutUrl = null;
      this.access.accessMosaicUrl = mergeUrlRoot + "?pubdid=" + publisherDid + "&amp;" + coord.toVoQueryString();

      this.vertices_deg = mergeVertices(datasetList, /*inputs.*/coord);
   }


   private static boolean hasFullOverlap(List<Dataset> datasetList)
   {
      Iterator<Dataset> it = datasetList.iterator();
      while(it.hasNext())
      {
         Dataset dataset = it.next();
         // 2: datacube inside inout, 3: inpout inside datacube, 5: two regions are identical
         boolean fullOverlapExist =  (dataset.overlapCode == 2) || (dataset.overlapCode == 3) || (dataset.overlapCode == 5); 
         if(fullOverlapExist) return true;
      }
      return false;
   }


   private String mergePublisherDids(List<Dataset> datasetList)
   {
      StringBuilder sb = new StringBuilder();

      for (ListIterator<Dataset> it = datasetList.listIterator(); it.hasNext(); )
      {
         Dataset ds = it.next();
         // FIXME max URL line length(?) iNet: recommendation 8000 octets or use POST
         sb.append(";" + ds.publisherDid);
      }

      return sb.toString();
   }


   private Vertices mergeVertices(List<Dataset> datasetList, Coord coord)
   {
      // FIXME for now simply return input defined rectangle vertices
      // which is not correct on edges of survey coverage

      double ll=coord.lon, bb=coord.lat;
      double dll=0, dbb=0; // FIXME why compilers errors (not warning): need to be inited ?

      switch(coord.shape)
      {
         case "CIRCLE" :
            dll = coord.radius;
            dbb = coord.radius;
            break;
         case "RECT" :
            dll = coord.dlon;
            dbb = coord.dlat;
            break;
         default:
            // FIXME internnal error
      }

      Vertices vert = new Vertices();

      vert.lon[0] = ll + dll;
      vert.lat[0] = bb + dbb;
      vert.lon[1] = ll + dll;
      vert.lat[1] = bb - dbb;
      vert.lon[2] = ll - dll;
      vert.lat[2] = bb + dbb;
      vert.lon[3] = ll - dll;
      vert.lat[3] = bb - dbb;

      return vert;
   }

}

