/*
 *
 *  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:30 $
 *  Revision :    $Revision: 1.1.1.1 $
 *  State:        $State: Exp $
*/

package viewer.presentation;

import java.util.*;
import java.awt.geom.*;
import java.awt.*;

import J2Ci.*;
import main.*;

/**
 * This class manages the layer of a presentation state. 
 *
 * @author Klaus Kleber
 * @since 30.04.1999
 */
public class PresentationStateGraphicLayer extends java.lang.Object
{

    /**
     * Contains the current jDVPresentationState 
     * 
     * @since 30.04.1999
     */
    jDVPresentationState ps;
    
    /**
     * Contains index  of this PresentationStateGraphicLayer
     * in the jDVPresentationState.
     * 
     * @since 30.04.1999
     */
    int index;
    
    /**
     * Contains the number of PresentationStateTextObjects of 
     * this PresentationStateGraphicLayer
     * 
     * @since 30.04.1999
     */
    int numberOfTexts = 0;
    
    /**
     * Contains the number of PresentationStateGraphicObjects of 
     * this PresentationStateGraphicLayer
     * 
     * @since 30.04.1999
     */
    int numberOfGraphics = 0;
    
    /**
     * Handles the overlays.
     * 
     * @since 30.04.1999
     */
    OverlayList overlayList;
    
    
    
    /**
     * Contains a list of all PresentationStateLayerObjects.
     * 
     * @since 30.04.1999
     */
    public Vector listPresentationStateObject;
    
    
    
    /**
     * Constructs a new object
     * 
     * @since 30.04.1999
     */
    PresentationStateGraphicLayer()
    {
        listPresentationStateObject = new Vector();
    }
    /**
     * Constructs a  new object form the specified jDVPresentationState. The
     * specified index is the index of the building graphic layer in the jDVPresentationState.
     * listPresentationStateObject will be filled with the annotations in the layer.
     * 
     * @param index Contains the index of the new object.
     * @param ps Contains the current jDVPresentationState.
     * @param scalingX Contains the vertical scaling value.
     * @param scalingY Contains the horizontal scaling value.
     * @param overlayList Contains all overlays.
     * @since 30.04.1999
     */
    public PresentationStateGraphicLayer(int index, jDVPresentationState ps,DisplayArea da, OverlayList overlayList)
    {
        
        this.ps = ps;
        this.index = index;
        this.overlayList = overlayList;
        numberOfTexts = 0;
        numberOfGraphics = 0;
        listPresentationStateObject = new Vector();
        
        jDVPSTextObject textObject;
        jDVPSGraphicObject graphicObject;
        
        //Init graphic annotations
        for (int i =0; i < ps.getNumberOfGraphicObjects(index); i++)
        {
            graphicObject = ps.getGraphicObject(index, i);
            add(new PresentationStateGraphicObject(graphicObject,da,i));
        }
        
        //Init text annotations
        for (int i =0; i < ps.getNumberOfTextObjects(index); i++)
        {
            
            textObject = ps.getTextObject(index, i);
            add(new PresentationStateTextObject(textObject,i));
        }
        
        
    }

    /**
     * Constructs a  object form the specified parameters 
     * and insert a new layer with monochome Colors to the jDVPresentationState. 
     * 
     * @param index The new index of the new Object and the index of the new layer in the jDVPresentationState.
     * @param ps Contains the current jDVPresentationState.
     * @param name Contains the name of the new layer
     * @param description Contains the description of the new layer.
     * @param monochrome Contains the gray color value of the new layer
     * @param overlayList Contains all overlays.
     * @since 30.04.1999
     */
    public PresentationStateGraphicLayer(int index, jDVPresentationState ps,  String name, String description, float monochrome,OverlayList overlayList)
    {
        this.ps = ps;
        this.index = index;
        this.overlayList = overlayList;
        numberOfTexts = 0;
        numberOfGraphics = 0;
        
        int intVar = index;
        while (ps.addGraphicLayer(new String (name +" " + intVar),description)!=0) intVar++;
        
            
        setFloatColorValue(monochrome);        
        listPresentationStateObject = new Vector();
        
    }
    
