/*
 * @(#) ROIStatsPanel.java 1.0 99/10/4
 * Copyright (c) 1999 Larry Rodrigues
 */
package com.vistech.jai.roi;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.io.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.color.*;
import vis.beans.plotter.*;
import com.vistech.util.*;
import java.util.*;
import com.vistech.roi.*;
import javax.media.jai.*;
import java.awt.image.renderable.*;
import java.beans.*;

/** Creates a panel to display the histogram and the statistics table.
  * @version 1.0  4 Oct 2000
  * @author Lawrence Rodrigues
  */
public class ROIStatsPanel extends JComponent {
   protected PlanarImage image;
   protected int imageWidth = 0;
   protected int imageHeight = 0;
   protected int viewerWid = 500;
   protected int viewerHt = 300;
   protected int  offsetX = 0, offsetY = 0;
   protected MultiXYPlot histogram;
   protected JTable imageStatsTable, roiStatsTable;

   protected String[][] roiData =null;
   protected String[] colNames = null;
   protected String[] roiColNames = null;

   protected String componentNam[];
   protected boolean guiCreated = false;
   protected SampleModel sampleModel;
   protected WritableRaster raster;
   protected DataBuffer dataBuffer;
   protected Dimension imageSize;
   protected int roiCount =0;
   protected String allRoiData[][] = new String[3][5];
   protected ROIContextJAI roiContext;
   protected Vector roiCollection = new Vector();
   protected ROIShape currentROI;
   boolean firstTime = true;
   protected JTabbedPane jtp;
   protected  int[] xVal = null;

   public ROIStatsPanel(){ }

   public ROIStatsPanel(ROIContextJAI roiContext){ setROIContext(roiContext);}

   public void setROIContext(ROIContextJAI roiContext){
      PlanarImage img = roiContext.getOriginalImage();
      if(img == null) return;
      (new Thread(new Analyze(img))).start();
   }

   class Analyze implements Runnable {
      PlanarImage bi;
      public Analyze(PlanarImage img) {bi = img; }
      public void run() { analyzeAndUpdate(bi);}
   }

   protected synchronized void analyzeAndUpdate(PlanarImage img){
      image = img;
      extractAttributes(img);
      if(guiCreated){ updateHistogram();}
      else{
        histogram = createHistogram();
        roiStatsTable = new JTable();
        createUI();
      }
   }

   private void extractAttributes(PlanarImage img){
      sampleModel = img.getSampleModel();
      raster = img.copyData();
      dataBuffer = raster.getDataBuffer();
      imageSize= new Dimension(img.getWidth(), img.getHeight());
   }

   private void createUI() {
      jtp = new JTabbedPane();
      setLayout(new GridLayout(1,2));
      add(histogram);
      add(jtp);
      histogram.repaint();
      setBorder(BorderFactory.createTitledBorder("ROI Analysis"));
      guiCreated = true;
   }

   public void setWidHt(Dimension d) {
      viewerWid = d.width;
      viewerHt = d.height;
      setSize(viewerWid, viewerHt);
   }

   public void addROI(ROIShape roi){
      currentROI = roi;
      if(firstTime) {
         roiStatsTable = createROIStatsTable();
         firstTime = false;
         JScrollPane roijsp = new JScrollPane(roiStatsTable);
         roijsp.setBorder(BorderFactory.createTitledBorder("ROI Statistics"));
         jtp.add("ROI ", roijsp);
         jtp.setSelectedComponent(roijsp);
      }
      else updateROIStatsTable();
      updateHistogram(roi.getAsShape());
      roiCount++;
  }

   protected JTable createROIStatsTable() {
      updateROIStatsTable();
      TableModel dataModel = new AbstractTableModel() {
          public String getColumnName(int column) {
             if(currentROI == null) return null;
             return  roiColNames[column];
          }
          public int getColumnCount() {
             if(currentROI == null) return 0;
             return roiColNames.length;
          }
          public int getRowCount() {
             if(allRoiData == null) return 0;
             return allRoiData.length;
          }
          public Object getValueAt(int row, int col) {
             if(allRoiData == null) return null;
             if((row >= allRoiData.length)||(col >= allRoiData[0].length)) return null;

             return allRoiData[row][col];
         }
      };
      JTable table = new JTable(dataModel);
      return new JTable(dataModel);
   }

