/*
 *
 *  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: 2003/09/08 10:17:26 $
 *  Revision :    $Revision: 1.2 $
 *  State:        $State: Exp $
*/

package viewer.presentation;

import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

import main.*;
import J2Ci.*;

/**
 * This class contains methods which draw the visible part of the image and the 
 * shutter in a BufferedImage. 
 * <br>
 * The virtualTLHC contains a value for 
 * positioning the  the image on the display. The maximum value of  virtualTLHC.x is
 * (width of the image + width of the display), the maximum value of virtualTLHC.y is
 * (height of the image+ height of the display).
 * If  (virtualTLHC.x < width of the display) and (virtualTLHC.y< height of the display)
 * the TLHC of the image will drawn on the point virtualTLHC on the display.
 * If (virtualTLHC.x > width of the display) and (virtualTLHC.y > height of the display)
 * the point (width of the display - virtualTLHC.x, height of the display -virtualTLHC.y)
 *  of the image will be drawn on the top left hand coner of the display.
 * <BR>
 *
 * @author Klaus Kleber
 * @since 30.04.1999
 * @see JavaTransformationConverter
 * @see C_TransformationConverter
 */
public abstract class TransformationConverter
{

    public static int number = 0;
    /**
     * Contains the transfomations of the PresentationStateLayerObjects
     * and the SutterList.
     * 
     * @since 30.04.1999
     */
    AffineTransform aff;
    
    AffineTransform printAff;
     AffineTransform printOverlayTransform;
    
    
    /**
     * Contains the transfomations of the PresentationStateOverlayObjects
     * 
     * @since 30.04.1999
     */ 
     AffineTransform overlayTransform;
    
    /**
     * Zoom value.
     * 
     * @since 30.04.1999
     */
    double zoomValue;
    
    
    /**
     * Contains the dimension of the display.
     * 
     * @since 30.04.1999
     */
    Dimension displayDimension;
    
    
    /**
     * Contains the displaying top left hand coner of the image.
     * 
     * @since 30.04.1999
     */
    protected Point sourcePixelBRHC;
   
    /**
     * Contains the displaying bottom right hand coner of the image.
     * 
     * @since 30.04.1999
     */
    protected Point sourcePixelTLHC;
    
    /**
     * Contains the top left hand coner of the display where the sourcePixelBRHC
     * of the image must be displayed. 
     * 
     * @since 30.04.1999
     */
    protected Point displayPixelTLHC;
    
    /**
     * Contains the botton right hand coner of the display where the sourcePixelTLHC
     * of the image must be displayed. 
     * 
     * @since 30.04.1999
     */
    protected Point displayPixelBRHC;
    
    /**
     * Contains the virtual top left hand corner(TLHC). The virtualTLHC contains a value for 
     * positioning the  the image on the display. The maximum value of  virtualTLHC.x is
     * (width of the image + width of the display), the maximum value of virtualTLHC.y is
     * (height of the image+ height of the display).
     * If  (virtualTLHC.x < width of the display) and (virtualTLHC.y< height of the display)
     * the TLHC of the image will drawn on the virtualTLHC.
     * If (virtualTLHC.x > width of the display) and (virtualTLHC.y > height of the display)
     * the point (width of the display - virtualTLHC.x, height of the display -virtualTLHC.y)
     *  of the image will be drawn on the top left hand coner of the display. 
     * 
     * 
     * @since 30.04.1999
     */
    Point virtualTLHC;
    
