/*
 *
 *  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 J2Ci.*;
import main.*;

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

/**
 * This class handles the text annoations. 
 * This class  implementing only the GUI-based methods,
 * the data are stored in the c++ interface jDVPSTextObject. Every 
 * PresentationStateTextObject must have one jDVPSTextObject which stores
 * the data of a text annotation. 
 *<BR>
 * Each jDVPSTextObject has an index in the jDVPresentationState, 
 * this index must be the same as the index in this class ( defined
 * in the super class PresentationStateLayerObject).
 * 
 * @author Klaus Kleber
 * @since 30.04.1999
 * @see PresentationStateAnnotatonObject
 * @see PresentationStateLayerObject
 * @see J2Ci.jDVPSTextObject
 */
public class PresentationStateTextObject extends PresentationStateAnnotationObject
{
    public boolean drawTLHC = false;
    public boolean drawBoundingBox = false;
    public boolean drawNewBoundingBox = false;
    
    
    /**
     * Contains the Attributes
     * 
     * @since 30.04.1999
     */
    jDVPSTextObject textObject;
    
    int needRot = -1;
    int rot = 0;
    int just = 0;
    //Gibt die Göße der Größten Zeile an
    private  float maxLength;
    
    //Transformationen der BoundingBox
    AffineTransform affBox = new AffineTransform();
    
    //Transformationen des Textes
    AffineTransform affText= new AffineTransform();
    
    //Enthält die einzelen Zeilen
    TextLayout[] layoutSegment;
    
    //Enthalt die Offsets für jedes Zeile
    Point2D.Float[] offsets;
    
    /**
     * Contains the geometric representation of the bounding rectangel of the text.
     * the bounding rectangel is differnt form the bounding box. The bounding box is the value
     * in the presentation state and is available form the jDVPSTextObject. The bounding rectangel 
     * is the exact bounding rectangle on the display, indepentent form the bounding box.But if this program 
     * creates a text annotation with a bounding box the bounding box will be calculate from the
     * bounding rectangle.
     * 
     * @since 30.04.1999
     */
    Rectangle2D.Double boundingRect = null;
    
    
    /**
     * Indicates that the PresentationStateTextObject  must redraw.
     * 
     * @since 30.04.1999
     */
    //public boolean mustRedraw = false;

    
    /**
     * If true the PresentationStateTextObject has not been drawn..
     * 
     * @since 30.04.1999
     */
    public boolean firstDraw = false;

    /**
     * If true the PresentationStateTextObject need a anchor point.
     * 
     * @since 30.04.1999
     */
    public boolean needAnchorPoint = false;

    /**
     * If true the PresentationStateTextObject need a bounding box.
     * 
     * @since 30.04.1999
     */
    public boolean needBox= false;

    /**
     * If true the needed  bounding box is display relative.
     * 
     * @since 30.04.1999
     */
    public boolean neededBoxIsDisplayRelative= false;

    /**
     * If true the needed  anchor point is display relative.
     * 
     * @since 30.04.1999
     */
    public boolean neededAnchorIsDisplayRelative= false;

    /**
     * If true the needed  anchor point is visible.
     * 
     * @since 30.04.1999
     */
    public boolean neededAnchorVisible= true;
    
    private static  Hashtable map = new Hashtable();
    static {
        map.put(TextAttribute.SIZE, new Float(18.0));
    }
    public static void setTextAttributeMap(Hashtable newMap)
    {
        map = newMap;
    }
    /**
     * Constructs a new  PresentationStateTextObject.
     * 
     * @since 30.04.1999
     */
    public PresentationStateTextObject()
    {
        super();
    }
    
    /**
     * Constructs an PresentationStateTextObject form the specified jDVPSTextObject.
     * 
    * @param textObject Contains the data of the text annotation in a c++ interface.
     * @param index Contains the index of the PresentationStateTextObject
     * @since 30.04.1999
     */
    public PresentationStateTextObject(jDVPSTextObject textObject,  int index)
    {
       this();
       this.index = index;
       this.textObject = textObject;
       just = textObject.getBoundingBoxHorizontalJustification();
    }
    