    /**
     * Constructs a  object form the specified parameters 
     * and insert a new layer with rgb Colors to the jDVPresentationState. 
     * 
     * @param index The new index of the new Object and the index of the new layer in the jDVPresentationState.
     * @param ps Contains the current jDVPresentationState.
     * @param name Contains the name of the new layer
     * @param description Contains the description of the new layer.
     * @param r Contains the red color value of the new layer
     * @param g Contains the green color value of the new layer
     * @param b Contains the blue color value of the new layer
     * @param overlayList Contains all overlays.
     * @since 30.04.1999
     */
    public PresentationStateGraphicLayer(int index, jDVPresentationState ps,  String name, String description, int r, int g, int b,OverlayList overlayList)
    {
        this.ps = ps;
        this.index = index;
        this.overlayList = overlayList;
        
        numberOfTexts = 0;
        numberOfGraphics = 0;
        int intVar = index;
        while (ps.addGraphicLayer(new String (name +" " +intVar),description)!=0) intVar++;
        
            
        ps.setGraphicLayerRecommendedDisplayValueRGB(index, r,g,b);
        
        listPresentationStateObject = new Vector();
        
    }
    
    /**
    * Sets the size for displaying the image in all PresentationStateLayerObjects
    * of the PresentationStateGraphicLayer. This vlaue will be used for calulating the 
    * display relative annotations.
    *
    * @param screenSize  The size for displaying the image 
    * @since 30.04.1999
    */
    public void setScreenSize(Dimension screenSize)
    {
        for (int i =0; i < listPresentationStateObject.size(); i++)
        {
            ((PresentationStateAnnotationObject ) listPresentationStateObject.elementAt(i)).setScreenSize(screenSize);
        }
    }
    public void convertDisplayedAreas(float offsetX, float offsetY,float transX, float transY)
    {
        for (int i =0; i < listPresentationStateObject.size(); i++)
        {
            ((PresentationStateAnnotationObject ) listPresentationStateObject.elementAt(i)).convertDisplayedAreas( offsetX, offsetY, transX,  transY);
        }
        
    }
    
    /**
    * Text objects have to be notyfied if the image have fliped. The reason is that the 
    * Bounding boxes are stored relative to the displayed area. The text values should be displayed
    * from the TLHC to the BRHC. If the image is flipped the bounding box and the text flipped too.
    * If the text should be readable the bounding boxes have to be flipped.
    *
    * @since 30.04.1999
    */
    public void setFlip(int rot)
    {
        for (int i =0; i < listPresentationStateObject.size(); i++)
        {
            
            if (listPresentationStateObject.elementAt(i) instanceof PresentationStateTextObject)
                ((PresentationStateTextObject ) listPresentationStateObject.elementAt(i)).setImageFlip(rot);
                
        }
    }
    /**
    * Text objects have to be notyfied if the image have rotated. The reason is that the 
    * Bounding boxes are stored relative to the displayed area. The text values should be displayed
    * from the TLHC to the BRHC. If the image will be rotated the bounding box and the text will be 
    * rotated too. If the text should be readable the bounding boxes have to be rotated.
    * 
    *
    * @since 30.04.1999
    */
    public void setRotation()
    {
        for (int i =0; i < listPresentationStateObject.size(); i++)
        {
            
            if (listPresentationStateObject.elementAt(i) instanceof PresentationStateTextObject)
                ((PresentationStateTextObject ) listPresentationStateObject.elementAt(i)).setImageRot();
                
        }
    }
    
    
    /**
    * Draws all PresentationStateLayerObject and all overlays after the specified transformation aff 
    * in the specified Graphics2 context.
    *
    * @param g  The context in wich the image will be drawn.
    * @param aff The transformation which will be applied befor drawing.
    * @param aff Specifies the transformation which will be used for PresentationStateOverlayObjects.
    * @since 30.04.1999
    */
    public void draw(Graphics2D g, AffineTransform aff, AffineTransform overlayAff, int bits, boolean scale)
    {
      //System.out.println("**********drawLayer*************************");
      g.setColor(getColor(bits));
      overlayList.draw(g,overlayAff,index,  bits);
      
      for (int i = 0; i < listPresentationStateObject.size(); i++)
      {
         
         ((PresentationStateLayerObject)listPresentationStateObject.elementAt(i)).drawActive(g,aff, scale);
      }
        
    }
    
