/*
 *
 *  Copyright (C) 1999, Institute for MicroTherapy
 *
 *  This software and supporting documentation were developed by
 *
 *    University of Witten/Herdecke
 *    Department of Radiology and MicroTherapy
 *    Institute for MicroTherapy
 *    Medical computer science
 *    
 *    Universitaetsstrasse 142
 *    44799 Bochum, Germany
 *    
 *    http://www.microtherapy.de/go/cs
 *    mailto:computer.science@microtherapy.de
 *
 *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND THE INSTITUTE MAKES  NO 
 *  WARRANTY REGARDING THE SOFTWARE, ITS PERFORMANCE, ITS MERCHANTABILITY
 *  OR FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES 
 *  OR ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY 
 *  AND PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
 *
 *
 *  Author :      $Author: kleber $
 *  Last update : $Date: 2001/06/06 10:32:29 $
 *  Revision :    $Revision: 1.1.1.1 $
 *  State:        $State: Exp $
*/

package dicomPrint;
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import main.*;
import javax.swing.border.*;
import J2Ci.*;

/**
 * This class contains the GUI for a page of a print job. 
 * This page can have the orientation portrait ( portrait = true)
 * or landscape (portrait = false) and will be drawn in a JPanel. 
 * The page have a table of PrintImagePreviews. 
 * @author Klaus Kleber
 */
public class PreviewPanel extends JPanel
{

     /**
     * Contains the PrintImagePreview of this page
     */
     private PrintImagePreview[] printImagePreviewList;
     /**
      * Contains the current jDVPSStoredPrint
      */
     private jDVPSStoredPrint storedPrint;

    /**
     * Contains the x -coordiante for the page
     */
    private int x;

    /**
     * Contains the y - coordinate for the page
     */
    private int y;

    /**
     * Contains the height of the page
     */
    private int h;

    /**
     * Contains the width of the page
     */
    private int w;

    /**
    * Width of a film box
    */
    private double filmBoxWidth ;
    /**
    * Height of a film box
    */
    private double filmBoxHeight;
    /**
    * Default width of a film box
    */
    private double defaultFilmBoxWidth = 11;
    
    /**
    * Default height of a film box
    */
    private double defaultFilmBoxHeight = 14;
    
    /**
    * DVI Interface
    */
    private jDVInterface dvi;
    
    /**
     * Contains the current page
     */
    private JPanel page = new JPanel();

    /**
     * if true the page will be portrait, esle landscape
     */
    private boolean portrait = true;

    /**
     * Contains the minimum border size 
     */
    private int border = 10;

    /**
     * Conatins the distance between the PrintImagePreview
     */
    private int gaps = 5;

    /**
     * Contains the current number of cols
     */
    private int cols = 1;

    /**
     * Contains the current number of rows
     */
    private int rows = 1;

    /**
     * Contains the current MouseHandler.
     */
    private PreviewMouseHandler previewMouseHandler;

    /**
     * Contains the current size for the PreviewPanel
     */
     private Dimension size = new Dimension();

    
    
    /**
    * Default value for the empty image
    */
    private Color defaultEmptyImageColor = Color.black;
    
    /**
     * Contains the color of the film
     */
    private Color emptyImageColor = defaultEmptyImageColor;
    
    
    /**
    * Default value for the film
    */
    private Color defaultFilmColor = Color.black;
    /**
     * Contains the color of the film
     */
    private Color filmColor = defaultFilmColor;
    
    /**
    * true, if last page should be displayed, else the first page will be displayed;
    */
    private boolean showLastPage = false;
    
    /**
    * True if the PrintImagePreview should displayed as Hardcopy. 
    * If false the PrintImagePreview will displayed as Softcopy
    */
    private boolean printLUT = true;
    
    private boolean notifyBrowser = false;
    
    
    /**
     * Constructor.
     * @param previewMouseHandler Contains the current MouseHandler.
     * @param cols Contains the number of cols.
     * @param rows Contains the number of rows.
     * @param storedPrint Contains the current jDVPSStoredPrint Object.
     * @param dvi Contains the current jDVInterface Object.
     */
    public PreviewPanel(PreviewMouseHandler previewMouseHandler, int cols, int rows,jDVPSStoredPrint storedPrint, jDVInterface dvi)
    {
        this.storedPrint = storedPrint;
        this.dvi = dvi;
        setLayout(null);
        //setBackground(backgroundColor);
        
        this.previewMouseHandler= previewMouseHandler;
        this.cols = cols;
        this.rows = rows;
        filmBoxWidth = defaultFilmBoxWidth;
        filmBoxHeight = defaultFilmBoxHeight;
        
    }