    /**
     * Constructs a new PresentationStateTextObject and sets the  specified attributs
     * in the jDVPSTextObject. 
     * 
     * @param textObject Contains the text annotation in a c++ interface.
     * @param index Contains the index of the PresentationStateTextObject.
     * @param screenSize Contains the size of the display for displaying the image.
     * @param needAnchorPoint True if the new PresentationStateTextObject need an anchor point. 
     * @param needBox True if the new PresentationStateTextObject need a bounding box
     * @param neededAnchorIsDisplayRelative True if the needed  anchor point is display relative.
     * @param neededBoxIsDisplayRelative True if the needed bounding box is display relative.
     * @param neededAnchorVisible True if the needed anchor point is visible.
     * @since 30.04.1999
     */
    public PresentationStateTextObject( jDVPSTextObject textObject,
                                        int index,
                                        Dimension screenSize,
                                        boolean needAnchorPoint,
                                        boolean needBox,
                                        boolean neededAnchorIsDisplayRelative,
                                        boolean neededBoxIsDisplayRelative,
                                        boolean neededAnchorVisible, 
                                        int just,
                                        int needRot)
    {
       this();
        this.index = index;
        this.screenSize = screenSize;
        this.textObject = textObject;
        this.needAnchorPoint = needAnchorPoint;
        this.needBox = needBox;
        this.neededAnchorIsDisplayRelative =neededAnchorIsDisplayRelative ;
        this.neededBoxIsDisplayRelative = neededBoxIsDisplayRelative;
        this.neededAnchorVisible = neededAnchorVisible;
        this.just = just;
        this.rot = needRot;
        calc();
    }
    public int getRot(){ return rot;}
    public int getJust(){ return just;}
    
    /**
     * Sets a new text value  to the PresentationStateTextObject.
     *
     * @param newText Specifies the new Text.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#setText
     */
    public void setNewValues(   String newText, int just, int rot)
    {
        this.just = just;
        while (this.rot != rot)
        {
            if (this.rot == 3) this.rot = 0;
            else this.rot++;
            setRot();
        }
        textObject.setText(newText);
        
    }


     /**
      * Not implemented yet.
      * 
      * @param point Not implemented yet
      * @param point1 Not implemented yet
      * @since 30.04.1999
      */
     public void moveTo(Point2D.Float point,Point2D.Float point1)
     {
     }
        public  void convertDisplayedAreas(float offsetX, float offsetY,float transX, float transY)
        {
            if (haveBoundingBox() && getBoundingBoxAnnotationUnits()==jDVPSannotationUnit.DVPSA_display)
            {
                    textObject.setBoundingBox(offsetX+getBoundingBoxTLHC_x()*transX, offsetY+getBoundingBoxTLHC_y()*transY, offsetX+getBoundingBoxBRHC_x()*transX,offsetY+getBoundingBoxBRHC_y()*transY, 1,just);
                        
            }
            if (haveAnchorPoint() && getAnchorPointAnnotationUnits() ==jDVPSannotationUnit.DVPSA_display)
            {
                textObject.setAnchorPoint(offsetX+getAnchorPoint_x()*transX, offsetY+getAnchorPoint_y()*transY, 1, textObject.anchorPointIsVisible());
            }
        }
    
    /**
     * Converts an image relative bounding box to display relative.
     *
     * @since 30.04.1999
     */
    public void convertBoxToDisplayRelative()
    {
        Point2D.Float translatedPointTLHC = new Point2D.Float();
        Point2D.Float translatedPointBRHC = new Point2D.Float();
        aff.transform(new Point2D.Float((float)(getBoundingBoxTLHC_x()-1) ,(float)(getBoundingBoxTLHC_y()-1)),translatedPointTLHC);
        aff.transform(new Point2D.Float((float)(getBoundingBoxBRHC_x()-1) ,(float)(getBoundingBoxBRHC_y()-1)),translatedPointBRHC);
        
        textObject.setBoundingBox( translatedPointTLHC.x/(screenSize.width-1), translatedPointTLHC.y/(screenSize.height-1), translatedPointBRHC.x/(screenSize.width-1),translatedPointBRHC.y/(screenSize.height-1), 1,just);
        
    }

    
    /**
     * Converts a display relative bounding box to  image relative.
     *
     * @since 30.04.1999
     */
    public void convertBoxToImageRelative()
    {
        Point2D.Float translatedPointTLHC = new Point2D.Float();
        Point2D.Float translatedPointBRHC = new Point2D.Float();
        try
        {   
            aff.inverseTransform(new Point2D.Float((float)getBoundingBoxTLHC_x()*(screenSize.width-1),(float)getBoundingBoxTLHC_y()*(screenSize.height-1)),translatedPointTLHC);
            aff.inverseTransform(new Point2D.Float((float)getBoundingBoxBRHC_x()*(screenSize.width-1),(float)getBoundingBoxBRHC_y()*(screenSize.height-1)),translatedPointBRHC);
        }
        catch(NoninvertibleTransformException e)
        {}
        
        textObject.setBoundingBox( translatedPointTLHC.x+1, translatedPointTLHC.y+1, translatedPointBRHC.x+1,translatedPointBRHC.y+1, 0,just);
        
    }