    /**
    * Returns a String representing this object.
    *
    * @return A String representing this object
    * @since 30.04.1999
    */
   public String getInfo()
   {
      String returnString;
      returnString = new String("    GraphicLayer" +  "\n"+"\n"+
                                "      Color: "+   getColor(8) + "\n" +   
                                "      Name : " + getName()+"\n"
                                );
      
      for (int i = 0; i < listPresentationStateObject.size(); i++)
      {
         returnString = returnString.concat("        Index Object: " + i + "\n" + 
                           ((PresentationStateLayerObject)listPresentationStateObject.elementAt(i)).getInfo());
      }
      
      return returnString;
   }
   
   /**
   * Gets the unique name of the graphic layer.
   *
   * @return Unique name of the graphic layer.
   * @since 30.04.1999
   * @see J2Ci.jDVPresentationState#getGraphicLayerName
   */
   public String getName()
   {
        return ps.getGraphicLayerName(index);
   }
    
   /**
   * Gets the description of the graphic layer.
   *
   * @return Description of the graphic layer.
   * @since 30.04.1999
   * @see J2Ci.jDVPresentationState#getGraphicLayerDescription
   */
   public String getDescription()
   {
        return ps.getGraphicLayerDescription(index);
   }

    /**
    * Gets the color for the recommended display value of the layer.
    *
    * @return Color for the recommended display value of the layer.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState
    */
    public Color getColor(int bits)
    {
        int pValue = 0x0000;
        jIntByRef gColorValue = new jIntByRef();
        
        ps.getGraphicLayerRecommendedDisplayValueGray(index, gColorValue);
        pValue = gColorValue.value;
        
        if (bits == 8) return GrayColorIndex.getColor(ps.convertPValueToDDL(pValue, 8));
        else return GrayColorIndex.get12Color(ps.convertPValueToDDL(pValue, 12));
        
       
        
    }
    
    /**
    * Gets a transformed  grey color value between 0 and 1 of the 
    * recommended display value. The recommended display value
    * have values between 0 and 0xffff. This function returns this value divide
    * to 0xffff.
    *
    * @return Gets a grey color value between 0 and 1.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#getGraphicLayerRecommendedDisplayValueGray
    */
    public float getFloatGrayColorValue()
    {
        jIntByRef grayColorValue = new jIntByRef();
        ps.getGraphicLayerRecommendedDisplayValueGray(index, grayColorValue);
        float floatValue =(float)grayColorValue.value/(float)0xffff;
        float newValue = (float)  Math.round(floatValue*1000d);  
        return newValue/1000f;
    }
    /**
    * Sets the recommended display value as a value between 0 and 1.
    * The recommended display value have values between 0 and 0xffff. 
    * This function mulipies the specified value with 0xffff and sets
    * these value as recommeded display value of the gaphic layer.
    * 
    * @param colorValue  Contains the recommended display value as a value between 0 and 1.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#setGraphicLayerRecommendedDisplayValueGray
    */
    public void setFloatColorValue (float colorValue)
    {
        
        ps.setGraphicLayerRecommendedDisplayValueGray(index,(int) (colorValue*(int)0xffff));
    }
   
    /**
    * Checks if the recommended display value is a gray value.
    *
    * @return Returns true, if the recommended display value is a gray value.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#isGrayGraphicLayerRecommendedDisplayValue
    */
    public boolean isGray()
    {
        //???????????????
        return true;
    }
    
    
    /** 
     * Checks whether a recommended display value
     * for the given graphic layer exists.
     *
     * @param idx index of the graphic layer, must be < getNumberOfGraphicLayers()
     * @return true if a recommended display value exists
     * @since 30.04.1999
     * @see J2Ci.jDVPresentationState#haveGraphicLayerRecommendedDisplayValue
    */
    public  boolean haveGraphicLayerRecommendedDisplayValue()
    {
        return ps.haveGraphicLayerRecommendedDisplayValue(index);
    }
    
    
    /**
     * Deletes all objects of the PresentationStateGraphicLayer.
     *
     * @since 30.04.1999
    */
    public void deleteAll()
    {
        
        for (int i = 0; i < listPresentationStateObject.size(); i++)
        {
            ((PresentationStateLayerObject)listPresentationStateObject.elementAt(0)).deleteAll();
            listPresentationStateObject.removeElementAt(0);            
        }        
        
        listPresentationStateObject = null;       
    }
    