    /**
     * Paints the component in the specified Graphics object
     * @param g Graphics
     */
    public synchronized void paintComponent(Graphics g)
    {
        if (! size.equals(getSize()))
        {
            size =  getSize();
            calculatePage();
        }
        page.validate();
        
        super.paintComponent(g);
    }

    /**
     * Calculates the the page 
     */
    private void calculatePage()
    {
        
        //Removes all obejcts
        removeAll();
        page.removeAll();
        //Calculates the sizes for portrait
        if (portrait)
        {
            
            h = size.height-border;
            w = (int)(h*(filmBoxWidth/filmBoxHeight));
            if (w > size.width-border)
            {
                double scaling = (double)w/(double)(size.width-border);
                
                h = (int)(h/scaling);
                w = size.width-border;
            }
        }
        //Calculates the size for landscape
        else
        {
            w = size.width-border;
            h = (int)(w*(filmBoxWidth/filmBoxHeight));
            if (h > size.height-border)
            {
                double scaling = (double)h/(double)(size.height-border);
                w = (int)(w/scaling);
                h= size.height-border;
            }
            
        }   
        
        //Sets the size of the page
        page.setSize(new Dimension(w, h));
        
        //Sets the location of the page
        x = (size.width-w)/2;
        y = (size.height-h)/2;
        page.setLocation(x,y);
        
        page.setBackground(filmColor);
        page.setBorder(new EmptyBorder(gaps, gaps,gaps,gaps));
        page.setLayout(new GridLayout(rows,cols,gaps,gaps));
        
        printImagePreviewList = new PrintImagePreview[rows*cols];
        
        int numberOfVisible = Math.min(rows*cols, storedPrint.getNumberOfImages());
        
        int pagesInJob = storedPrint.getNumberOfImages()/printImagePreviewList.length;
        if (storedPrint.getNumberOfImages()%printImagePreviewList.length>0)pagesInJob++;
        int offset = 0;
        for (int i = 0; i <printImagePreviewList.length; i++) 
        {
            
            
            
            PrintImagePreview im = new PrintImagePreview(offset+i,emptyImageColor, filmColor, dvi, printLUT);
            
            if ((i <numberOfVisible)|| ((numberOfVisible ==0)&& (storedPrint.getNumberOfImages()!= 0))) 
            {
                im.setReferToImage();
                im.setParameter(havePrintSettings(offset+i));
            }
            printImagePreviewList[i] = im;
            im.addMouseListener(previewMouseHandler);
            page.add(im);
        }
        if (notifyBrowser)
        {
            if ((printImagePreviewList!=null) &&(printImagePreviewList.length >0))
            {
                //Zero ist the last printed Componenet
                //Bad hack
                printImagePreviewList[0].notifyBrowser = true;
            }
            notifyBrowser = false;
        }
        
        add(page);
    }
   
    /**
     * Sets the orentation of the page. If portrait = true the page will be displayed in 
     * portrait else in landscape.
     * 
     * @param portrait If portrait = true the page will be displayed in 
     * portrait else in landscape.
     */
    public synchronized void setOrientation(boolean portrait)
    {
        if (this.portrait != portrait)
        {
            this.portrait = portrait;
            calculatePage();
            repaint();
            page.updateUI();
        }
    }


    /**
     * Sets rows and cols of the page
     * @param rows Number of cols of the page
     * @param cols Number of cols of the page
     */
    public synchronized void setRowsCols(int rows, int cols)
    {
            this.cols = cols;
            this.rows = rows;
            
            calculatePage();
            repaint();
            page.updateUI();
    }

    /**
     * Updates the Print Preview
     */
    public synchronized void updatePrintPreview()
    {
        calculatePage();
        repaint();
        page.updateUI();
        
        
    }
    /**
     * Updates the Print Preview
     */
    public synchronized void instertPrint()
    {
        if (printImagePreviewList== null)
        {
            calculatePage();
        }
        else
        {
            int index = storedPrint.getNumberOfImages();
            if (index<= rows*cols)
            {
                PrintImagePreview im = printImagePreviewList[index-1];
                im.setReferToImage();
                im.setParameter(havePrintSettings(index-1));
            }
        }
        repaint();
        page.updateUI();
        
    }
    