    /**
     * Sets the anchor point visible /unvisible
     *
     * @param isVisible True if the anchor point must be visible.
     * @see J2Ci.jDVPSTextObject#setAnchorPoint
     * @since 30.04.1999
     */
    public void setAnchorPointVisible(boolean isVisible)
    {
        textObject.setAnchorPoint( getAnchorPoint_x(), getAnchorPoint_y(),getAnchorPointAnnotationUnits() , isVisible);
        
    }

    /**
     * Converts an image relative anchor point to display relative.
     *
     * @since 30.04.1999
     */
    public void convertAnchorToDisplayRelative()
    {
        Point2D.Float translatedPoint = new Point2D.Float();
        aff.transform(new Point2D.Float((float)(getAnchorPoint_x()-1) ,(float)(getAnchorPoint_y()-1)),translatedPoint);
        textObject.setAnchorPoint( translatedPoint.x/(screenSize.width-1), translatedPoint.y/(screenSize.height-1),1 , anchorPointIsVisible());
        
    }

    
    /**
     * Converts a display relative anchor point to an image relative.
     *
     * @since 30.04.1999
     */
    public void convertAnchorToImageRelative()
    {
        
        Point2D.Float translatedPoint = new Point2D.Float();
        try
        {   
            aff.inverseTransform(new Point2D.Float((float)getAnchorPoint_x()*(screenSize.width-1),(float)getAnchorPoint_y()*(screenSize.height-1)),translatedPoint);
        }
        catch(NoninvertibleTransformException e)
        {}
        textObject.setAnchorPoint( translatedPoint.x+1, translatedPoint.y+1,0 , anchorPointIsVisible());
        
    }

    
    /**
     * Removes the bounding box form the PresentationStateTextObject.
     *
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#removeBoundingBox
     */
    public void removeBoundingBox()
    {
        textObject.removeBoundingBox();
    }

    
    /**
     * Removes the anchor point form the PresentationStateTextObject.
     *
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#removeBoundingBox
     */
    public void removeAnchorPoint()
    {
        textObject.removeAnchorPoint();
    }
    /**
     * Sets an exact new bounding box for an existing PresentationStateTextObject with
     * the specified point on the top left hand coner and draw the PresentationStateTextObject
     * in the specified Graphics2D context. 
     * 
     * @param g2 Contains Graphics2D context.
     * @param point Contains the top left hand coner of the new bonding box.
     * @param aff Contains the applying transformation 
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#setBoundingBox
     */
    public void setNewBoundingBox(Graphics2D g2, Point2D.Float point, AffineTransform aff)
    {
        this.aff = aff;
        Point2D.Float transPoint = new Point2D.Float();
        if (!neededBoxIsDisplayRelative) 
        {
            transPoint = getInverseTransformedPoint(point,aff);
            transPoint.x++;
            transPoint.y++;
        }
        else
        {
            transPoint.x = point.x/(screenSize.width-1);
            transPoint.y = point.y/(screenSize.height-1);
        
        }
        Point2D.Float brhcText = new Point2D.Float(point.x +maxLength, point.y+offsets[offsets.length-1].y);
        brhcText = getInverseTransformedPoint(brhcText,aff);
            
        if (!neededBoxIsDisplayRelative) 
        {
            setBoundingBox(transPoint.x,transPoint.y ,brhcText.x,brhcText.y,0);
            
        }
        else setBoundingBox(transPoint.x, transPoint.y,transPoint.x+maxLength/(screenSize.width-1),transPoint.y+offsets[offsets.length-1].y/(screenSize.height-1),1);
        
        for (int i = 0; i < rot; i++)setRot();
        
    }

    /**
     * Sets a new bounding box.
     *
     * @param tlhc_x X value of the top left hand coner of the box
     * @param tlhc_y y value of the top left hand coner of the box.
     * @param brhc_x X value of the botton right hand coner of the box.
     * @param brhc_y Y value of the botton right hand coner of the box.
     * @param ann Contains the annotation units of the bounding box.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#setBoundingBox
     */
    public void setBoundingBox(double tlhc_x, double tlhc_y,double brhc_x,double brhc_y,int ann)
    {
        textObject.setBoundingBox( tlhc_x, tlhc_y, brhc_x,brhc_y, ann,just);
    }
   