    /**
     * Contains the current PresentationStateGraphicsHandler.
     * 
     * @since 30.04.1999
     */ 
    PresentationStateGraphicsHandler presentationStateGraphicsHandler;
    
    
    /**
     * Constructs the object with the specified  PresentationStateGraphicsHandler.
     * 
     * @param presentationStateGraphicsHandler Conatins the current PresentationStateGraphicsHandler.
     * @see PresentationStateGraphicsHandler
     * @since 30.04.1999
     */
    public TransformationConverter(PresentationStateGraphicsHandler presentationStateGraphicsHandler)
    {
        //init var
        this.presentationStateGraphicsHandler = presentationStateGraphicsHandler;
        
        
        //gets the part of the image which should be visible.
        //Default ist the full image
        sourcePixelTLHC = new Point(0,0);
        sourcePixelBRHC = new Point(presentationStateGraphicsHandler.getCurrentImageWidth(),presentationStateGraphicsHandler.getCurrentImageHeight());
        
        
        //Sets the TLHC of the display in which the image should be paint.
        //Default ist the top left hand coner of the image;
        displayPixelTLHC = new Point(0,0);
    
        //init var
        displayDimension = new Dimension(0,0);
        
        //
        virtualTLHC = new Point(0,0);
        
    }
    
    
    /**
     * Returns the maximum y-value for the virtualTLHC. 
     * 
     * @return  The maximum y-value for the virtualTLHC. 
     * @since 30.04.1999
     */
    public int getScollValueHeight()
    {
        return (presentationStateGraphicsHandler.getCurrentImageHeight()+displayDimension.height);
    }

    /**
     * Returns the maximum x-value for the virtualTLHC. 
     * 
     * @return  The maximum x-value for the virtualTLHC. 
     * @since 30.04.1999
     */
    
    public int getScollValueWidth()
    {
        return(presentationStateGraphicsHandler.getCurrentImageWidth()+displayDimension.width);
    }

    /**
     * Returns the current virtualTLHC. 
     * 
     * @return The current virtualTLHC
     * @since 30.04.1999
     */
    public Point getScrollbarValue()
    {
        return virtualTLHC;
    }

    /**
     * Sets a new x-value for the virtualTLHC
     * 
     * @param newWidth New x-value for the virtualTLHC
     * @since 30.04.1999
     */
    
    public void setVirtualTHLCWidth(int newWidth)
    {
        virtualTLHC.x = newWidth;
    }

    /**
     * Sets a new y-value for the virtualTLHC
     * 
     * @param newHeight New y-value for the virtualTLHC
     * @since 30.04.1999
     */
    public void setVirtualTHLCHeight(int newHeight)
    {
        virtualTLHC.y = newHeight;
    }
    public void setNewZoom(double oldZoom)
    {
        
    }
    