    /**
    * Deletes the PresentationStateLayerObject with the specified 
    * index form the jDVPresentationState object and the PresentationStateGraphicLayer
    *  
    * @param deleteIndex The index of the PresentationStateLayerObject in the listPresentationStateObject.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#removeGraphicObject
    * @see J2Ci.jDVPresentationState#removeTextObject
    */
    public void deleteObjectAt(int deleteIndex)
    {
            PresentationStateLayerObject delLayerObject = ((PresentationStateLayerObject)listPresentationStateObject.elementAt(deleteIndex));
            System.out.println("deleteIndex: " + deleteIndex);
            System.out.println("delLayerObject.getIndex(): " + delLayerObject.getIndex());
            System.out.println(" löschendes Object: " + delLayerObject.getInfo());
            //Delete C++
            delLayerObject.deleteAll();
            
            if (delLayerObject instanceof PresentationStateGraphicObject)
            {
                ps.removeGraphicObject(index, delLayerObject.getIndex());
            }
            if (delLayerObject instanceof PresentationStateTextObject)
            {
        
        System.out.println( "delete the following Object " + " ist " + ps.getTextObject(index,delLayerObject.getIndex()).getText());
                
                ps.removeTextObject(index, delLayerObject.getIndex());
            }
            
            
            //Removes form java
            removeObjectAt(deleteIndex);
    }
    
    
    /**
    * Removes the PresentationStateLayerObject with the specified 
    * index form this PresentationStateGraphicLayer.
    *  
    * @param deleteIndex The index of the PresentationStateLayerObject in the listPresentationStateObject.
    * @since 30.04.1999
    */
    public void removeObjectAt(int deleteIndex)
    {
        PresentationStateLayerObject removePresentationStateLayerObject = (PresentationStateLayerObject)listPresentationStateObject.elementAt(deleteIndex);
        listPresentationStateObject.removeElementAt(deleteIndex);
        if (removePresentationStateLayerObject instanceof PresentationStateTextObject)
        {
            setNewTextIndex(removePresentationStateLayerObject.getIndex());
            numberOfTexts--;
        }
        else if (removePresentationStateLayerObject instanceof PresentationStateGraphicObject)
        {
            setNewGraphicIndex(removePresentationStateLayerObject.getIndex());
           numberOfGraphics--; 
        }
   }
   
    /**
    * Adds the specified PresentationStateLayerObject to 
    * this PresentationStateGraphicLayer
    *  
    * @param addPresentationStateLayerObject The new PresentationStateLayerObject.
    * @since 30.04.1999
    */
   public void add( PresentationStateLayerObject addPresentationStateLayerObject)
   {
       listPresentationStateObject.add(addPresentationStateLayerObject);
       if (addPresentationStateLayerObject instanceof PresentationStateTextObject)
       {
            addPresentationStateLayerObject.setIndex(numberOfTexts);
            numberOfTexts++;
       }
       if (addPresentationStateLayerObject instanceof PresentationStateGraphicObject)
       {
            addPresentationStateLayerObject.setIndex(numberOfGraphics);
            numberOfGraphics++;
       }
        
   }
    
    
    /**
    * Search and returns the first PresentationStateLayerObject that 
    * contains the specified point. Returns null if there is no such 
    * PresentationStateLayerObject.
    *
    * @param point The specified point.
    * @return The first PresentationStateLayerObject that contains the specified point. Returns null
    * @since 30.04.1999
    */
    public int containsLayerObject(Point2D.Float point)
    {
        for (int i = listPresentationStateObject.size()-1; i >= 0; i--)
        {
            if (((PresentationStateLayerObject)listPresentationStateObject.elementAt(i)).contains(point))
            {
                return i;
            }
        }
        return -1;
    }