   public void setImageFlip(int rot)
   {
        if (haveBoundingBox() && (getBoundingBoxAnnotationUnits() == jDVPSannotationUnit.DVPSA_pixels))
           if (rot == 0) setBoundingBox(getBoundingBoxBRHC_x(),  getBoundingBoxTLHC_y(), getBoundingBoxTLHC_x(), getBoundingBoxBRHC_y(),getBoundingBoxAnnotationUnits());
           else if (rot == 1) setBoundingBox(getBoundingBoxTLHC_x(),  getBoundingBoxBRHC_y(), getBoundingBoxBRHC_x(), getBoundingBoxTLHC_y(),getBoundingBoxAnnotationUnits());
           else if (rot == 2) setBoundingBox(getBoundingBoxBRHC_x(),  getBoundingBoxTLHC_y(), getBoundingBoxTLHC_x(), getBoundingBoxBRHC_y(),getBoundingBoxAnnotationUnits());
           else if (rot == 3) setBoundingBox(getBoundingBoxTLHC_x(),  getBoundingBoxBRHC_y(), getBoundingBoxBRHC_x(), getBoundingBoxTLHC_y(),getBoundingBoxAnnotationUnits());
            
        System.out.println("rot: " + rot);
   }
   public void setImageRot()
   {
        if (haveBoundingBox() && (getBoundingBoxAnnotationUnits() == jDVPSannotationUnit.DVPSA_pixels))
        {
            setBoundingBox(getBoundingBoxTLHC_x(),  getBoundingBoxTLHC_y(),getBoundingBoxTLHC_x()+ (getBoundingBoxBRHC_y()-getBoundingBoxTLHC_y()),getBoundingBoxTLHC_y()-(getBoundingBoxBRHC_x()-getBoundingBoxTLHC_x()),getBoundingBoxAnnotationUnits());
            System.out.println(" rot: " + getInfo());
            
        }
   }
   public void setRot()
   {
        if (haveBoundingBox() )
            setBoundingBox(getBoundingBoxTLHC_x(),  getBoundingBoxTLHC_y(),getBoundingBoxTLHC_x()- (getBoundingBoxBRHC_y()-getBoundingBoxTLHC_y()),getBoundingBoxTLHC_y()+(getBoundingBoxBRHC_x()-getBoundingBoxTLHC_x()),getBoundingBoxAnnotationUnits());
   }

    /**
     * Sets a new anchor point for an existing PresentationStateTextObject with
     * the specified point and draw the PresentationStateTextObject
     * in the specified Graphics2D context. 
     * 
     * @param g2 Contains Graphics2D context.
     * @param point Contains point of the anchor point.
     * @param aff Contains the applying transformation 
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#setAnchorPoint
     */
    public void setNewAnchor(Graphics2D g2, Point2D.Float point, AffineTransform aff)
    {
        this.aff = aff;
        Point2D.Float transPoint = new Point2D.Float();
        if (!neededAnchorIsDisplayRelative) 
        {
            transPoint = getInverseTransformedPoint(point,aff);
            transPoint.x++;
            transPoint.y++;
        }
                else
        {
            transPoint.x = point.x/(screenSize.width-1);
            transPoint.y = point.y/(screenSize.height-1);
        
        }
         if (g2!= null)
         {
            setAnchorPoint((double)transPoint.x, (double)transPoint.y);
         }
    
    }

    /**
     * Sets a new anchor point.
     *
     * @param tlhc_x X value of the anchor point.
     * @param tlhc_y Y value of the anchor point.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#setBoundingBox
     */
    public void setAnchorPoint(double tlhc_x, double tlhc_y)
    {
        if (neededAnchorIsDisplayRelative)textObject.setAnchorPoint( tlhc_x, tlhc_y,1 , neededAnchorVisible);
        else textObject.setAnchorPoint( tlhc_x, tlhc_y, 0 ,neededAnchorVisible);
    }

    /**
     * Sets a new  size for displaying the image.
     * 
     * @param screenSize The new size for displaying the image.
     * @since 30.04.1999
     */
    public void setScreenSize(Dimension screenSize)
    {
        this.screenSize = screenSize;
    }
    public void calculateTextRotation(AffineTransform spatialTransformation)
    {
        AffineTransform rotTransform = new AffineTransform();
        affText = new AffineTransform();
         //Draw bounding Box
        if (haveBoundingBox())
        {
            Point2D.Double spatialTransformedTLHC  = new Point2D.Double(getBoundingBoxTLHC_x()-1,getBoundingBoxTLHC_y()-1);
            Point2D.Double spatialTransformedBRHC= new Point2D.Double(getBoundingBoxBRHC_x()-1,getBoundingBoxBRHC_y()-1);
            
            if (getBoundingBoxAnnotationUnits()==jDVPSannotationUnit.DVPSA_pixels) rotTransform = spatialTransformation;
            
            rotTransform.transform(spatialTransformedTLHC,spatialTransformedTLHC);
            rotTransform.transform(spatialTransformedBRHC,spatialTransformedBRHC);
            int textRotation = 0;
            if ((spatialTransformedTLHC.x>spatialTransformedBRHC.x)&&(spatialTransformedTLHC.y<spatialTransformedBRHC.y))textRotation = 1;
            if ((spatialTransformedTLHC.x>spatialTransformedBRHC.x)&&(spatialTransformedTLHC.y>spatialTransformedBRHC.y))textRotation = 2;
            if ((spatialTransformedTLHC.x<spatialTransformedBRHC.x)&&(spatialTransformedTLHC.y>spatialTransformedBRHC.y))textRotation = 3;
            
            //text transformations
            affText.rotate(textRotation*0.5*Math.PI,0,0);
            rot = textRotation;
            
        }
        
    }
    