    /**
    * True if the PrintImagePreview should displayed as Hardcopy. 
    * If false the PrintImagePreview will displayed as Softcopy
    */
    public  void setPrintLUT(boolean printLUT)
    {
        this.printLUT = printLUT;
    }
    /**
     * Updates the Print Preview.
     *@param storedPrint
     * @param portrait
     * @param rows Number of cols of the page
     * @param cols Number of cols of the page
     */
    public synchronized void updatePrintPreview( jDVPSStoredPrint storedPrint, boolean portrait, int rows, int cols)
    {
        this.storedPrint = storedPrint;
        this.portrait = portrait;
        this.rows = rows;
        this.cols = cols;
        notifyBrowser = true;
        calculatePage();
        repaint();
        page.updateUI();
        
        
    }
    
    /**
     * Sets the film size. 
     * @param filmBoxWidth width of the film box.
     * @param filmBoxHeight height of the film box.
     */
    public void setFilmSize(double filmBoxWidth, double filmBoxHeight)
    {
        this.filmBoxHeight = filmBoxHeight;
        this.filmBoxWidth = filmBoxWidth;
        updatePrintPreview();
        
        
    }
    
    
    /**
     * Sets the film size of the default value.
     */
    public void setDefaultFilmSize()
    {
        filmBoxWidth = defaultFilmBoxWidth;
        filmBoxHeight = defaultFilmBoxHeight;
        updatePrintPreview();
        
        
    }
    /**
     * Sets the color of the film
     */
    public void setFilmColor(int grayValue)
    {
        if (grayValue == -1) filmColor = defaultFilmColor;
        else filmColor = new Color(grayValue, grayValue, grayValue);
        updatePrintPreview();
    }
    /**
    * Sets the film box color and the empty image color without any update. Only gray colors can be set by a single 
    * gray color value. 
    * @param fc Gray color value of the film box.
    *  @param eic Gray color value of empfy image boxes
    */ 
    public void setFilmAndEmptyImageColorWithoutUpdate(int fc, int eic)
    {
        if (fc == -1) filmColor = defaultFilmColor;
        else filmColor = new Color(fc, fc, fc);
        if (eic == -1) emptyImageColor = defaultEmptyImageColor;
        else emptyImageColor = new Color(eic, eic, eic);
    }
    
    
    /**
    * Sets the film box color and the empty image color. Only gray colors can be set by a single 
    * gray color value. 
    * @param fc Gray color value of the film box.
    *  @param eic Gray color value of empfy image boxes
    */ 
    public void setFilmAndEmptyImageColor(int fc, int eic)
    {
        if (fc == -1) filmColor = defaultFilmColor;
        else filmColor = new Color(fc, fc, fc);
        if (eic == -1) emptyImageColor = defaultEmptyImageColor;
        else emptyImageColor = new Color(eic, eic, eic);
        
        updatePrintPreview();
    }
    
    
    /**
     * Sets the color of the film to the default value (black).
     */
    public void setDefaultFilmColor()
    {
        filmColor = defaultFilmColor;
        updatePrintPreview();
    }
    /**
     * Sets the color of the film. Only gray colors can be set by a single 
     * gray color value. 
     * @param grayValue 
     */
    public void setEmptyImageColor(int grayValue)
    {
        if (grayValue == -1) emptyImageColor = defaultEmptyImageColor;
        else emptyImageColor = new Color(grayValue, grayValue, grayValue);
        updatePrintPreview();
    }
    
    /**
     * Sets the color of the film to the default value (black)
     */
    public void setDefaultEmptyImageColor()
    {
        emptyImageColor = defaultEmptyImageColor;
        updatePrintPreview();
    }
   
    
    /**
     * Sets a new jDVPSStoredPrint
     * @param storedPrint New jDVPSStoredPrint.
     */
    public void setStoredPrint(jDVPSStoredPrint storedPrint)
    {
        this.storedPrint = storedPrint;
    }
    
    
    /**
     * Check if the image with the specified index have his own print settings
     * @param index Index of the image
     * @return true if the image has his own print settings
     */
    public boolean havePrintSettings(int index)
    {
         if (index <= storedPrint.getNumberOfImages())
         {
             if ( (storedPrint.getImageConfigurationInformation(index) ==null)&&
            (storedPrint.getImageSmoothingType(index)== null)&&
            (storedPrint.getImageMagnificationType(index)== null)) return false;
            else return true;
         }
         return false;
        
    }
}
/*
 *  CVS Log
 *  $Log: PreviewPanel.java,v $
 *  Revision 1.1.1.1  2001/06/06 10:32:29  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
*/
