
import java.io.InputStream;
import java.util.Iterator;

import cds.aladin.AladinData;
import cds.aladin.AladinPlugin;
import cds.aladin.Ligne;
import cds.aladin.Obj;
import cds.aladin.RepereSpectrum;
import cds.aladin.SourceStat;
import cds.tools.VOApp;
import cds.tools.VOObserver;

public class PhotControlPlug extends AladinPlugin implements VOObserver,VOApp {
   
   static String planeName = "PhotTool";
   AladinData ad=null;
   
   public String menu() { return "Photometry tool manipulation"; }
   public String description() {
      return "PLUGIN TUTORIAL:\n" +
      "This plugin is an example for photometry tools manipulation.\n" +
      "This plugin extracts the spectrum at the mouse position.";
   }   
   public String version()     { return "1.0 - February 2021 -  - required Aladin >= v11.040"; }
   public String author()      { return "Pierre Fernique [CDS]"; }
   public String url()         { return "http://aladin.u-strasbg.fr/java/Plugins/PhotControlPlug.java"; }
   
   public void exec() {
      // Register this plugin as a VOObserver (see execCommand() method)
      aladin.addObserver(this,VOApp.MEASURE | VOApp.STACKEVENT);
      
      // get or create a dedicated tool plane
      try {
         ad = getOrCreateToolPlane();
         System.out.println("The phot tools must be stored in \""+ad.getLabel()+"\" tool plane");
      } catch( Exception e ) { e.printStackTrace(); }
      
   }
   
   // Find or create a tool plane
   private AladinData getOrCreateToolPlane() throws Exception {
      
      // Is there already a Tool Plane in the Aladin stack ?
      String [] planeID = aladin.getAladinStack();
      for( int i=0; i<planeID.length; i++ ) {
         AladinData sd = aladin.getAladinData(planeID[i]);
         if( sd.getPlaneType().indexOf("Tool")>=0 ) return sd;
      }
      
      // otherwise, create one
      return aladin.createAladinTool(planeName);
   }
   
   // Call by Aladin when the stack is modified, or an event on phot tools occured
   public String execCommand(String cmd) {
      System.out.println("Aladin event: => "+cmd);
      rescanPhotTool();
      return "";
   }
   
   // Scanning the dedicated Tool plane generated by the Plugin
   // and display the statistics associated to each Phot objects (Cicle, Polygon)
   private void rescanPhotTool() {
      try {
         
         // Get the plane in background
         AladinData adbg = aladin.getAladinImage();
         String planeType = adbg.getPlaneType();
         System.out.println("Phot stats from "+adbg.getLabel()+" plane ("+planeType+")...");
         boolean isCube = planeType.indexOf("Blink")>=0 || planeType.indexOf("Cube")>=0;
         
         // Scanning of the Tool objects in the dedicated tool plane
         Iterator<Obj> it = ad.iteratorObj();
         while( it.hasNext() ) {
            Obj o = it.next();
            if( !o.hasPhot() || !o.isVisible() ) continue;
            
            double stats [] = o.getStatistics(adbg);
            if( stats==null ) continue;
            
            String type = o instanceof Ligne ? "polygon" 
                        : o instanceof SourceStat ? "circle" 
                        : o instanceof RepereSpectrum ? "point" 
                        : "Other??";
            
            System.out.println("Obj "+type+" hash="+o.hashCode()
               +"=>  cnt="+stats[0]+",sum="+stats[1]+",sigma="+stats[2]+",surf="+stats[3]+",min="+stats[4]+",max="+stats[5]);
            
            // For a cube, also compute stats for the middle frame and the last frame of the cube
            if( isCube ) {
               int z = adbg.getDepth();
               stats = o.getStatistics(adbg, z/2 );
               System.out.println("      middle frame ("+(z/2)+"): "
                  +"=>  cnt="+stats[0]+",sum="+stats[1]+",sigma="+stats[2]+",surf="+stats[3]+",min="+stats[4]+",max="+stats[5]);
               
               stats = o.getStatistics(adbg, z-1 );
               System.out.println("      last frame ("+(z-1)+") : "
                  +"=>  cnt="+stats[0]+",sum="+stats[1]+",sigma="+stats[2]+",surf="+stats[3]+",min="+stats[4]+",max="+stats[5]);
            }

            // Pixels access (by triplet array) - display 2 values here
            double [] raDecVal = o.getStatisticsRaDecPix(adbg,0);
            if( raDecVal.length>0 ) {
               int i=0;
               System.out.println("First pixel "+(i/3)+" (frame 0) ra="+raDecVal[i]+" dec="+raDecVal[i+1]+" pix="+raDecVal[i+2]);
               i = raDecVal.length-3;
               System.out.println("Last pixel  "+(i/3)+" (frame 0) ra="+raDecVal[i]+" dec="+raDecVal[i+1]+" pix="+raDecVal[i+2]);
            }
         }
      } catch( Exception e ) { e.printStackTrace(); }
   }
   
   
   // VOApp & VOObserver methods (not used here)
   public String putVOTable(InputStream in, String label) { return null; }
   public String putVOTable(VOApp app, InputStream in, String label) { return null; }
   public InputStream getVOTable(String dataID) { return null; }
   public String putFITS(InputStream in, String label) { return null; }
   public InputStream getFITS(String dataID) { return null; }
   public void showVOTableObject(String[] oid) { }
   public void selectVOTableObject(String[] oid) { }
   public void setVisible(boolean flag) { }
   public void addObserver(VOObserver app, int eventMasq) { }
   public void position(double raJ2000, double deJ2000) { }
   public void pixel(double pixValue) { } 
}