    public void calc()
    {
        maxLength = 0;
        
        
        
        FontRenderContext fontRenderContext = new FontRenderContext(affText,true,true);
        
        //FontRenderContext for calculating the length of the rows
        FontRenderContext helpFontRenderContext = new FontRenderContext(new AffineTransform(),true,true);
        
        
        StringTokenizer stringtoken = new StringTokenizer(getTextValue(),"\n");
        
        
        int numberOfLines = stringtoken.countTokens();
        
        
        layoutSegment = new TextLayout[numberOfLines];
        
        
        offsets = new Point2D.Float[numberOfLines];
        
        
        float offsetY = 0;
        
        
        String token;
        
        
        TextLayout helpLayout;
        
       
        float[] textLength = new float[numberOfLines];
        
        for(int i =0; i< numberOfLines; i++)
        {
             
             token = stringtoken.nextToken();
             
             
             layoutSegment[i] = new TextLayout(token,map,fontRenderContext);
             
             
             helpLayout = new TextLayout(token, map, helpFontRenderContext); 
             
             
             offsetY =offsetY+ layoutSegment[i].getAscent();
             offsets[i] = new Point2D.Float(0,offsetY);
             textLength[i] =  helpLayout.getAdvance();
             maxLength = Math.max(maxLength, helpLayout.getAdvance());
        }
        
        
        float scale = 0;
        if (just ==2) scale = 0.5f;
        if (just ==1) scale = 1;
        for(int i =0; i< numberOfLines; i++)
        {
            offsets[i].x= scale*(maxLength-textLength[i]);
        }
    }
   