    /**
     * Draws the specified display area of the image after the zooming, scaling, rotation and flipping 
     * in the specified BufferedImage.
     * 
     * @param bufferedImage Specifies the BufferedImage in which the image will be drawn.
     * @param zoomValue Specifies the zoom value of the image.
     * @param newPixels false if the pixels must get from the c++ part of the code.
     * @since 30.04.1999
     */
    public void drawInDeviceSpaceFirst (BufferedImage bufferedImage,double zoomValue,boolean newPixels,int applyTo)
    {
        
        //System.out.println("*******************************drawInDeviceSpaceFirst");
        this.zoomValue = zoomValue;
            
        //gets the dimension of the screen
        displayDimension.height = bufferedImage.getRaster().getHeight();
        displayDimension.width = bufferedImage.getRaster().getWidth();
        
        //Maps the display area. The display area specified in the DICOM Supp 33
        //is relative to the image pixel without ratiotion and flipping.
        //In the code the display area is relative to the image after ratation and flipping.
            
        //get display area values
        DisplayArea da = presentationStateGraphicsHandler.getDisplayArea();
        int xTLHC = da.tlhc_x-1;
        int yTLHC =da.tlhc_y-1;
        int xBRHC =da.brhc_x-1 ;
        int yBRHC =da.brhc_y-1;
           
        //converts to points
        Point2D.Float tlhc = new Point2D.Float(xTLHC,yTLHC);
        Point2D.Float brhc = new Point2D.Float(xBRHC,yBRHC);
            
	    //Converts the points TLHC and BRHC of the display area
	    AffineTransform  affDisplay = calculateSpatialTransfomation();     //Calculate transformation for Annotations, Shutter usw.
        affDisplay.transform(tlhc,tlhc);            
        affDisplay.transform(brhc,brhc);            
            
        //rotation of the image
        int rot = presentationStateGraphicsHandler.getRotation();
            
        //help value
        float change;
            
        //changes x values if image is flipped
        if (rot == 0)
        {
            if (presentationStateGraphicsHandler.ps.getFlip())
            {
                change = tlhc.x;
                tlhc.x = brhc.x;
                brhc.x = change;
            }
                    
        }
        //changes x values if image is rotated 90 degree
        //if the image is rotated 90 degree and flipped 
        //the transfomation eliminates each other.
        else if (rot == 1)
        {
            if (!presentationStateGraphicsHandler.ps.getFlip())
            {
                change = tlhc.x;
                tlhc.x = brhc.x;
                brhc.x = change;
            }
        }
        //changes x and y values if image is rotated 180 degree
        //if the image is rotated 180 degree and flipped only 
        //the y values must be changed
        else if (rot == 2)
        {
                   
            if (!presentationStateGraphicsHandler.ps.getFlip())
            {
                    
                change = tlhc.x;
                tlhc.x = brhc.x;
                brhc.x = change;
                        
                change = tlhc.y;
                tlhc.y = brhc.y;
                brhc.y = change;
            }
            else
            {
                change = tlhc.y;
                tlhc.y = brhc.y;
                brhc.y = change;
                        
            }
                    
        }
        //changes y values if image is rotated 270 degree
        //if the image is rotated 180 degree and flipped
        //the x an the y values must be changed
        else if (rot == 3)
        {
                   
            if (!presentationStateGraphicsHandler.ps.getFlip())
            {
                   
                change = tlhc.y;
                tlhc.y = brhc.y;
                brhc.y = change;
            }
            else
            {
                change = tlhc.x;
                tlhc.x = brhc.x;
                brhc.x = change;
                        
                change = tlhc.y;
                tlhc.y = brhc.y;
                brhc.y = change;
                        
            }
                    
        }
            
        
        
        //calculates the virtualTLHC 
        
        
        if (tlhc.x >=0) virtualTLHC.x =displayDimension.width+(int)tlhc.x;
        else 
        {
            virtualTLHC.x =displayDimension.width+(int)Math.round(tlhc.x*(zoomValue*presentationStateGraphicsHandler.getScalingX()));
        }
        if (tlhc.y >=0) virtualTLHC.y =displayDimension.height +(int)tlhc.y;
        else 
        {
            virtualTLHC.y =displayDimension.height+(int)Math.round(tlhc.y*(zoomValue*presentationStateGraphicsHandler.getScalingY()));
        }
        
        //virtualTLHC.x =displayDimension.width+(int)tlhc.x;
        //virtualTLHC.y =displayDimension.height +(int)tlhc.y;
        //draws the image in the bufferedImage
        drawInDeviceSpace(bufferedImage,newPixels, true,applyTo);
        
    }
    
    
    /**
     * Draws the image in the specified ImageBuffer with the specified zoom value
     * 
     * @param bufferedImage Specifies the BufferedImage in which the image will be drawn.
     * @param zoomValue Specifies the zoom value of the image.
     * @param newPixels false if the pixels must get from the c++ part of the code.
     * @since 30.04.1999
     */
    public void drawInDeviceSpace (BufferedImage bufferedImage,double zoomValue,boolean newPixels,boolean newBackground, int applyTo)
    {
        this.zoomValue = zoomValue;
        if (bufferedImage==null) return;
        displayDimension.height = bufferedImage.getRaster().getHeight();
        displayDimension.width = bufferedImage.getRaster().getWidth();
        drawInDeviceSpace(bufferedImage,newPixels, newBackground,applyTo);
        
    }
    
