/*
 * @(#) JAIRoiUtil.java 1.0 2000/11/21
 * Copyright (c) 1999 Larry Rodrigues
 */
package com.vistech.jai.roi;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.image.renderable.*;
import java.io.*;
import com.vistech.jai.render.*;
import javax.media.jai.*;

/**
  * A utility class that provides a number of static methods for creating ROI objects.
  * @version 1.0  21 Nov 2000
  * @author Lawrence Rodrigues
  */
public class JAIROIUtil {
   public static TiledImage createTiledImage(PlanarImage image){
      SampleModel sampleModel = image.getSampleModel();
      ColorModel colorModel = image.getColorModel();
      TiledImage tlImage = new TiledImage(image.getMinX(), image.getMinY(),
                                    image.getWidth(), image.getHeight(),
                                    image.getTileGridXOffset(), image.getTileGridYOffset(),
                                    sampleModel, colorModel);
      tlImage.setData(image.copyData());
      return tlImage;
   }

   public static ROI[] createThresholdROI(ROI[] baseROI,
                                          ROIShape roi,
                                          int thresh) {
      if((roi == null)|| (baseROI == null)) return null;
      ROI[] roiT = new ROI[baseROI.length];
      for(int i=0; i<baseROI.length;i++) {
          baseROI[i].setThreshold(thresh);
          roiT[i] = roi.intersect(baseROI[i]);
      }
      return roiT;
   }

   public static TiledImage createThresholdImage(TiledImage image,
                                                 ROI[] roiImage,
                                                 ROIShape roi) {
      int numbands = roiImage.length;
      Rectangle bounds = roi.getBounds();
      Vector vect = new Vector();
      for(int j = bounds.x; j< bounds.x+bounds.width;j++) {
          for(int k = bounds.y; k< bounds.y+bounds.height;k++) {
              if(roi.contains(j,k)){
                 Point pix = new Point(j,k);
                 vect.add(pix);
              }
          }
      }
      Point ptarray[] = new Point[vect.size()];
      vect.copyInto(ptarray);
      int leftIndex = image.XToTileX(bounds.x);
      int rightIndex = image.XToTileX(bounds.x + bounds.width - 1);
      int topIndex = image.YToTileY(bounds.y);
      int bottomIndex = image.YToTileY(bounds.y + bounds.height - 1);
      PlanarImage img[] = createBandImages(image);//temp fix
      for(int tj = topIndex; tj <= bottomIndex; tj++) {
          for(int ti = leftIndex; ti <= rightIndex; ti++) {
              WritableRaster tile = image.getWritableTile(ti, tj);
              int[] bandlist = new int[1];

              for(int i=0;i< roiImage.length;i++){
                  bandlist[0] =i;
                  WritableRaster multiBandROI = tile.createWritableChild(bounds.x, bounds.y,
                                                 bounds.width, bounds.height,
                                                 bounds.x, bounds.y, bandlist);
                 
                  for(int p =0;p<ptarray.length;p++) {
                      int arr[] = new int[1];
                      int x = ptarray[p].x;
                      int y = ptarray[p].y;
                      int samp = roiImage[i].getAsImage().getData().getSample(x,y,0);
                      multiBandROI.setSample(x,y,0,samp);
                  }
             }
             image.releaseWritableTile(ti,tj);
          }
      }
      return image;
   }
   
   public static ROI[] createROIFromImage(RenderedImage  image) {
      int numbands = image.getSampleModel().getNumBands();
      ROI[] roi = new ROI[numbands];
      if(numbands == 1) {
         roi[0] = new ROI(image);
         return roi;
      }
      int[] bandindices = new int[1];
      for(int i=0;i<numbands;i++){
          bandindices[0] =i;
          RenderedOp opImage = JAI.create("bandselect", image,bandindices);
          roi[i] = new ROI((PlanarImage)opImage);
      }
      return roi;
   }
 
   //This method was added as a temporory fix to 
   // make thresholding work with JAI 1.1.
   public static TiledImage createThresholdImage(TiledImage image,
                                                 ROI[] roiImage,
                                                 ROIShape roi,
                                                 int thresh,
                                                 int mask) throws JAIROIException {
      
      try {
         int numbands = roiImage.length;
         Rectangle bounds = roi.getBounds();
         Vector vect = new Vector();
         for(int j = bounds.x; j< bounds.x+bounds.width;j++) {
             for(int k = bounds.y; k< bounds.y+bounds.height;k++) {
                 if(roi.contains(j,k)){
                    Point pix = new Point(j,k);
                    vect.add(pix);
                 }
             }
         }
         Point ptarray[] = new Point[vect.size()];
         vect.copyInto(ptarray);
         int leftIndex = image.XToTileX(bounds.x);
         int rightIndex = image.XToTileX(bounds.x + bounds.width - 1);
         int topIndex = image.YToTileY(bounds.y);
         int bottomIndex = image.YToTileY(bounds.y + bounds.height - 1);
         PlanarImage img[] = createBandImages(image);
         for(int tj = topIndex; tj <= bottomIndex; tj++) {
             for(int ti = leftIndex; ti <= rightIndex; ti++) {
                 WritableRaster tile = image.getWritableTile(ti, tj);
                 int[] bandlist = new int[1];

                 for(int i=0;i< roiImage.length;i++){
                     bandlist[0] =i;
                     WritableRaster multiBandROI = tile.createWritableChild(bounds.x, bounds.y,
                                                 bounds.width, bounds.height,
                                                 bounds.x, bounds.y, bandlist);
                

                     for(int p =0;p<ptarray.length;p++) {
                         int arr[] = new int[1];
                         int x = ptarray[p].x;
                         int y = ptarray[p].y;
                         int samp = img[i].getData().getSample(x,y,0);
                         if (samp > thresh) samp = mask;
                         //int samp = roiImage[i].getAsImage().getData().getSample(x,y,0);
                         multiBandROI.setSample(x,y,0,samp);
                    }
                 }
                 image.releaseWritableTile(ti,tj);
            }
         }
      }catch (Exception e) {
         JAIROIException ex = new JAIROIException("Thresholding error");
         throw(ex);
      }finally {
         return image;
      }
   }
   
  
   //This method was added as a temporory fix to make the thresholding with JAI 1.1.
   public static PlanarImage[] createBandImages(PlanarImage  image) {
      int numbands = image.getSampleModel().getNumBands();
      PlanarImage[] plimage = new PlanarImage[numbands];
      if(numbands == 1) {
         plimage[0] = image;
         return plimage;
      }
      int[] bandindices = new int[1];
      for(int i=0;i<numbands;i++){
          bandindices[0] =i;
          RenderedOp opImage = JAI.create("bandselect", image,bandindices);
          plimage[i] = (PlanarImage)opImage;
      }
      return plimage;
   }

}