    /**
    * Draws the PresentationStateTextObject with the specified 
    * transformation in the specified Graphics2d object. The geometric
    * representation of this obejct will be calculate. 
    *
    * @param g2 The context in which this object will be drawn.
    * @param aff Contains the applying transformation.
    * @since 30.04.1999
    */
   public  void draw(Graphics2D g2,AffineTransform aff, boolean scale)
   {
        this.aff = aff;
        System.out.println(getInfo());
        
        if(g2!=null)
        {
            g2.setTransform(new AffineTransform());
            calculateTextRotation(aff);
            Point2D.Double rectBRHC = new Point2D.Double();
            Point2D.Double  anchorPoint = new Point2D.Double();
            Point2D.Double tlhcDst = new Point2D.Double();
            Point2D.Double brhcDst = new Point2D.Double();
           Rectangle2D.Double oldBoundingBox;
            Font  mapFont = null;
           if (haveBoundingBox())
            {
                if (getBoundingBoxAnnotationUnits() ==0)
                {
                    tlhcDst = new Point2D.Double(getBoundingBoxTLHC_x()-1,getBoundingBoxTLHC_y()-1);
                    brhcDst = new Point2D.Double(getBoundingBoxBRHC_x()-1,getBoundingBoxBRHC_y()-1);
                    aff.transform(tlhcDst,tlhcDst);
                    aff.transform(brhcDst,brhcDst);
                }
                else
                {
                    tlhcDst = new Point2D.Double((getBoundingBoxTLHC_x())*(screenSize.width-1),(getBoundingBoxTLHC_y())*(screenSize.height-1));
                    brhcDst = new Point2D.Double((getBoundingBoxBRHC_x())*(screenSize.width-1),(getBoundingBoxBRHC_y())*(screenSize.height-1));
                    
                }
                
                
                //Berechnen der alten BoundingBox
                double btx = tlhcDst.x;
                double bty = tlhcDst.y;
                double bby = brhcDst.y;
                double bbx = brhcDst.x;
                            
                if (btx>bbx)
                {
                    double help = bbx;
                    bbx = btx;
                    btx = help;
                }
                            
                if (bty>bby)
                {
                    double help = bby;
                    bby = bty;
                    bty = help;
                }
                oldBoundingBox  = new Rectangle2D.Double(btx,bty,bbx-btx,bby-bty);
               // if (drawBoundingBox) g2.draw(oldBoundingBox);
                 System.out.println("Hier1");
                if (scale)
                {
                    float scaleX;
                    if ((rot == 1) ||(rot == 3))
                    {
                        scaleX = (float)oldBoundingBox.getHeight()/(float)maxLength;
                    }
                    else
                    {
                        scaleX = (float)oldBoundingBox.getWidth()/(float)maxLength;
                        
                    }
                    mapFont = (Font)(map.get(TextAttribute.FONT));
                   int newFontSize = (int)((float) mapFont.getSize()* scaleX);
                    map.put(TextAttribute.FONT, new Font( mapFont.getName(), mapFont.getStyle(),(int)((float) mapFont.getSize()* scaleX)));
                    System.out.println("newFontSize :"+newFontSize);
                }
                 
                
            }
            
            
                 
            System.out.println("maxLength: " + maxLength);
            
            calc();
            System.out.println("maxLength: " + maxLength);
            System.out.println("hier: ");
                 
            
            if ((scale)&&(haveBoundingBox())) map.put(TextAttribute.FONT, mapFont);
            System.out.println("hier: -ende ");
            //Construct Anchorpoint
            if  (haveAnchorPoint())
            {
                if (getAnchorPointAnnotationUnits() == 0)
                {
                    aff.transform(new Point2D.Double(   textObject.getAnchorPoint_x()-1,
                                                        textObject.getAnchorPoint_y()-1),
                                                        anchorPoint);
                            
                }
                else
                {
                    anchorPoint = new Point2D.Double(   textObject.getAnchorPoint_x()*(screenSize.width-1),
                                                        textObject.getAnchorPoint_y()*(screenSize.height-1));
                }
            }
            System.out.println("hier:1 ");
            
            //Anchor point only
            if  (!haveBoundingBox()&& haveAnchorPoint())
            {
                
                
                if((anchorPoint.getX() < 0)||(anchorPoint.getX()> screenSize.width-1 )) return;
                if((anchorPoint.getY() < 0)||(anchorPoint.getY()> screenSize.height-1)) return;
                
                if (anchorPoint.getX() > screenSize.width-100) 
                {
                    tlhcDst.x = anchorPoint.getX()-maxLength-50;
                }
                else 
                {
                    tlhcDst.x  = anchorPoint.getX()+50;
                }
                if (anchorPoint.getY() > 100) 
                {
                    tlhcDst.y  = anchorPoint.getY()-offsets[offsets.length-1].y -50;
                }
                else 
                {
                    tlhcDst.y  = anchorPoint.getY()+50;
                }
            }
            
            if(haveAnchorPoint() || haveBoundingBox())
            {
            
                    if (layoutSegment!= null)
                    {
                        //Point for drawing one line of the text
                        Point2D.Double blhc;
                        
                        //Number of Lines
                        int numberOfLines = layoutSegment.length;
                        
                        //Draw lines
                        for(int i =0; i< numberOfLines; i++)
                        {
                            
                            blhc = new Point2D.Double(offsets[i].x,offsets[i].y);
                            affText.transform(blhc, blhc);
                            layoutSegment[i].draw(g2,(float)(tlhcDst.x+blhc.x),(float)(tlhcDst.y+blhc.y));
                        }
                        
                        
                        affBox = new AffineTransform();
                        affBox.rotate(rot*0.5*Math.PI,tlhcDst.x,tlhcDst.y);
                        rectBRHC = new Point2D.Double(tlhcDst.x+maxLength,tlhcDst.y+offsets[offsets.length-1].y);
                        affBox.transform(rectBRHC,rectBRHC);
                        boundingRect = new Rectangle2D.Double(Math.min(tlhcDst.x,rectBRHC.x),Math.min(tlhcDst.y,rectBRHC.y) ,Math.abs(tlhcDst.x-rectBRHC.x),Math.abs(tlhcDst.y-rectBRHC.y));
                       
                        if (drawNewBoundingBox)
                        {
                            g2.draw(boundingRect);
                        }
                        //g2.setTransform(affBox);
                        if(drawTLHC)
                        {
                            //Tlhc
                            Rectangle2D.Double tlhcBox = new Rectangle2D.Double(tlhcDst.x,tlhcDst.y,5,5);
                            
                            
                            g2.draw( tlhcBox);
                        }
                        
                    }
            
            }
            
            
            if (haveBoundingBox())
            {
                if (getBoundingBoxAnnotationUnits() ==0) 
                {
                    Point2D.Double newBRHC =new Point2D.Double();
                    newBRHC = getInverseTransformedPoint(rectBRHC,aff);
                    setBoundingBox(getBoundingBoxTLHC_x(),getBoundingBoxTLHC_y() ,newBRHC.x,newBRHC.y,0);
                }
                else
                {
                   setBoundingBox(getBoundingBoxTLHC_x(),getBoundingBoxTLHC_y() ,rectBRHC.x/(screenSize.width-1),rectBRHC.y/(screenSize.height-1),1);
                
                }
            System.out.println(getInfo());
                    
         
       
                
            }    
                   
                    //Display only if anchorpoint ist visible
            if  (haveAnchorPoint()&& textObject.anchorPointIsVisible())
            {
                            
                Point2D.Double rectPoint = getBestPoint(boundingRect, anchorPoint);
                g2.draw( new Line2D.Double(rectPoint.getX(),rectPoint.getY(),anchorPoint.getX(),anchorPoint.getY()));
                //g2.draw(new Rectangle2D.Double(rectPoint.getX(),rectPoint.getY(),5,5));   
                //g2.draw(new Rectangle2D.Double(anchorPoint.getX(),anchorPoint.getY(),5,5));   
            }
            
        }//g2!=null
    }//drawShape