    /**
     * Draws the image in the specified ImageBuffer.
     * 
     * @param bufferedImage Specifies the BufferedImage in which the image will be drawn.
     * @param newPixels false if the pixels must get from the c++ part of the code.
     * @since 30.04.1999
     */
    public  void drawInDeviceSpace(BufferedImage bufferedImage,boolean newPixels,boolean newBackground, int applyTo)
    {
        System.out.println("--------------------------drawInDeviceSpace: " + number++);
        int yTLHC;
        int xTLHC;
        int yBRHC;
        int xBRHC;
        System.out.println("zoomValue: " + zoomValue);
        
        
        //Sets new screenRows ????
        if ((displayDimension.height!= bufferedImage.getRaster().getHeight())||
            (displayDimension.width!= bufferedImage.getRaster().getWidth()))
        {
            if (!displayDimension.equals(new Dimension(0,0)))
            {
                virtualTLHC.y = bufferedImage.getRaster().getHeight();
                virtualTLHC.x = bufferedImage.getRaster().getWidth();
            }
            displayDimension.height = bufferedImage.getRaster().getHeight();
            displayDimension.width = bufferedImage.getRaster().getWidth();
        }
            
            
        //
        if ((virtualTLHC.x - displayDimension.width) >= 0)
        {
            sourcePixelTLHC.x = virtualTLHC.x - displayDimension.width;
            displayPixelTLHC.x = 0;
            xTLHC = sourcePixelTLHC.x;
                    
        }
        else
        {
            sourcePixelTLHC.x = 0;
            displayPixelTLHC.x = displayDimension.width-virtualTLHC.x;
            xTLHC = -(int)Math.round(displayPixelTLHC.x/(zoomValue*presentationStateGraphicsHandler.getCurrentScalingX()));
        }
                
        if((virtualTLHC.y - displayDimension.height)>=0)
        {
            sourcePixelTLHC.y = virtualTLHC.y - displayDimension.height;
            displayPixelTLHC.y = 0;
            yTLHC =sourcePixelTLHC.y;
        }
        else
        {
            sourcePixelTLHC.y = 0;
            displayPixelTLHC.y = displayDimension.height-virtualTLHC.y;
            yTLHC = -(int)Math.round(displayPixelTLHC.y/(zoomValue*presentationStateGraphicsHandler.getCurrentScalingY()));
                    
        }
        
                
        //System.out.println(" sourcePixelTLHC.width: " +sourcePixelTLHC.x);
        //System.out.println(" screenDimension.width: " +screenDimension.width);
        //System.out.println(" displayPixelTLHC.width: " +displayPixelTLHC.x);
                
        //Calculates new visible BRHC of the image.
        sourcePixelBRHC = new Point (  (int)Math.round( sourcePixelTLHC.x +  ((displayDimension.width-displayPixelTLHC.x)/(zoomValue*presentationStateGraphicsHandler.getCurrentScalingX()))),
                                        (int) Math.round(sourcePixelTLHC.y +  ((displayDimension.height-displayPixelTLHC.y)/(zoomValue*presentationStateGraphicsHandler.getCurrentScalingY()))));
                
        //Calculates the new dispaly BRHC
        displayPixelBRHC =  new Point(displayDimension.width,displayDimension.height);
            
        yBRHC = yTLHC +(int)Math.round(displayDimension.height/(zoomValue*presentationStateGraphicsHandler.getCurrentScalingY()));
        xBRHC = xTLHC +(int)Math.round(displayDimension.width/(zoomValue*presentationStateGraphicsHandler.getCurrentScalingX()));
            
	    //transforms the display area    
	    AffineTransform  affDisplay = calculateSpatialTransfomation();     
            
        Point2D.Float brhcPoint = new Point2D.Float(xBRHC,yBRHC);
        brhcPoint = getInverseTransformedPoint(brhcPoint,affDisplay);
            
        Point2D.Float tlhcPoint = new Point2D.Float(xTLHC,yTLHC);
        tlhcPoint = getInverseTransformedPoint(tlhcPoint,affDisplay);
    /*
        System.out.println("Hallo calculate TLHC ");
        System.out.println(" yBRHC " +yBRHC);
        System.out.println(" xBRHC " +xBRHC);
        System.out.println(" xTLHC " +xTLHC);
        System.out.println(" yTLHC " +yTLHC);
        System.out.println(" brhcPoint " +brhcPoint);
        System.out.println(" tlhcPoint " +tlhcPoint);
        */           
            
        // 
        float change;
        //changes x values if image is flipped
        int rot = presentationStateGraphicsHandler.getRotation();
        if (rot ==0)
        {
            if (presentationStateGraphicsHandler.ps.getFlip())
            {
                change=tlhcPoint.x;
                tlhcPoint.x = brhcPoint.x;
                brhcPoint.x = change;
            }
                    
        }
        //changes y values if image is rotated 90 degree
        //if the image is rotated 90 degree and flipped 
        //the transfomation eliminates each other.
        else if (rot == 1)
        {
            if (!presentationStateGraphicsHandler.ps.getFlip())
            {
                change = tlhcPoint.y;
                tlhcPoint.y = brhcPoint.y;
                brhcPoint.y = change;
            }
               
        }
        //changes x and y values if image is rotated 180 degree
        //if the image is rotated 180 degree and flipped only 
        //the y values must be changed
        else if (rot == 2)
        {
            if (!presentationStateGraphicsHandler.ps.getFlip())
            {
                    
                change = tlhcPoint.y;
                tlhcPoint.y = brhcPoint.y;
                brhcPoint.y = change;
                            
                change = tlhcPoint.x;
                tlhcPoint.x = brhcPoint.x;
                brhcPoint.x = change;
            }
            else
            {
                change = tlhcPoint.y;
                tlhcPoint.y = brhcPoint.y;
                brhcPoint.y = change;
                        
            }
                    
        }
        //changes x values if image is rotated 270 degree
        //if the image is rotated 180 degree and flipped
        //the x an the y values must be changed
        else if (rot == 3)
        {
            if (!presentationStateGraphicsHandler.ps.getFlip())
            {
                    
                change = tlhcPoint.x;
                tlhcPoint.x = brhcPoint.x;
                brhcPoint.x = change;
            }
            else
            {
                change = tlhcPoint.y;
                tlhcPoint.y = brhcPoint.y;
                brhcPoint.y = change;
                            
                change = tlhcPoint.x;
                tlhcPoint.x = brhcPoint.x;
                brhcPoint.x = change;
                        
            }
                    
        }
        xBRHC = (int)brhcPoint.x;
        yBRHC = (int)brhcPoint.y;
        xTLHC = (int)tlhcPoint.x+1;
        yTLHC = (int)tlhcPoint.y+1;
        /*       
        System.out.println(" yBRHC " +yBRHC);
        System.out.println(" yTLHC " +yTLHC);
        System.out.println(" xBRHC " +xBRHC);
        System.out.println(" xTLHC " +xTLHC);
        System.out.println(" virtualTLHC : " + virtualTLHC);
	     System.out.println("Dispaly Mode: " + presentationStateGraphicsHandler.getDisplayArea());                                                   
        */
        //sets the new display area to the c++ part.
        System.out.println("drawInDeviceSpace -End1: " + applyTo);
        presentationStateGraphicsHandler.ps.setImageRelativeDisplayedArea(presentationStateGraphicsHandler.ps.getDisplayedAreaPresentationSizeMode(), xTLHC, yTLHC, xBRHC, yBRHC, zoomValue, applyTo);
        System.out.println("drawInDeviceSpace -End: " );
        
        
        //Calculates the transformations 
        calculateTransformation(zoomValue,sourcePixelTLHC, displayPixelTLHC);
        
        draw(bufferedImage,newPixels,newBackground);
        
    }