    /**
    * Returns the  PresentationStateLayerObject at the specified index. 
    * Returns null if there is no such PresentationStateLayerObject.
    *
    * @param index The index  specified the PresentationStateLayerObject
    * @return The PresentationStateLayerObject at the specified index. 
    * @since 30.04.1999
    */
    public PresentationStateLayerObject layerObjectAt(int index)
    {
        if ((index < 0 )|| (index >=listPresentationStateObject.size())) return null;
        else return (PresentationStateLayerObject)listPresentationStateObject.elementAt(index);
    }
    
    
    /**
    * Sets the description of the layer.
    * The value is stored in the c++ interface 
    * and is available in  the jDVPresententationState object ps.
    *
    * @param newDescription The description of the layer.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#setGraphicLayerDescription
    */
    public void setDescription(String newDescription)
    {
        ps.setGraphicLayerDescription(index,newDescription);
    }
    
    /**
    * Sets the name of the layer.
    * The value is stored in the c++ interface 
    * and is available in  the jDVPresententationState object ps.
    *
    * @param newName The name of the layer.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#setGraphicLayerName
    */
    public boolean setNewName(String newName)
    {
        if ( newName.trim().equals(getName())) return true;
        int status = ps.setGraphicLayerName(index,newName);
        if(status == 0) return true;
        else return false;
    }
    
    /**
    * Sets the monochrome recommended display value of the layer.
    * The value is stored in the c++ interface 
    * and is available in  the jDVPresententationState object ps.
    *
    * @param color The monchrome color  of the layer.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#setGraphicLayerRecommendedDisplayValueGray
    */
    public void setGraphicLayerRecommendedDisplayValueGray(int color)
    {
        ps.setGraphicLayerRecommendedDisplayValueGray(index,color);
    }
    
    
    /**
    * Sets the RGB recommended display value of the layer.
    * The value is stored in the c++ interface 
    * and is available in  the jDVPresententationState object ps.
    *
    * @param color The RGB color  of the layer.
    * @since 30.04.1999
    * @see J2Ci.jDVPresentationState#setGraphicLayerRecommendedDisplayValueRGB
    */
    public void setGraphicLayerRecommendedDisplayValueRGB(int r,int g,int b)
    {
        ps.setGraphicLayerRecommendedDisplayValueRGB(index,r,g,b);
    }
    
    
    /**
    * Reduces the attribut index of all PresentationStateTextObject where the index in
    * the listPresentationStateObject is greather than the specified delIndex.
    * 
    * @param delIndex  Specifies the deleted index
    * @since 30.04.1999
    */
    public void setNewTextIndex(int delIndex)
    {
        PresentationStateLayerObject presentationStateLayerObject;
        for (int i = 0; i < listPresentationStateObject.size(); i++)
        {
            presentationStateLayerObject = (PresentationStateLayerObject)listPresentationStateObject.elementAt(i);
            if ((presentationStateLayerObject instanceof PresentationStateTextObject)&&(presentationStateLayerObject.getIndex() >= delIndex)) 
                presentationStateLayerObject.setIndex(presentationStateLayerObject.getIndex()-1);
        }
    }
    /**
    * Reduces the index of all PresentationStateGraphicObject where the index in
    * the listPresentationStateObject is greather than the specified delIndex.
    * 
    * @param delIndex Specified the deleted index.
    * @since 30.04.1999
    */
    public void setNewGraphicIndex(int delIndex)
    {
        PresentationStateLayerObject presentationStateLayerObject;
        for (int i = 0; i < listPresentationStateObject.size(); i++)
        {
            presentationStateLayerObject = (PresentationStateLayerObject)listPresentationStateObject.elementAt(i);
            if ((presentationStateLayerObject instanceof PresentationStateGraphicObject)&&(presentationStateLayerObject.getIndex() >= delIndex)) 
                presentationStateLayerObject.setIndex(presentationStateLayerObject.getIndex()-1);
        }
        
    }
    
}

/*
 *  CVS Log
 *  $Log: PresentationStateGraphicLayer.java,v $
 *  Revision 1.1.1.1  2001/06/06 10:32:30  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
*/