    /**
     * Returns the location of the nearest corner from the specified Rectangle2D
     *
     * @param rectangle The specified Rectangle
     * @param point Specifies the point.
     * @returns The location of the nearest corner from the specified Rectangle2D
     * @since 30.04.1999
     */
    Point2D.Double getBestPoint( Rectangle2D rectangle, Point2D.Double point)
    {
        Point2D.Double returnPoint = new Point2D.Double();
        if (point.getX() > rectangle.getX() +rectangle.getWidth()/2) returnPoint.x =  rectangle.getX() +rectangle.getWidth();
        else returnPoint.x =   rectangle.getX();
        if (point.getY() >  rectangle.getY() +rectangle.getHeight()/2) returnPoint.y = rectangle.getY() +rectangle.getHeight();
        else returnPoint.y = rectangle.getY();
        return returnPoint;
    }
    
      
    
    
    /**
     * Checks if the anchor point is visible.
     *
     * @return True if the anchor point is visible.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#anchorPointIsVisible
     */
    public boolean anchorPointIsVisible()
    {
        return textObject.anchorPointIsVisible();
    }

    /**
     * Returns the annotation units of the anchor point.
     *
     * @return The annotation units of the anchor point.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getAnchorPointAnnotationUnits
     */
    public int getAnchorPointAnnotationUnits()
    {
        return textObject.getAnchorPointAnnotationUnits();
    }

    /**
     * Returns the annotation units of the bounding box
     *
     * @return The annotation units of the bounding box
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getBoundingBoxAnnotationUnits
     */
    public int getBoundingBoxAnnotationUnits()
    {
        return textObject.getBoundingBoxAnnotationUnits();
    }

    /**
     * Checks if the annotation has an anchor point.
     *
     * @return True if the annotation has an anchor point.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#haveAnchorPoint
     */
    public boolean haveAnchorPoint()
    {
        return textObject.haveAnchorPoint();
    }

    /**
     * Checks if the annotation has bounding box
     *
     * @return True if the annotation has bounding box
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#haveBoundingBox
     */
    public boolean haveBoundingBox()
    {
        return textObject.haveBoundingBox();
    }

    /**
     * Checks if the annotation has an anchor point.
     *
     * @return True if the annotation has an anchor point.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#haveAnchorPoint
     */
    public String getTextValue()
    {
        return textObject.getText();
    }

    /**
     * Returns the x value of the bottom right hand corner of the bounding box.
     *
     * @return The x value of the bottom right hand corner of the bounding box.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getBoundingBoxBRHC_x
     */
    public  double getBoundingBoxBRHC_x()
    {
        return textObject.getBoundingBoxBRHC_x();
    }

    /**
     * Returns the x value of the top left hand corner of the bounding box.
     *
     * @return The x value of the top left hand corner of the bounding box.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getBoundingBoxTLHC_x
     */
    public  double getBoundingBoxTLHC_x()
    {
        return textObject.getBoundingBoxTLHC_x();
    }

    /**
     * Returns the y value of the bottom right hand corner of the bounding box.
     *
     * @return The y value of the bottom right hand corner of the bounding box.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getBoundingBoxBRHC_y
     */
    public  double getBoundingBoxBRHC_y()
    {
        return textObject.getBoundingBoxBRHC_y();
    }

    /**
     * Returns the x value of the top left hand corner of the bounding box.
     *
     * @return The x value of the top left hand corner of the bounding box.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getBoundingBoxTLHC_x
     */
    public  double getBoundingBoxTLHC_y()
    {
        return textObject.getBoundingBoxTLHC_y();
    }

    /**
     * Returns the bottom right hand corner of the bounding box.
     *
     * @return The bottom right hand corner of the bounding box.
     * @since 30.04.1999
     */
    public Point2D getBoundingBoxBRHC()
    {
        return new Point2D.Double(getBoundingBoxBRHC_x(),getBoundingBoxBRHC_y());
    }

    /**
     * Returns the the top left hand corner of the bounding box.
     *
     * @return The  the top left hand corner of the bounding box.
     * @since 30.04.1999
     */
    public Point2D getBoundingBoxTLHC()
    {
        return new Point2D.Double(getBoundingBoxTLHC_x(),getBoundingBoxTLHC_y());
    }