    /**
     * Draws the image in the specified ImageBuffer.
     * 
     * @param bufferedImage Specifies the BufferedImage in which the image will be drawn.
     * @param newPixels false if the pixels must get from the c++ part of the code.
    */
    public abstract void draw(BufferedImage bufferedImage,boolean newPixels, boolean newBackground);

    /**
     * Calculates the applying transformation 
     * 
     * @since 30.04.1999
     */
    
    public void calculatePrint(double zoom)
    
    {
            int rot = presentationStateGraphicsHandler.ps.getRotation();
	        boolean flip =presentationStateGraphicsHandler.ps.getFlip();
	        printAff = new AffineTransform();
	        printOverlayTransform = new AffineTransform();
	        DisplayArea da = presentationStateGraphicsHandler.getDisplayArea();  
	        float x1 =0;
	        float y1=0;
	        if (rot == 0)
	        {
	             x1 = (-da.tlhc_x+1);
	             y1 = (-da.tlhc_y+1);
	             if (flip) x1=(da.brhc_x -presentationStateGraphicsHandler.getImageWidth());
            } 
            else if (rot ==1)
            {
                
                    x1 = (da.brhc_y -presentationStateGraphicsHandler.getImageHeight());
                    y1= (-da.tlhc_x+1);
	                if (flip) x1=(-da.tlhc_y+1);
            }
            else if (rot ==2)
            {
                y1 = ((da.brhc_y -presentationStateGraphicsHandler.getImageHeight()));
                x1=  ((da.brhc_x -presentationStateGraphicsHandler.getImageWidth()));
	            if (flip) x1=(-da.tlhc_x+1);
                
            }
            else 
            {
                x1=  -da.tlhc_y+1;
                y1=  (da.brhc_x -presentationStateGraphicsHandler.getImageWidth());
	            if (flip) x1=(da.brhc_y -presentationStateGraphicsHandler.getImageHeight());
	            
                
            }
            
            printAff.scale(zoom,zoom);
	        printAff.translate(x1,y1);
            printOverlayTransform.scale(zoom,zoom);
	        printOverlayTransform.translate(x1,y1);
            //flipping
            if (flip)
            {
                printAff.scale(-1d,1d);
	            printAff.translate(-presentationStateGraphicsHandler.getCurrentImageWidth(),0);
	        }
            //rotation
           
            //if image height an image width are diffenent, there must set an offset.
            double diff =(presentationStateGraphicsHandler.getImageWidth()-presentationStateGraphicsHandler.getImageHeight())/2;
	        
	        if (rot ==1) 
	        {
	            printAff.translate(-diff,-diff);
	        }
	        else if (rot == 3)
	        {
	            printAff.translate(diff,diff);
	        }
	        
            printAff.rotate( (rot*0.5)*Math.PI,
                        (presentationStateGraphicsHandler.getCurrentImageWidth()/2d),
                        (presentationStateGraphicsHandler.getCurrentImageHeight()/2d));
            
    }
    
