/*
 * @(#) ReportPanel.java 1.0 99/10/4
 * Copyright (c) 1999 Larry Rodrigues
 */
package com.vistech.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.*;

/** Creates a panel to display the histogram and the statistics table.
  * @version 1.0  4 Oct 2000
  * @author Lawrence Rodrigues
  */

public class ReportPanel extends JComponent {
   protected BufferedImage image;
   protected int imageWidth = 0;
   protected int imageHeight = 0;
   protected int viewerWid = 500;
   protected int viewerHt = 300;
   protected MultiHistogram histogram;
   protected JTable imageStatsTable, roiStatsTable;

   protected String[][] imageData =null;
   protected String[][] roiData =null;
   protected String[] colNames = null;
   protected String[] roiColNames = null;
   protected Shape currentShape;
   protected String componentName[];

   protected SampleModel sampleModel;
   protected WritableRaster raster;
   protected DataBuffer dataBuffer;
   protected Dimension imageSize;
   protected int roiCount =0;
   protected String allRoiData[][] = new String[3][5];
   protected ROIContext roiContext;
   protected Vector roiCollection = new Vector();
   protected ROI2D currentROI;

   private boolean firstTime = true;
   private JTabbedPane jtp;
   private JFrame fr;
   private boolean guiCreated = false;

   public ReportPanel(){ }

   public ReportPanel(ROIContext roiContext){
      setROIContext(roiContext);
   }

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

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

   protected void analyzeAndUpdate(BufferedImage img){
      image = img;
      extractAttributes(img);
      if(guiCreated)  {
         updateHistogram();
         updateImageStatsTable(img);
      } else{
         histogram = createHistogram();
         imageStatsTable = createImageStatsTable(img);
         roiStatsTable = new JTable();
         createUI();
      }
   }

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

   private void createUI() {
      JScrollPane imjsp = new JScrollPane(imageStatsTable);
      imjsp.setBorder(BorderFactory.createTitledBorder("Image Statistics"));
      jtp = new JTabbedPane();
      jtp.add("Image ",imjsp );
      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(ROI2D roi){
      currentROI = roi;
      roiCollection.add(currentROI);
       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.getShape());
      roiCount = currentROI.getID();
   }

   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 = currentROI.getColumnNames();
      String[][] roiStats = currentROI.getStatsAsString();
      int numSamples = roiStats.length;
      allRoiData = null;

      int size = roiCollection.size();
      allRoiData = new String[size*roiStats.length][roiColNames.length];
      Iterator it = roiCollection.iterator();
      int i=0;
      while(it.hasNext()){
          ROI2D roi = (ROI2D)it.next();
          String[][] dat = roi.getStatsAsString();
          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 MultiHistogram createHistogram() {
      if((sampleModel == null) || (dataBuffer == null) || (imageSize == null)) return null;
      int[][] pix = ImageInfoUtil.getPixelSamples(sampleModel, dataBuffer, imageSize);
      MultiHistogram histo = new MultiHistogram();
      histo.setSize(400,300);
      String[] colstr = {"red sample", "green sample", "blue sample", "yellow"};
      Color[]  col = {Color.red, Color.green, Color.blue, Color.yellow};
      histo.setLegendOn(true);
      for (int i=0; i<pix.length;i++) {
           histo.addGraph(null, pix[i]);
           histo.addLegend(col[i], colstr[i]);
      }
      histo.setNumBars(6);
      histo.setTitleString("Histogram ");
      histo.setXLabelString("Pixel sample values");
      histo.setYLabelString("Frequency");
      return histo;
   }

   public void updateHistogram(){
      if((sampleModel == null) || (dataBuffer == null) || (imageSize == null)) return;
      int[][] pix = ROIUtil.getPixelSamples(sampleModel, dataBuffer, imageSize);
      updateHistogram(pix);
   }
   public void updateHistogram(Shape shape){
      if((sampleModel == null) || (dataBuffer == null) || (shape == null)) return;
      int[][] pix = ROIUtil.getROIPixelSamples(sampleModel,dataBuffer, shape);
      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(null, data[i]);
           histogram.addLegend(col[i], colstr[i]);
      }
      histogram.draw();
      histogram.repaint();
   }

   protected JTable createImageStatsTable(BufferedImage img) {
      ColorModel cm = img.getColorModel();
      imageWidth = img.getWidth();
      imageHeight = img.getHeight();
      ColorSpace cs = cm.getColorSpace();
      int numComponents = cs.getNumComponents();
      componentName = new String[numComponents];
      for(int i=0;i<numComponents;i++){
           componentName[i] = cs.getName(i);
      }
      updateImageStatsTable(img);
      TableModel dataModel = new AbstractTableModel() {
          public String getColumnName(int column) {
             return  colNames[column];
          }
          public int getColumnCount() { return colNames.length;}
          public int getRowCount() {return imageData.length;}
          public Object getValueAt(int row, int col) {
             return imageData[row][col];
         }
      };
      JTable table = new JTable(dataModel);
      return new JTable(dataModel);
   }

   public void updateImageStatsTable(BufferedImage img) {
      int[][] imstats = ImageInfoUtil.getImageStats(img);
      colNames = new String[] {"Sample", "Min", "Max", "Mean", "Area"};
      imageData = new String[imstats.length][colNames.length];

      for(int i=0; i<imstats.length;i++){
          imageData[i][0] = componentName[i];
          for(int j=0;j<colNames.length-1;j++){
              imageData[i][j+1] = Integer.toString(imstats[i][j]);
          }
      }
      if(roiStatsTable  != null){
         roiStatsTable.repaint();
         repaint();
      }
   }

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