

import java.awt.*;
import javax.swing.*;

import cds.aladin.*;
import cds.tools.*;

public class MouseTrackPlug extends AladinPlugin implements VOObserver {
   
   public String menu() { return "Mouse Tracking"; }
   public String description()   {
      return "PLUGIN TUTORIAL:\n" +
             "This plugin is an example VOObserver usage and real pixel access.\n" +
             "This plugin uses VOObserver callback method for displaying the " +
             "pixel values around the mouse. It displays the result in a JFrame panel.";
   }   
   public String author()        { return "Pierre Fernique [CDS]"; }
   public String version()       { return "1.1 - January 2007"; }
   public String url() { return "http://aladin.u-strasbg.fr/java/Plugins/MouseTrackPlug.java"; }
   public String category()      { return "Plugin tutorial"; }
   
   static private int SIZE = 5;     // Grid size
   private JLabel cell[][]=null;    // Grid of cells
   
   /*
    * Usage of VOObserver interface to track Aladin mouse clicks
    * 1) Create Java Swing objects to generate a grid of cells
    * 2) register itself has a Aladin VOObserver for POSITION
    */
   public void exec() {
      
      // Already active => nothing to do
      if( active ) return;
      active=true;
      
      // Create the grid of cells
      f = new JFrame();
      f.getContentPane().setLayout(new GridLayout(SIZE,SIZE,2,2));
      cell = new JLabel[SIZE][SIZE];
      for( int y=0; y<SIZE; y++ ) {
         for( int x=0; x<SIZE; x++ ) {
            cell[y][x] = new JLabel();
            cell[y][x].setPreferredSize(new Dimension(60,60));
            cell[y][x].setBorder(BorderFactory.createEtchedBorder());
            if( x==SIZE/2 && y==SIZE/2 ) cell[y][x].setForeground(Color.red);

            f.getContentPane().add(cell[y][x]);
         }
      }
      f.pack();
      f.setVisible(true);
     
      // Register itself has a VOObserver of Aladin positions
      aladin.addObserver(this,VOApp.POSITION);
   }
   
   private JFrame f;
   private boolean active=false;
   
   /** VOObserver methods (called by aladin when the user clicks on the mouse */
   public void position(double ra,double dec) {
      try {
         
         // Get information on current image
         AladinData sd = aladin.getAladinImage();
         int width = sd.getWidth();
         int height = sd.getHeight();
         
         // get x,y image position corresponding to the current sky position ra,dec
         double xy[] = sd.getXY(ra,dec);
         int X = (int)(xy[0]-0.5);
         int Y = (int)(xy[1]-0.5);
         
         // Fill the cells of the grid with corresponding pixel values
         
         // The simplest method (but really slow) is to use sd.getPixels() which
         // provide full pixel values in doubles
//         double [][] pix = sd.getPixels();
//         int i,j;
//         int x,y;
//         for( j=0, y=Y+SIZE/2; j<SIZE; j++,y-- ) {
//            for( i=0, x=X-SIZE/2; i<SIZE; i++,x++ ) {
//               if( x>=0 && x<width && y>=0 && y<height ) {
//                  cell[j][i].setText( pix[x][y] +"" );
//               } else cell[j][i].setText("-");
//            }
//         }
         

         // An very fast alternative method is to use a direct access to the internal
         // Aladin full pixel buffer. But in this case, you have to apply yourself the required
         // pixel transformations
         byte pix[] = sd.seeCodedPixels();
         int bitpix = sd.getFitsBitPix();
         double bzero = sd.getFitsBzero();
         double bscale = sd.getFitsBscale();
         int i,j;
         int x,y;
         for( j=0, y=Y+SIZE/2; j<SIZE; j++,y-- ) {
            for( i=0, x=X-SIZE/2; i<SIZE; i++,x++ ) {
               if( x>=0 && x<width && y>=0 && y<height ) {
                  double pixVal = sd.CodedPixelsToDouble(pix, bitpix, y*width + x);
                  cell[j][i].setText( (pixVal*bscale+bzero) +"" );
               } else cell[j][i].setText("-");
            }
         }
         
      } catch( AladinException e ) { e.printStackTrace(); }
      
   }
   
   /** VOObserver methods (called by aladin when the user clicks on the mouse
    * => Not used here
    */
   public void pixel(double pixValue) { }
   
   /** Can be called by Aladin to know the state of plugin */
   public boolean isRunning() { return active; }
   
   /** Call by Aladin during a manual plugin stop */
   public void cleanup() {
      if( !active ) return;
      aladin.addObserver(this,0);
      f.dispose();
      active=false;
   }
   

   
}