   public void updateROIStatsTable(){
      if(currentROI == null) return;
      roiColNames = new String[] {"ROI num", "band", "min", "max", "average"};
      double minmax[][] = ROIStats.getMinMax(image, currentROI);
      double mean[] =  ROIStats.getMean(image, currentROI);
      int numSamples = mean.length;
      String[][] roiStats = new String[numSamples][5];
      String colstr[];
      if(numSamples >1 )
         colstr = new String[] {"red", "green", "blue", "alpha"};
      else colstr = new String[] {"grey"};
      for(int i=0;i<numSamples;i++) {
          roiStats[i][0] = Integer.toString(roiCount);
          roiStats[i][1] = colstr[i];
          roiStats[i][2] = Double.toString(minmax[0][i]);
          roiStats[i][3] = Double.toString(minmax[1][i]);
          roiStats[i][4] = Double.toString(mean[i]);
      }

      allRoiData = null;
      roiCollection.add(roiStats);
      int size = roiCollection.size();
      allRoiData = new String[size*roiStats.length][roiColNames.length];
      Iterator it = roiCollection.iterator();
      int i=0;
      while(it.hasNext()){
          String[][] dat = (String[][])it.next();
          if(dat == null){
             i++; continue;
          }
          for(int j=0; j< numSamples; j++){
              for(int k=0;k<roiColNames.length;k++)
                  allRoiData[i*numSamples+j][k] =  dat[j][k];
          }
          i++;
      }
      if(roiStatsTable  != null){
         roiStatsTable.revalidate();
         repaint();
      }
   }

   public MultiXYPlot createHistogram() {
      String[] colstr;
      Color[]  col = {Color.red, Color.green, Color.blue, Color.yellow};
      int[][] data = ROIStats.computeHistData(image,12);
      if(data == null) return null;
      int numbands = data.length;
      if(numbands >1 )
         colstr = new String[] {"red sample", "green sample", "blue sample", "yellow"};
      else colstr = new String[] {"grey"};
      
      int binWidth = 20;
      int numBins = data[0].length;
      xVal = new int[numBins];
      for (int i=0;i< numBins;i++)  xVal[i] = i*binWidth;
      try {
         ClassLoader cl = (MultiXYPlot.class).getClassLoader();
         MultiXYPlot xyp = (MultiXYPlot)Beans.instantiate(cl, "vis.beans.plotter.MultiXYPlot");
         xyp.setSize(400,300);
         xyp.setLegendOn(true);
         for(int i=0; i<numbands;i++) {
             xyp.addGraph(xVal, data[i]);
             xyp.addLegend(col[i], colstr[i]);
         }
         xyp.setTitleString("Histogram  ");
         xyp.setXLabelString("Sample Values");
         xyp.setYLabelString("Frequency");
         xyp.repaint();
         return xyp;
      } catch(Exception  e) {
        return null;
      }
   }

   public void updateHistogram(){
      if((sampleModel == null) || (dataBuffer == null) || (imageSize == null)) return;
      int[][]  pix = ROIStats.computeHistData(image, currentROI,12);
      updateHistogram(pix);
   }
   public void updateHistogram(java.awt.Shape shape){
      if((sampleModel == null) || (dataBuffer == null) || (shape == null)) return;
      int[][]  pix = ROIStats.computeHistData(image, currentROI, 12);
      updateHistogram(pix);
   }

   public void updateHistogram(int[][] data){
      histogram.resetPlotViewport();
      String[] colstr = {"red sample", "green sample", "blue sample", "yellow"};
      Color[]  col = {Color.red, Color.green, Color.blue, Color.yellow};
      histogram.setLegendOn(true);
      for (int i=0; i<data.length;i++) {
           histogram.addGraph(xVal, data[i]);
           histogram.addLegend(col[i], colstr[i]);
      }
      histogram.draw();
      histogram.repaint();
   }

   public void reset() {
      roiCount = 0;
      currentROI = null;
      allRoiData = new String[3][5];
      roiCollection = new Vector();
      if(roiStatsTable != null) roiStatsTable.revalidate();
   }
 }