    void calculateTransformation(double zoom,   
                                    Point transSourceTLHC,
                                    Point transDisplayTLHC)
    {
	         
	        System.out.println("zoom: " + zoom);
	        System.out.println("presentationStateGraphicsHandler.getCurrentScalingX(): " + presentationStateGraphicsHandler.getCurrentScalingX());
	        System.out.println("presentationStateGraphicsHandler.getCurrentScalingY(): " + presentationStateGraphicsHandler.getCurrentScalingY());
	        //Calculate transformation for Annotations, Shutter usw.
	        aff = new AffineTransform();
	        overlayTransform = new AffineTransform(); 
	        //Offsets
	            
	        //horizontal offset
	        double x;
	            
	        //Vertical offset
	        double y ;
	            
	            
	        if (transSourceTLHC.x >0) x=(-transSourceTLHC.x)*zoom*presentationStateGraphicsHandler.getCurrentScalingX();
	        else x=transDisplayTLHC.x-zoom*presentationStateGraphicsHandler.getCurrentScalingX();
	            
	        if (transSourceTLHC.y >0) y= (-transSourceTLHC.y)*zoom*presentationStateGraphicsHandler.getCurrentScalingY();
	        else y=transDisplayTLHC.y-zoom*presentationStateGraphicsHandler.getCurrentScalingY();
	        aff.translate(x,y);
	        overlayTransform.translate(x,y);
	        
	        //zooming
	        aff.scale(zoom*presentationStateGraphicsHandler.getCurrentScalingX(),zoom*presentationStateGraphicsHandler.getCurrentScalingY());
            overlayTransform.scale(zoom*presentationStateGraphicsHandler.getCurrentScalingX(),zoom*presentationStateGraphicsHandler.getCurrentScalingY());
            //flipping
            if (presentationStateGraphicsHandler.ps.getFlip())
            {
                aff.scale(-1d,1d);
                if (presentationStateGraphicsHandler.ps.getDisplayedAreaPresentationSizeMode()==jDVPSPresentationSizeMode.DVPSD_trueSize)
                {
	                aff.translate(-presentationStateGraphicsHandler.getCurrentImageWidth(),0);
	            }
	            else
	            {
	                aff.translate(-presentationStateGraphicsHandler.getCurrentImageWidth()*presentationStateGraphicsHandler.getCurrentScalingX(),0);
	                
	            }
	        }
	            
            //rotation
            int rot = presentationStateGraphicsHandler.ps.getRotation();
           
                
            //if image height an image width are diffenent, there must set an offset.
            double diff =(presentationStateGraphicsHandler.getImageWidth()*presentationStateGraphicsHandler.getScX()-presentationStateGraphicsHandler.getImageHeight()*presentationStateGraphicsHandler.getScY())/2;
            System.out.println("diff: "+diff);
	        if (rot ==1) 
	        {
	            aff.translate(-diff,-diff);
	        }
	        else if (rot == 3)
	        {
	            aff.translate(diff,diff);
	        }
            if (presentationStateGraphicsHandler.ps.getDisplayedAreaPresentationSizeMode()==jDVPSPresentationSizeMode.DVPSD_trueSize)
            {
                aff.rotate( (rot*0.5)*Math.PI,
                            (presentationStateGraphicsHandler.getCurrentImageWidth()/2d),
                            (presentationStateGraphicsHandler.getCurrentImageHeight()/2d));
                
            }
            else
            {
                aff.rotate( (rot*0.5)*Math.PI,
                            (presentationStateGraphicsHandler.getCurrentImageWidth()*presentationStateGraphicsHandler.getCurrentScalingX()/2d),
                            (presentationStateGraphicsHandler.getCurrentImageHeight()*presentationStateGraphicsHandler.getCurrentScalingY()/2d));
	        }        
    }
    
    
    /**
     * Builds the AffineTransfomation which rotate and flip points.
     * 
     * @since 30.04.1999
     */
    AffineTransform calculateSpatialTransfomation()
    {
        AffineTransform returnTransform = new AffineTransform();
        
        //rotation
        int rot = presentationStateGraphicsHandler.ps.getRotation();
                
        //if image height an image width are diffenent, there must set an offset.
        double diff =(presentationStateGraphicsHandler.getImageWidth()-presentationStateGraphicsHandler.getImageHeight())/2;
	    
	    if (rot ==1) returnTransform.translate(-diff,diff);
	    else if (rot == 3)returnTransform.translate(-diff,diff);
	                
        //Rotates 90*rot degree
        returnTransform.rotate( (presentationStateGraphicsHandler.ps.getRotation()*0.5)*Math.PI,
                                ((presentationStateGraphicsHandler.getImageWidth()-1)/2d),
                                ((presentationStateGraphicsHandler.getImageHeight()-1)/2d));
        
        
        
        //flipping
        if (presentationStateGraphicsHandler.ps.getFlip())
        {
            if ((rot == 0)||(rot == 2))
            {
                returnTransform.scale(-1d,1d);
	            returnTransform.translate(-presentationStateGraphicsHandler.getImageWidth()+1,0);
	        }
	        else if ((rot== 1)||(rot == 3))
	        {
                returnTransform.scale(1d,-1d);
	            returnTransform.translate(0,-presentationStateGraphicsHandler.getImageHeight()+1);
	        }
	    }
	    
        return returnTransform;
    }
    