    /**
     * Returns the x value of the anchor point.
     *
     * @return The x value of the anchor point.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getAnchorPoint_x
     */
    public double getAnchorPoint_x()
    {
        return textObject.getAnchorPoint_x();
    }

    /**
     * Returns the y value of the anchor point.
     *
     * @return The y value of the anchor point.
     * @since 30.04.1999
     * @see J2Ci.jDVPSTextObject#getAnchorPoint_y
     */
    public double getAnchorPoint_y()
    {
        return textObject.getAnchorPoint_y();
    }


    /**
    * Returns a String representing this object.
    *
    * @return A String representing this object
    * @since 30.04.1999
    */
    public String getInfo()
    {
        String returnString = new String();
        //fill attributes
        returnString = new String(  "    PresenationStateTextObject" +  "\n"+"\n"+
                                    "      getTextValue: "+     getTextValue() + "\n" );
                                                
        //fill points
        if (haveBoundingBox())        
        {
            returnString = returnString.concat("        haveBoundingBox: " +haveBoundingBox() + "\n"+
                                               "           getBoundingBoxAnnotationUnits: " +  getBoundingBoxAnnotationUnits() + "\n" +    
                                               "           TLHC x = " + getBoundingBoxTLHC_x() + " y = " + getBoundingBoxTLHC_y() + "\n"+
                                               "           BRHC x = " + getBoundingBoxBRHC_x() + " y = " + getBoundingBoxBRHC_y() +"\n");
        }                     
        //fill points
        if (haveAnchorPoint())        
        {
            returnString = returnString.concat("        haveAnchorPoint: " +haveAnchorPoint() + "\n"+
                                               "           getAnchorPointAnnotationUnits: " +  getAnchorPointAnnotationUnits() + "\n" +    
                                               "           anchorPointIsVisible: " +  anchorPointIsVisible() + "\n" +    
                                               "            x = " + getAnchorPoint_x() + " y = " + getAnchorPoint_y() + "\n");
                                                          
        }                     
        
        
        return returnString;
    }

    /**
     * Deltes the object.
     *
     * @since 30.04.1999
     */
    public void deleteAll()
    {
        textObject = null;
    }


    /**
     * Returns a String representing this object.
     *
     * @return A String representing this object.
     * @since 30.04.1999
    */
    public String getListText()
    {
        String returnString = new String("Text: " + getTextValue());
        
        return returnString;
    }

    /**
     * Check if this object contains the specified point. 
     * 
     * @return true if this object contains the specified point.
     * @since 30.04.1999
     */
    public boolean contains(Point2D.Float point)
    {
            return boundingRect.contains(point);
    }
    /**
     * Converts the bounding box or the anchor point form image relative to 
     * display relative or vice versa.If units = 0, convert the bounding box, 
     * else convert the anchor point.
     * 
     * @param units If units = 0, convert the bounding box, else convert the anchor point.
     * @since 30.04.1999
    */ 
    
    public void convert( int units)
    {
       
        if (units == 0)
        {
           if (getBoundingBoxAnnotationUnits() ==0)convertBoxToDisplayRelative();
           else convertBoxToImageRelative();
        }
        else 
        {
            if (getAnchorPointAnnotationUnits() ==0)convertAnchorToDisplayRelative();
            else convertAnchorToImageRelative();
        }
    
    }
   
    /**
    * Marked the PresentationStateTextObject with Rectangles and draws 
    * them in the specified Graphics2D context.
    *
    * @param g2 The context in which this object will be merked.
    * @param aff Contains the applying transformation.
    * @since 30.04.1999
    */

    public void drawBounding(Graphics2D g2,AffineTransform aff)
    {
        g2.setTransform(new AffineTransform());
        g2.draw(new Rectangle2D.Double(boundingRect.getX()- 6,boundingRect.getY()-6,5,5));
        g2.draw(new Rectangle2D.Double(boundingRect.getX()+boundingRect.getWidth()+1,boundingRect.getY()-6,5,5));
        g2.draw(new Rectangle2D.Double(boundingRect.getX()-6,boundingRect.getY()+boundingRect.getHeight()+1,5,5));
        g2.draw(new Rectangle2D.Double(boundingRect.getX()+boundingRect.getWidth()+1,boundingRect.getY()+boundingRect.getHeight()+1,5,5));
    }
   
   
   /**
    * Marked the PresentationStateTextObject with Rectangles and draws 
    * them in the specified Graphics2D context. This function must be redesigned.
    * 
    * @param g2 The graphics2d object in which the shape will be drawn.
    * @param aff Contains the transformations which should be applied to the shape.
    * @since 30.04.1999
    */
    public  void drawMarked(Graphics2D g2,AffineTransform aff)
    {
        if ((g2!=null) )
        {
                drawBounding(g2,this.aff);
        }
    }

}  

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