    /**
     * Gets the inverse transfomation of an specified point 
     * and an specified AffineTransformation.
     * 
     * @param displayPoint The point which should be transformed.
     * @param transAff The transformation which will be applied.
     * @return The inverse transfomation of the displayPoint.
     * @since 30.04.1999
     */
    public Point2D.Float getInverseTransformedPoint(Point2D.Float displayPoint,AffineTransform transAff)
    {
        Point2D.Float dstPoint = new Point2D.Float();
        try
        {
            transAff.inverseTransform(displayPoint,dstPoint);
        }
        catch(NoninvertibleTransformException e)
        {
            System.out.println("NoninvertibleTransformException: " + e);
        }
        return dstPoint;
    }
    
    /**
     * Returns the transformation for the PresentationStateAnnotationObject
     * 
     * @return The transformation for the PresentationStateAnnotationObject.
     * @since 30.04.1999
     */
    public AffineTransform getTransformation()
    {
        return aff;
    }
    public AffineTransform getPrintTransformation(double zoom)
    {
        calculatePrint(zoom);
        return printAff;
    }
    
    /**
     * Returns the transformation for the PresentationStateOverlayObject
     * 
     * @return The transformation for the PresentationStateOverlayObject.
     * @since 30.04.1999
     */
    public AffineTransform getOverlayTransformation()
    {
        return overlayTransform;
    }
    public AffineTransform getPrintOverlayTransformation()
    {
        return printOverlayTransform;
    }
    
}



/*
/*
 *  CVS Log
 *  $Log: TransformationConverter.java,v $
 *  Revision 1.2  2003/09/08 10:17:26  kleber
 *  Bugfix: The Displayed Area is defined after the spatial transformation.
 *
 *  Revision 1.1.1.1  2001/06/06 10:32:30  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
*/
