/*
 *
 *  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 09:00:23 $
 *  Revision :    $Revision: 1.2 $
 *  State:        $State: Exp $
*/

package browser;
 

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.border.*;
import javax.swing.*;
import javax.swing.tree.*;

import J2Ci.*;
import dicomscope.*;
import viewer.main.*;
import jToolkit.gui.*;
import main.*;

/**
 * This class contains the study browser. 
 * A tree shows the study/series/instance 
 * information hierarchically. 
 * 
 * @author Andreas Schroeter
 * @since 30.04.1999
 */
public class StudyMan extends JPanel implements MainListener
{
    /** 
    * The Interface class 
    */
    private jDVInterface dvi;
    
    /** 
    * The main tree containing all  data 
    */
    private JTree tree;
    
    /** 
    * Root element of the tree 
    */
    private DefaultMutableTreeNode root;
    
    /** 
    * Instance of the Frame class 
    */
    private DICOMscope parent;
    
    
    /** 
    * Thread to update the tree after recieving instances 
    */
    private UpdateThread ut;
    
    
    /** 
    * Folder where an image was loaded from 
    */
    private File oldLoadFileDir = null;
    //private String fileN;
    
    private boolean  warnUnsignedSrDouments   = false;
    /**
     * Constructor.
     * @param dvi  Interface to the DICOMtoolkit
     * @param parent DICOMscope frame
     * @param config Configuation of the StudyMan
     * @since 30.03
     */
    public StudyMan(jDVInterface dvi, DICOMscope parent,Hashtable config)	
    {	    
        super();
        this.dvi = dvi;
        this.parent = parent;
        
        Controller.instance().addMainListener(this);
        setLayout(new BorderLayout(5,5));
		
	//init Tree
	root = new DefaultMutableTreeNode (new TreeElement ("All Studies"));
	tree = new JTree (root);
		
	tree.setRootVisible(true);		
	tree.setShowsRootHandles(true);		
	tree.getSelectionModel().setSelectionMode (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
	tree.putClientProperty("JTree.lineStyle", "Angled"); // Linien zwischen Knoten
				
	tree.setCellRenderer(new MyTreeCellRenderer());
        
        //Init MouseListener
        MouseListener ml = new MouseAdapter() // load Image on double-click!
        {
            public void mouseClicked(MouseEvent e) 
            {
                int selRow = tree.getRowForLocation(e.getX(), e.getY());
                TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
                if(selRow != -1) 
                {
                    if(e.getClickCount() == 2) 
                    {                        
                        DefaultMutableTreeNode dm = (DefaultMutableTreeNode) selPath.getLastPathComponent();	 
                        if (dm.isLeaf())onLoad ();
                        
                    }
                }
            }
        };
        tree.addMouseListener(ml);        
            
        add("Center", new JScrollPane(tree));
    		
    	
    	loadAll();
        setConfiguaration (config, true);
        dvi.newInstancesReceived();
        tree.expandRow (0);
    }


    /**
    * If the tree has changed this functions updates the tree.
    * @since 30.03
    */
    private  synchronized void treeChanged ()
    {
            
        DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
        int n = tree.getRowCount();	    
    	    	    
        for (int i = 0; i < n; i++)
        {
	    TreePath tp = tree.getPathForRow(i);
	    DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tp.getLastPathComponent();
	    treemodel.nodeChanged(dm);	    
        }	    
    }
	
	
    /**
    * Rereshs the TreeElements from dvi and updates the tree
    * @since 30.03.99
    */
    synchronized void refreshTree ()
    {	
	    
	
        String studyUID;
        String seriesUID;
        String instanceUID;
        
        //TreeElemt
        TreeElement helpTreeElement= null;
        
        //Default
        DefaultMutableTreeNode studyNode = null;
        DefaultMutableTreeNode seriesNode = null;
        DefaultMutableTreeNode instanceNode = null;
        
        boolean hasStudyNode = false;
        boolean hasSeriesNode = false;
        boolean hasInstanceNode = false;
        
        //Treemodel init    
        DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
            
            
        int nrOfStudies = dvi.getNumberOfStudies ();
        //For all Studies     
        for (int st = 0; st < nrOfStudies; st++)
        {   
            int status = dvi.selectStudy (st);
            if (status != jE_Condition.EC_Normal)continue;
            
                
            //if the tree should not be reloaded and if the study contains no new object 
            //this study must not updated.
            int stStatus = dvi.getStudyStatus();
            studyUID = dvi.getStudyUID();
                
                           
            // Search in the tree for the Study
            int cc = root.getChildCount ();
            hasStudyNode = false;
	    for (int i = 0; i < cc; i++)
	    {
	        studyNode = (DefaultMutableTreeNode) root.getChildAt (i);
	        helpTreeElement = (TreeElement) studyNode.getUserObject();
            	        
        	if (helpTreeElement.studyUID.equals (studyUID))
        	{
        	    
        	    helpTreeElement.setStatus(stStatus);
        	    treemodel.nodeChanged(studyNode);
        	    hasStudyNode = true;
        	    break;
        	}	                	        
	    }  	        
    	        
	    if (!hasStudyNode) 
	    {
	         
                //Build treeElement for Study
                String dateTimeTest = dvi.getStudyDate ();
                if (dateTimeTest == null) dateTimeTest = toReadableTime(dvi.getStudyTime());
                else if (toReadableTime(dvi.getStudyTime()) != null) dateTimeTest = dateTimeTest + ", " + toReadableTime(dvi.getStudyTime());
                    
                String patientInfo;
                patientInfo = dvi.getPatientName();
                if (toReadableDate(dvi.getPatientBirthDate()) != null) patientInfo = patientInfo+ ", " + toReadableDate(dvi.getPatientBirthDate());
                studyNode = new DefaultMutableTreeNode();    
                studyNode.setUserObject( new TreeElement ("Study", 
                                        dvi.getStudyUID(),
                                        null,
                                        dvi.getStudyDescription(),
                                        patientInfo,
                                        dateTimeTest,
                                        null,
                                        null,
                                        stStatus));
	        root.add(studyNode);
	        
	    }
	   
            // ---
            //For all Series     
            int nrOfSeries = dvi.getNumberOfSeries ();
            for ( int se = 0; se < nrOfSeries; se++)
            {
                status=  dvi.selectSeries (se);
                if (status != jE_Condition.EC_Normal)continue;
                    
                //if the tree should not be reloaded and if the series contains no new object 
                //this instance must not updated.
                int seStatus = dvi.getSeriesStatus();
                seriesUID = dvi.getSeriesUID();     
                                           
                             
                 //BuildTreeElement   
                    
                // ---
                hasSeriesNode = false;
                
                // Search in the tree for the Series
                cc = studyNode.getChildCount ();         
	        for (int i = 0; i < cc; i++)
	        {
	            
	            seriesNode = (DefaultMutableTreeNode) studyNode.getChildAt (i);
	            helpTreeElement = (TreeElement) seriesNode.getUserObject();
                	        
        	    if (helpTreeElement.seriesUID.equals (seriesUID))
        	    {
        	            helpTreeElement.setStatus(seStatus);  
        	            treemodel.nodeChanged(seriesNode);
        	            hasSeriesNode= true;
        	        
        	        break;
        	    }    	                	        
	        }      	        
    	            
	        if (!hasSeriesNode) 
	        {
	         
                    String dateTimeTese = toReadableDate(dvi.getSeriesDate());
                    if (dateTimeTese == null) dateTimeTese = toReadableTime(dvi.getSeriesTime());
                    else if (toReadableTime(dvi.getSeriesTime()) != null) dateTimeTese = dateTimeTese + ", " + toReadableTime(dvi.getSeriesTime());
                    seriesNode = new DefaultMutableTreeNode();    
                    seriesNode.setUserObject( new TreeElement ("Series", 
                                            dvi.getStudyUID(), 
                                            dvi.getSeriesUID(), 
                                            dvi.getModality(),
                                            dvi.getSeriesDescription(),
                                            null,
                                            dateTimeTese,
                                            null,
                                            null,
                                            seStatus));
                    studyNode.add (seriesNode);
	    }
               
                    
                // for all Instances
                int nrOfInstances = dvi.getNumberOfInstances ();
                for (int in = 0; in < nrOfInstances; in++)
                {                 
                    status = dvi.selectInstance (in);
                    if (status != jE_Condition.EC_Normal)continue;
                    
                    int instStatus = dvi.getInstanceStatus();
                    instanceUID = dvi.getInstanceUID();    
                    
                // Search in the tree for the Instance
                    hasInstanceNode = false;
                    cc = seriesNode.getChildCount ();
                    
                    for (int i = 0; i < cc; i++)
	            {
	                instanceNode = (DefaultMutableTreeNode) seriesNode.getChildAt (i);
	                helpTreeElement = (TreeElement) instanceNode.getUserObject();
                    	        
        	        if (helpTreeElement.instanceUID.equals (instanceUID))
        	        {
        	             helpTreeElement.setStatus(instStatus);
        	            treemodel.nodeChanged(instanceNode);
        	            hasInstanceNode = true;
        	            break;
        	        }        	                	        
	            }
                    if (!hasInstanceNode)
	            {    
                        //Build TreeElement   
                        instanceNode = new DefaultMutableTreeNode ();
                        instanceNode.setUserObject(new TreeElement (null,
                                                dvi.getSeriesType(),
                                                dvi.getStudyUID(), 
                                                dvi.getSeriesUID(), 
                                                dvi.getInstanceUID(),
                                                dvi.getModality(),
                                                dvi.getInstanceDescription(),
                                                null,
                                                null,
                                                dvi.getFilename(studyUID, seriesUID, instanceUID),
                                                dvi.getPresentationLabel(),
                                                instStatus));
                            
                            seriesNode.add (instanceNode);
                            if (hasSeriesNode) treemodel.reload(seriesNode);
                            else if (hasStudyNode)
                            {
                                hasSeriesNode = true;
                                treemodel.reload(studyNode);
                            }
                            else
                            {
                                hasStudyNode = true;
                                hasSeriesNode =true;
                                treemodel.reload(root);
                            }
                            
                        }
                }
            }
	    
        }
            
        dvi.releaseDatabase();
            
    }

    /**
    * Loads the TreeElements from dvi and creates the tree
    * @since 30.03.99
    */
    synchronized void loadAll ()
    {	
	    
	//number of studies, series, instances
	int nrOfStudies, nrOfSeries, nrOfInstances;
        
        //TreeElemt
        TreeElement teSt, teSe, teInst;
        
        //Default
        DefaultMutableTreeNode currStudyNode;
    	DefaultMutableTreeNode currSeriesNode;
	DefaultMutableTreeNode currInstanceNode;
        
        
                    
        //Treemodel init    
        DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
        root.removeAllChildren();
	
                
            
            
            
        nrOfStudies = dvi.getNumberOfStudies ();
         
             
        //For all Studies     
        for (int st = 0; st < nrOfStudies; st++)
        {   
            int status = dvi.selectStudy (st);
            if (status != jE_Condition.EC_Normal)
            {
		dvi.writeLogMessage(jDVPSLogMessageLevel.DVPSM_warning,"GUI-Browser","Select study with index: " +st + " results in status: " +  status);
                continue;
            }
            
            int percent = (((st+1) * 100) / nrOfStudies);
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,("Loading " + percent + "%")));
            
            
                
            
            //Build treeElement for Study
            String dateTimeTest = dvi.getStudyDate ();
            if (dateTimeTest == null) dateTimeTest = toReadableTime(dvi.getStudyTime());
            else if (toReadableTime(dvi.getStudyTime()) != null) dateTimeTest = dateTimeTest + ", " + toReadableTime(dvi.getStudyTime());
                
            String patientInfo;
            patientInfo = dvi.getPatientName();
            if (toReadableDate(dvi.getPatientBirthDate()) != null) patientInfo = patientInfo+ ", " + toReadableDate(dvi.getPatientBirthDate());
                
            teSt = new TreeElement ("Study", 
                                    dvi.getStudyUID(),
                                    null,
                                    dvi.getStudyDescription(),
                                    patientInfo,
                                    dateTimeTest,
                                    null,
                                    null,
                                    dvi.getStudyStatus());
                
                           
        	    
    	        
	    currStudyNode = new DefaultMutableTreeNode (teSt);            
                
            //For all Series     
            nrOfSeries = dvi.getNumberOfSeries ();
            for ( int se = 0; se < nrOfSeries; se++)
            {
                status=  dvi.selectSeries (se);
                if (status != jE_Condition.EC_Normal)
                {
		    dvi.writeLogMessage(jDVPSLogMessageLevel.DVPSM_warning,"GUI-Browser","Select series with index: " +se + " results in status: " +  status);
                    continue;
                }
                    
                //if the tree should not be reloaded and if the series contains no new object 
                //this instance must not updated.
                int seStatus = dvi.getSeriesStatus();
                                           
                             
                 //BuildTreeElement   
                String dateTimeTese = toReadableDate(dvi.getSeriesDate());
                if (dateTimeTese == null) dateTimeTese = toReadableTime(dvi.getSeriesTime());
                else if (toReadableTime(dvi.getSeriesTime()) != null) dateTimeTese = dateTimeTese + ", " + toReadableTime(dvi.getSeriesTime());
                teSe = new TreeElement ("Series", 
                                        dvi.getStudyUID(), 
                                        dvi.getSeriesUID(), 
                                        null,
                                        dvi.getSeriesDescription(),
                                        null,
                                        dateTimeTese,
                                        null,
                                        null,
                                        seStatus);
                    
                
                
                
	        currSeriesNode = new DefaultMutableTreeNode (teSe);
                 currStudyNode.add(currSeriesNode);   
                // for all Instances
                nrOfInstances = dvi.getNumberOfInstances ();
                for (int in = 0; in < nrOfInstances; in++)
                {                 
                    status = dvi.selectInstance (in);
                    if (status != jE_Condition.EC_Normal) continue;
                    
                    //if the tree should not be reloaded and if the series contains no new object 
                    //this instance must not updated.
                    int instStatus = dvi.getInstanceStatus();
                        
                    //Modality for the series    
                    teSe.modality = dvi.getModality();
     
                        
                     //Build TreeElement   
                    teInst = new TreeElement (null,
                                            dvi.getSeriesType(),
                                            dvi.getStudyUID(), 
                                            dvi.getSeriesUID(), 
                                            dvi.getInstanceUID(),
                                            dvi.getModality(),
                                            dvi.getInstanceDescription(),
                                            null,
                                            null,
                                            dvi.getFilename(teSt.studyUID, teSe.seriesUID, dvi.getInstanceUID()),
                                            dvi.getPresentationLabel(),
                                            instStatus);                  
                    currInstanceNode = new DefaultMutableTreeNode (teInst);
                        
                 currSeriesNode.add(currInstanceNode);   
                        
                }

            }
            treemodel.insertNodeInto(currStudyNode, root, root.getChildCount());
	            
                
                
                
        }
        treemodel.reload();   
        dvi.releaseDatabase();
            
    }

    /**
    * Called if the load-file button was clicked. 
    * A File-Open-Dialog wil appear and
    * ask for a filename. The image will be loaded.
    * @since 30.03
    */
    private synchronized void onLoadFile ()
    {	
	    
	//Load Dicom File
	JFileChooser openDlg = new JFileChooser ();
	openDlg.setDialogTitle( "Open DICOM File");
	    
	//Opens the Dialog 
	if (oldLoadFileDir != null) openDlg.setCurrentDirectory (oldLoadFileDir);
	openDlg.showOpenDialog(null);
	oldLoadFileDir = openDlg.getCurrentDirectory();
	    
	if (openDlg.getSelectedFile() == null) return;
	String filename = openDlg.getSelectedFile().getPath();
	
	int status = dvi.loadImage (filename);
	  	  
        if (status != jE_Condition.EC_Normal)
        {
	    dvi.writeLogMessage(jDVPSLogMessageLevel.DVPSM_warning,"GUI-Browser","Load of image failed: " + filename+ " result in status: " +  status);
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Failed."));
	    (Toolkit.getDefaultToolkit()).beep();
            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    return;
            
        }
	    Controller.instance().fireEvent(new ImageActionEvent(this,
	                                    ImageActionEvent.ACTION_SETNEWIMAGE,
	                                    getNumberOfImages(dvi), 
	                                    getNumberOfFrames(dvi)));
	    parent.switchToViewer();
        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    
	    Controller.instance().fireStatus(new SignedStatusEvent(this,
	                        SignedStatusEvent.LOADIMAGE,
		                    dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_image), 
		                    dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
        
             
    }
    /**
    * Called if the load-file button was clicked. 
    * A File-Open-Dialog wil appear and
    * ask for a filename. The image will be loaded.
    * @since 30.03
    */
    private synchronized void onLoadSRFile ()
    {	
	    
	//Load Dicom File
	JFileChooser openDlg = new JFileChooser ();
	openDlg.setDialogTitle( "Open Structured Report File");
	    
	//Opens the Dialog 
	if (oldLoadFileDir != null) openDlg.setCurrentDirectory (oldLoadFileDir);
	openDlg.showOpenDialog(null);
	oldLoadFileDir = openDlg.getCurrentDirectory();
	    
	if (openDlg.getSelectedFile() == null) return;
	String filename = openDlg.getSelectedFile().getPath();
	
	int status = dvi.loadStructuredReport (filename);
	  	  
        if (status != jE_Condition.EC_Normal)
        {
	    dvi.writeLogMessage(jDVPSLogMessageLevel.DVPSM_warning,"GUI-Browser","Load of SR failed: " + filename+ " result in status: " +  status);
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Failed."));
	    (Toolkit.getDefaultToolkit()).beep();
            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    return;
            
        }
	    
	        dvi.disableImageAndPState();
	        Controller.instance().fireEvent(new ImageActionEvent(this,ImageActionEvent.ACTION_SETNEW_SR,null,null));
	        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
		    Controller.instance().fireStatus(new SignedStatusEvent(this,
		                        SignedStatusEvent.LOADSR,
		                        dvi.getCombinedImagePStateSignatureStatus(), 
		                        dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
	        parent.switchToViewer();
	    
	    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready."));
	    
             
    }

	/**
	 * Loads a presentation state from file
	 * @since 30.03
	 */
	private synchronized void onLoadPSFile ()
	{	
	    
	    setCursor (new Cursor (Cursor.WAIT_CURSOR));
	    
	    //Load Dicom File
	    JFileChooser openDlg = new JFileChooser ();
	    if (oldLoadFileDir != null) openDlg.setCurrentDirectory (oldLoadFileDir);
	    openDlg.setDialogTitle ("Open Presentation State");
	    openDlg.showOpenDialog(null);
	    oldLoadFileDir = openDlg.getCurrentDirectory();
	    String presstate = null;
	    
	    if (openDlg.getSelectedFile() == null)
	    {
	      
                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	        return;
	    }
	    presstate = openDlg.getSelectedFile().getPath();
	  	
	    int    status = dvi.loadPState (presstate);
            if (status != jE_Condition.EC_Normal)
            {
	        dvi.writeLogMessage(jDVPSLogMessageLevel.DVPSM_warning,"GUI-Browser","Load of Presentation State failed: " + presstate+ " result in status: " +  status);
	        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Failed."));
	        (Toolkit.getDefaultToolkit()).beep();
                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	        return;
                
            }
	    
	    Controller.instance().fireEvent(new ImageActionEvent(this,
	                                    ImageActionEvent.ACTION_SETNEWIMAGE,
	                                    getNumberOfImages(dvi), 
	                                    getNumberOfFrames(dvi)));
	    parent.switchToViewer();
            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
		Controller.instance().fireStatus(new SignedStatusEvent(this,
		                    SignedStatusEvent.LOADPS,
		                    dvi.getCombinedImagePStateSignatureStatus(), 
		                    dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
        
        
            
	}
	
	
	/**
	 * called after the load button was clicked. This method loads the selected instance
	 * or presentation state. If an instance was selected that have at least one 
	 * presentation state, a dialog box will appear. In this box you may select a 
	 * presentation state or the default state. Then the viewer will be shown with
	 * the loaded instance / presentation state.
	 * 
	 * @since 30.03
	 */
	public synchronized void onLoad()
	{
	    DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
	        
	    	    
	    if (tree.isSelectionEmpty()) 
	    {
		        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Can't Load - No Selection!"));
	        return;
	    }
	    
	    TreePath[] tps = tree.getSelectionPaths();
            String instanceUID=null ;
	      
	    int status = 0;
	    boolean selectedFirstImage = false;
	    boolean imagesLoaded = false;
	    boolean loadSR = false;
	    for (int i = 0; i < tps.length; i++)
	    {
	        
	        DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tps[i].getLastPathComponent();	 
    	        
    	        if (!dm.isLeaf()) continue;   
	           
	        TreeElement te = (TreeElement) dm.getUserObject();
	        	    
	        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading"));	    
    	    
	        instanceUID = te.instanceUID;	    
	    
	        setCursor (new Cursor (Cursor.WAIT_CURSOR));
	        
	        if (!te.isInstance()) continue;
	        
	        if (te.isST()) continue;
	        if (te.isSR()) 
	        {
	            if (i != 0) continue;
	            status =  dvi.selectInstance(te.studyUID, te.seriesUID, te.instanceUID);
	            if (status != 0 ) System.err.println("Error while selecting instance: " +  te.instanceUID + ", status: " + status);
	            if (status == 0)status = dvi.loadStructuredReport(te.studyUID, te.seriesUID, te.instanceUID,true);
	            if (status != 0) // Fehler
	            {
    	            
	                Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Failed."));
                        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                (Toolkit.getDefaultToolkit()).beep();
                        status = dvi.releaseDatabase();
	                return;
	            }
	            loadSR = true;
	            break;
	        }
	        imagesLoaded = true;
	        
	        if (!te.isPS ()) 
	        {	
	            if (!selectedFirstImage) 
	            {
	                
	                if (tps.length == 1) 
	                {
	                    status =  dvi.selectInstance(te.studyUID, te.seriesUID, te.instanceUID);
                            if (status != jE_Condition.EC_Normal)
                            {
	                         setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                         Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed"));	    
	                         return;
                            }
	                    int nps = dvi.getNumberOfPStates();
	                    if (nps == 0) 
	                    {
	                        
	                        status =  dvi.loadImage(te.studyUID, te.seriesUID, te.instanceUID,true);		    
	                    }
	                    else status = selectPState(te, te.instanceUID, te.seriesUID, te.studyUID);
                            if (status != jE_Condition.EC_Normal)
                            {
	                         setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                         Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed"));	    
	                         return;
                            }
	                    
	                }
	                else 
	                {
	                    
	                    status = dvi.loadImage(te.studyUID, te.seriesUID, te.instanceUID,true);
	                }
	                selectedFirstImage = true;
	            }
	            else 
	            {
	                status = dvi.addImageReferenceToPState(te.studyUID, te.seriesUID,te.instanceUID );
	            }
    	        
	            if (status == -1) 
	            {
	                
	                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                return;
	            }
	        }
	        else 
	        {
	            if (i == 0) status = dvi.loadPState(te.studyUID, te.seriesUID, te.instanceUID,true);
	           
	        }
    	    
	        if (status != 0) // Fehler
	        {
	            
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Failed."));
                    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	        }

	    }
            dvi.saveCurrentPStateForReset();
            status = dvi.releaseDatabase();
            refreshTree();
	    if (loadSR)
	    {
	        dvi.disableImageAndPState();
	        Controller.instance().fireEvent(new ImageActionEvent(this,ImageActionEvent.ACTION_SETNEW_SR,null,instanceUID));
	        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
		    Controller.instance().fireStatus(new SignedStatusEvent(this,
		                        SignedStatusEvent.LOADSR,
		                        dvi.getCombinedImagePStateSignatureStatus(), 
		                        dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
	        parent.switchToViewer();
	        
	    }
	    else
	    {
	            parent.switchToViewer();
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    Controller.instance().fireEvent(new ImageActionEvent(this,
	                                    ImageActionEvent.ACTION_SETNEWIMAGE,
	                                    getNumberOfImages(dvi), 
	                                    getNumberOfFrames(dvi)));
		    if (imagesLoaded)
		    {
		        Controller.instance().fireStatus(new SignedStatusEvent(this,
		                            SignedStatusEvent.LOADIMAGE,
		                            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_image), 
		                            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
		        
		    }
		    else
		    {
		        Controller.instance().fireStatus(new SignedStatusEvent(this,
		                            SignedStatusEvent.LOADIMAGE,
		                            dvi.getCombinedImagePStateSignatureStatus(), 
		                            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
	            }
	    }
	    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready."));
	    
	    
	}
	/**
	 * called after the load button was clicked. This method loads the selected image
	 * with the specified  presentation state. 
	 */
	public synchronized void onLoadImageForSR(  String sopClassUID, 
	                                            String sopInstanceUID,
	                                            String psSOPClassUid,
	                                            String psSOPInstanceUid, 
	                                            int[] frames)
	{
	    //sopInstanceUID = "1.2.276.0.7230010.3.200.13.2.1";
	    /*sopClassUID = "1.2.840.10008.5.1.4.1.1.7";
	    System.err.println("Imnage SOP Class UID: " + sopClassUID);
	    System.err.println("Image SOP Instance UID: " + sopInstanceUID);
	    System.err.println("PS SOP Class UID: " + psSOPClassUid);
	    System.err.println("PS SOP Instance UID: " + psSOPInstanceUid);
	    */
	    
	    DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading Image / Presentation State"));	    
    	    
	    setCursor (new Cursor (Cursor.WAIT_CURSOR));
	     
	    int status = dvi.selectInstance(sopInstanceUID,sopClassUID);                   
        if (status != jE_Condition.EC_Normal)
        {
	            System.err.println("Status: " + status);
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed, image maybe not in database"));	    
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	    }
	    //Load only the image
	    if (psSOPInstanceUid == null)
	    {
	          status =  dvi.loadImage(dvi.getStudyUID(), dvi.getSeriesUID(), dvi.getInstanceUID(),true);		    
              if (status != jE_Condition.EC_Normal)
              {
	                System.err.println("Status: " + status);
	                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed"));	    
	                (Toolkit.getDefaultToolkit()).beep();
                        status = dvi.releaseDatabase();
	                return;
	           }
	     }
	     //Load the image and the presentation state
	     else
	     {
	        String imageFileName = dvi.getFilename();
	         status = dvi.selectInstance(psSOPInstanceUid,psSOPClassUid);                   
            if (status != jE_Condition.EC_Normal)
            {
	                System.err.println("Status: " + status);
	                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed, image maybe not in database"));	    
	                (Toolkit.getDefaultToolkit()).beep();
                        status = dvi.releaseDatabase();
	                return;
	        }
	        String psFileName =dvi.getFilename();
	        status = dvi.loadPState(psFileName, imageFileName);                  
            if (status != jE_Condition.EC_Normal)
            {
	                System.err.println("Status: " + status);
	                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	                Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed, image maybe not in database"));	    
	                (Toolkit.getDefaultToolkit()).beep();
                        status = dvi.releaseDatabase();
	                return;
	        }
	        
	     }
	     
        status = dvi.releaseDatabase();
        refreshTree();
	    Controller.instance().fireEvent(new ImageActionEvent(this,
	                                    ImageActionEvent.ACTION_SETNEWIMAGE,
	                                    getNumberOfImages(dvi), 
	                                    getNumberOfFrames(dvi)));
	    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
		Controller.instance().fireStatus(new SignedStatusEvent(this,
		                    SignedStatusEvent.LOADIMAGE,
		                    dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_image), 
		                    dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
	        
	     if (warnUnsignedSrDouments)
	     {
	        if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) == jDVPSSignatureStatus.DVPSW_signed_OK ||
	            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) == jDVPSSignatureStatus.DVPSW_signed_unknownCA )
	        {
	            if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_image) == jDVPSSignatureStatus.DVPSW_unsigned)
	            {
    	            
	                JOptionPane.showMessageDialog (   this, 
                                                                    "Report is signed, but image is not",
						                    "Warning", 
	                                                            JOptionPane.WARNING_MESSAGE);
    	            
	            }
    	        
	        }
	     }
	     
	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready."));
	    
	    
	}
	/**
	 * called after the load button was clicked. This method loads the selected instance
	 * or presentation state. If an instance was selected that have at least one 
	 * presentation state, a dialog box will appear. In this box you may select a 
	 * presentation state or the default state. Then the viewer will be shown with
	 * the loaded instance / presentation state.
	 * 
	 * @since 30.03
	 */
	public synchronized void onLoadPSForSR(String sopClassUID, String sopInstanceUID)
	{
	    //sopInstanceUID = "1.2.276.0.7230010.3.200.13.0.2";
	    //sopClassUID = "1.2.840.10008.5.1.4.1.1.11.1";
	    //System.err.println("PS SOP Class UID: " + sopClassUID);
	    //System.err.println("SOP Instance UID: " + sopInstanceUID);
	    DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
	        
	    	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Presentation State"));	    
    	    
	        	    
	    
	    setCursor (new Cursor (Cursor.WAIT_CURSOR));
	        
	     int status = dvi.selectInstance(sopInstanceUID,sopClassUID);                   
            if (status != jE_Condition.EC_Normal)
            {
	            System.err.println("Status: " + status);
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed, ps maybe not in database"));	    
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	    }
	     status =  dvi.loadPState(dvi.getStudyUID(), dvi.getSeriesUID(), dvi.getInstanceUID(),true);		    
            if (status != jE_Condition.EC_Normal)
            {
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed"));	    
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	    }
            status = dvi.releaseDatabase();
            refreshTree();
	    Controller.instance().fireEvent(new ImageActionEvent(this,
	                                    ImageActionEvent.ACTION_SETNEWIMAGE,
	                                    getNumberOfImages(dvi), 
	                                    getNumberOfFrames(dvi)));
	        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
		    Controller.instance().fireStatus(new SignedStatusEvent(this,
		                        SignedStatusEvent.LOADPS,
		                        dvi.getCombinedImagePStateSignatureStatus(), 
		                        dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
	        //((parent.switchToViewer();
	    
	     if (warnUnsignedSrDouments)
	     {
	        if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) == jDVPSSignatureStatus.DVPSW_signed_OK ||
	            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) == jDVPSSignatureStatus.DVPSW_signed_unknownCA )
	        {
	            if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_image) == jDVPSSignatureStatus.DVPSW_unsigned)
	            {
    	            
	                JOptionPane.showMessageDialog (   this, 
                                                                    "Report is signed, but image is not",
						                    "Warning", 
	                                                            JOptionPane.WARNING_MESSAGE);
    	            
	            }
	            if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_presentationState) == jDVPSSignatureStatus.DVPSW_unsigned)
	            {
    	            
	                JOptionPane.showMessageDialog (   this, 
                                                                    "Report is signed, but Presentation State is not",
						                    "Warning", 
	                                                            JOptionPane.WARNING_MESSAGE);
    	            
	            }
    	        
	        }
	     }
	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready."));
	    
	    
	}
	/**
	 * called after the load button was clicked. This method loads the selected instance
	 * or presentation state. If an instance was selected that have at least one 
	 * presentation state, a dialog box will appear. In this box you may select a 
	 * presentation state or the default state. Then the viewer will be shown with
	 * the loaded instance / presentation state.
	 * 
	 * @since 30.03
	 */
	public synchronized void onLoadSRForSR(String sopClassUID, String sopInstanceUID)
	{
	    //System.err.println("SR For SR: " );
	   // System.err.println("SR SOP Class UID: " + sopClassUID);
	    //System.err.println("SOP Instance UID: " + sopInstanceUID);
	    DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
	    boolean signed = false;
	    if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) == jDVPSSignatureStatus.DVPSW_signed_OK ||
	            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) == jDVPSSignatureStatus.DVPSW_signed_unknownCA )
	    	        signed= true;
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Composite"));	    
    	    
	        	    
	    
	    setCursor (new Cursor (Cursor.WAIT_CURSOR));
	        
	     int status = dvi.selectInstance(sopInstanceUID,sopClassUID);                   
            if (status != jE_Condition.EC_Normal)
            {
	            System.err.println("Status: " + status);
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed, SR maybe not in database"));	    
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	    }
	      status = dvi.selectInstance(sopInstanceUID,sopClassUID);                   
            if (status != jE_Condition.EC_Normal)
            {
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed, SR maybe not in database"));	    
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	    }
	     status =  dvi.loadStructuredReport(dvi.getStudyUID(), dvi.getSeriesUID(), dvi.getInstanceUID(),true);		    
            if (status != jE_Condition.EC_Normal)
            {
	            setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading failed"));	    
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
	            return;
	    }
            status = dvi.releaseDatabase();
            refreshTree();
	        dvi.disableImageAndPState();
	        Controller.instance().fireEvent(new ImageActionEvent(this,ImageActionEvent.ACTION_COMPOSITE_SR,sopClassUID,  sopInstanceUID));
	        //((parent.switchToViewer();
	        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
		    Controller.instance().fireStatus(new SignedStatusEvent(this,
		                        SignedStatusEvent.LOADSR,
		                        dvi.getCombinedImagePStateSignatureStatus(), 
		                        dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
	    
	     if (warnUnsignedSrDouments&&signed)
	     {
	        if (dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) != jDVPSSignatureStatus.DVPSW_signed_OK &&
	            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport) != jDVPSSignatureStatus.DVPSW_signed_unknownCA )
	        {
    	            
	                JOptionPane.showMessageDialog (   this, 
                                                                    "Current Report is signed, but referenced report is not",
						                    "Warning", 
	                                                            JOptionPane.WARNING_MESSAGE);
    	            
	           
    	        
	        }
	     }
	     
	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready."));
	    
	}
	
	/**
	* Sends the selected Stored Print Objects to a Printer
	*/
	public synchronized void onPrintStToPrinter()
	{
	    DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
	        
	    	    
	    if (tree.isSelectionEmpty()) 
	    {
		        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Can't Print - No Selection!"));
	        return;
	    }
	    
	    TreePath[] tps = tree.getSelectionPaths();
	      
	    int status = 0;
	    boolean selectedFirstImage = false;
	    for (int i = 0; i < tps.length; i++)
	    {
	        DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tps[i].getLastPathComponent();	 
    	        
    	        if (!dm.isLeaf()) continue;   
	           
	        TreeElement te = (TreeElement) dm.getUserObject();
	        	    
	        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Printing Stored Print"));	    
    	    
	        	    
	    
	        setCursor (new Cursor (Cursor.WAIT_CURSOR));
	        
	        if (te.isST ()) 
	        {	
	            if (i == 0) 
	            {
	                status = dvi.spoolStoredPrintFromDB(te.studyUID, te.seriesUID, te.instanceUID);
	            }
	        }
    	        else
    	        {
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Error: Please select only Stored Print Objects"));
    	            
    	        }
	        if (status != 0) // Fehler
	        {
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Print Failed."));
                    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	            (Toolkit.getDefaultToolkit()).beep();
                    status = dvi.releaseDatabase();
                    
	            return;
	        }
	        
	    }
            
            status = dvi.releaseDatabase();
        
	    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready."));
	    
	}
	
	
	
	/**
	* Adds the selected Objects to the current Print Job. A number of Hardcopy Images can be 
	* Selected or one Stored Print Object
	*/
	private synchronized void onAddtoPrintJob()
	{
	    DefaultTreeModel treemodel = (DefaultTreeModel) tree.getModel();
	    	    
	    
	    TreePath tp = tree.getLeadSelectionPath();
	    
	    if (tp == null) 
	    {
		        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Can't Add to Print - No Selection!"));
	        return;
	    }
	    
            
	    DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tp.getLastPathComponent();
	    TreeElement te= (TreeElement) dm.getUserObject();
	    
	    
	    if ((!te.isInstance())||(!te.isHC() && !te.isST()))
	    {
	        
	        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Error: Add only Hardcopy Images or Stored Print Objects to Print Job"));
	        return ;
	    }
	    if (te.isST())
	    {
                int respond = JOptionPane.showConfirmDialog(parent,"Replace current Print Job?","Load Stored Print Object", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE );
	        if (respond!=JOptionPane.YES_OPTION) return;
	        
	    }
	    	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Add to Print"));	    
	    
	    int status;	    
	    
	    setCursor (new Cursor (Cursor.WAIT_CURSOR));
	    if (te.isHC())
	    {
	        status = dvi.addToPrintHardcopyFromDB(te.studyUID, te.seriesUID, te.instanceUID);
	        dvi.instanceReviewed(te.studyUID, te.seriesUID, te.instanceUID);
	    }
	    else
	    {
	        status = dvi.loadStoredPrint(te.studyUID, te.seriesUID, te.instanceUID,true);
	        
	    }
	    if (status != 0) // Fehler
	    {
	        
	        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Load Failed."));
	        (Toolkit.getDefaultToolkit()).beep();
                setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
                status = dvi.releaseDatabase();
                refreshTree();
	        return;
	    }
            
            status = dvi.releaseDatabase();
            refreshTree();
            if (te.isHC())Controller.instance().firePrint(new PrintEvent(this,PrintEvent.ID_HC));
            else 
            {
                Controller.instance().firePrint(new PrintEvent(this,PrintEvent.ID_ST));
                parent.switchToPrinter();
            }
	    
	    
	    setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	    
	    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Ready"));
	    
	}
	
	/**
	 * Sends the selected Objects with the DICOM C-Store
	 * @since 30.03
	 */
	public void onSend()
	{   	    
	    
        // Dialog
	    SendToDlg sdlg = new SendToDlg (parent, dvi);
	    sdlg.show();
	    
	    if (!sdlg.okClicked) return;    
	    
	    if (tree.isSelectionEmpty()) return;
	    
	    DefaultTreeModel treemodel= (DefaultTreeModel) tree.getModel();
	    
	    String lastSendedSeriesUid ="";
	    String lastSendedStudyUid = "";
	    
	    while (true)
	    {
	        if (tree.isSelectionEmpty()) return;
	        
	        TreePath tps = tree.getPathForRow(tree.getMinSelectionRow());
	        DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tps.getLastPathComponent();	    
	        MutableTreeNode parent = (MutableTreeNode) dm.getParent();
	        if (parent == null) return; // root element ? -> abort
	        TreeElement te = (TreeElement)dm.getUserObject();	    
                Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Network - Sending IOD"));
	        if (te.studyUID != null && te.seriesUID == null)
	        {
                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Network - Sending Study IOD: "+ te.toString()));
	             dvi.sendStudy (sdlg.selectedItem, te.studyUID);	    
	             lastSendedStudyUid = te.studyUID;
	        }
	        else  if (te.instanceUID == null) 
	        {
                    if (!lastSendedStudyUid.equals(te.studyUID))
                    {
                        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Network - Sending Series IOD: "+ te.toString()));
	                dvi.sendSeries (sdlg.selectedItem, te.studyUID, te.seriesUID);
	                lastSendedSeriesUid = te.seriesUID;
	                
	            }
	        }
	        else if (te.instanceUID != null)
	        {
                    if ((!lastSendedStudyUid.equals(te.studyUID))&&(!lastSendedSeriesUid.equals( te.seriesUID)))
                    {
                    
                        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Network - Sending Instance IOD: "+ te.toString()));
	                dvi.sendIOD (sdlg.selectedItem, te.studyUID, te.seriesUID, te.instanceUID);
	            }
	        }
	        tree.removeSelectionRow(tree.getMinSelectionRow());
	    }
	}
	
	/**
	 * Called after the Dump button was clicked. A list box will appear to select the
	 * destination workstation to send the selected study/series/instance/presentation
	 * state to. Details can be requested with the Detail button.
	 * @since 30.03
	 */
	public void onDump()
	{   	    
            
            if (tree.isSelectionEmpty() ) return ;
            
            TreePath tp = tree.getLeadSelectionPath();
	        
	    DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tp.getLastPathComponent();
	    TreeElement te=  (TreeElement) dm.getUserObject();
	    
	    
	    if (te.isInstance())dvi.dumpIOD(te.studyUID, te.seriesUID, te.instanceUID);
	    
	}
	
	/**
	* Checks the Selected Instance 
	*/
	public void onCheckIOD()
	{
            if (tree.isSelectionEmpty() ) return ;
            TreePath tp = tree.getLeadSelectionPath();
	    DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tp.getLastPathComponent();
	    TreeElement te=  (TreeElement) dm.getUserObject();
	    if (te.isInstance())dvi.checkIOD(te.studyUID, te.seriesUID, te.instanceUID);
	    
	}
	
	
	/**
	 * Delete the selected TreeElements. 
	 * @since 30.03
	 */
	public synchronized void onDelete()
	{	
	    
	    TreePath[] tps = tree.getSelectionPaths();
	    if ((tps == null)||(tps.length == 0)) return;
	    
	           
	    TreeElement te;	 
	    
	    //TreePath tp = tree.getLeadSelectionPath();
	    DefaultTreeModel treemodel= (DefaultTreeModel) tree.getModel();
	    
	    
	    if ( tree.getMinSelectionRow()== 0)
	    {
	        
                int respond = JOptionPane.showConfirmDialog(parent,"Do you really want to delete all studies?","Delete Objects",  JOptionPane.OK_OPTION, JOptionPane.WARNING_MESSAGE );
	        if (respond==JOptionPane.NO_OPTION) return;
    	        
	        root.removeAllChildren();
	        treemodel.reload();
    	        
	        // delete all from the database...
    	        
	        String studyUID;
	        while (dvi.getNumberOfStudies() > 0)
	        {
	            dvi.selectStudy(0);
	            studyUID = dvi.getStudyUID();
	            dvi.deleteStudy(studyUID);
	        }
	        return;
	    }
            int respond = JOptionPane.showConfirmDialog(parent,"Are you sure?","Delete Objects",  JOptionPane.OK_OPTION, JOptionPane.WARNING_MESSAGE );
	    if (respond==JOptionPane.NO_OPTION) return;
	    
	    String lastSendedSeriesUid =null;
	    String lastSendedStudyUid = null;
	    TreeElement oldElement = null;
	    
	    while (true)
	    {
	        if (tree.isSelectionEmpty()) break;
	        
	        TreePath tp = tree.getPathForRow(tree.getMinSelectionRow());
	        DefaultMutableTreeNode dm = (DefaultMutableTreeNode) tp.getLastPathComponent();	    
	        MutableTreeNode parent = (MutableTreeNode) dm.getParent();
	        
	        te = (TreeElement)dm.getUserObject();	    
	        if (te.isInstance())
	        {
        	        
	            dvi.deleteInstance(te.studyUID, te.seriesUID, te.instanceUID);
	            
	            
	            DefaultMutableTreeNode dmse = (DefaultMutableTreeNode) dm.getParent();
	            if (dmse == null) continue;
	            
	            DefaultMutableTreeNode dmst = (DefaultMutableTreeNode) dmse.getParent();
	            if (dmst == null) continue;
	            
	            treemodel.removeNodeFromParent(dm);
	            
	            TreeElement teSe = (TreeElement) dmse.getUserObject();
	            
	            
	            if (dmse.getChildCount() == 0) treemodel.removeNodeFromParent(dmse);
	            else treemodel.nodeChanged(dmse);	
	            if (dmst.getChildCount() == 0) treemodel.removeNodeFromParent(dmst);
	            else treemodel.nodeChanged(dmst);
	            
	        }
	        else
	        if (te.isSeries())
	        {	            
        	        
    	    
	            dvi.deleteSeries(te.studyUID, te.seriesUID);
	           
	            
	            DefaultMutableTreeNode dmst = (DefaultMutableTreeNode) dm.getParent();
	            if (dmst == null) continue;
    	            
	            treemodel.removeNodeFromParent(dm);
	            
	            if (dmst.getChildCount() == 0) treemodel.removeNodeFromParent(dmst);
	            else treemodel.nodeChanged(dmst);	
	            
	        }
	        else
	        {	            
	            dvi.deleteStudy(te.studyUID);
	            treemodel.removeNodeFromParent(dm);	            
	        }
	        
	    }
	    dvi.releaseDatabase();
	    refreshTree();
	    
	}
    
    /**
     * Corrects the given date (yyyymmdd) to a "readable" date (mm/dd/yyyy).
     * if the year is 2 digits long, the output will be "mm/dd/yy".
     * 
     * @param ddate  a date to correct
     * @return the corrected date
     * @since 30.03
     */
	protected String toReadableDate (String ddate)
	{
        if (ddate.length () == 8) // long format
        {
            return ddate.substring (4, 6) + "/" + ddate.substring (6, 8) + "/" + ddate.substring (0, 4);
        }
        else if (ddate.length () == 6) // short format
        {
            return ddate.substring (2, 4) + "/" + ddate.substring (4, 6) + "/" + ddate.substring (0, 2);
        }
        else return null;
	}	
	
	/**
	 * Corrects the given time (hhmmss) to a "readable" time (hh:mm).
	 * 
	 * @param dtime   a time to correct.
	 * @return the corrected time
	 * @since 30.03
	 */
	protected String toReadableTime (String dtime)
	{
        if (dtime.length () == 6) // short format
        {
            return dtime.substring (0, 2) + ":" + dtime.substring (2, 4);
        }
        else return null;
	}		
	
	
	/**
	 * Starts the Thread
	 * 
	 * @since 30.03
	 */
	public void startThread()
	{
	    ut = new UpdateThread (this, dvi);
	    ut.start();
            dvi.writeLogMessage(jDVPSLogMessageLevel.DVPSM_informational,"GUI","Started update Thread" );
	}
	
	
	/**
	 * Selects a PState for a loaded image.
	 * @param te          the selected Tree element
	 * @param instanceUID the instance UID
	 * @param seriesUID   series UID
	 * @param studyUID    study UID
	 * @since 30.03
	 */
	public int selectPState(TreeElement te, String instanceUID, String seriesUID, String studyUID)
	{
	    int status;
	    
	    JDialog selPStatDlg = new JDialog (parent, "Select Presentation State", true);
	    
	    DefaultListModel lm = new DefaultListModel(); 
	    JList info = new JList(lm);	    
	    	    
	    selPStatDlg.getContentPane().setLayout (new BorderLayout (5, 5));
	    selPStatDlg.setLocation (200, 150);
	    
	    DisposeCommand okDC, cancelDC;
	    
	    CommandJButton okBt = new CommandJButton (okDC = new DisposeCommand(selPStatDlg), 0);
	    okBt.setText("  Ok  ");
		okBt.setBackground(java.awt.Color.lightGray);		
		JPanel p = new JPanel ();
		p.add (okBt);
		
		CommandJButton cancelBt = new CommandJButton (cancelDC = new DisposeCommand(selPStatDlg), 1);
	        cancelBt.setText("  Cancel  ");
		cancelBt.setBackground(java.awt.Color.lightGray);				
		p.add (cancelBt);
		
		
		
		lm.addElement ("<default>");
	        status = dvi.selectInstance(te.studyUID,te.seriesUID,te.instanceUID);		
	        if (status != jE_Condition.EC_Normal) 
	        {
	            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"PS Load Failed"));
		    return 0;
		}
		int nps = dvi.getNumberOfPStates();
		for (int i = 0; i < nps; i++)
		{
		    String descr = dvi.getPStateDescription(i);
		    String label = dvi.getPStateLabel(i);
		    if (descr == null) descr = new String ("<no descr>");
		    else if (descr.length() == 0) descr = new String ("<no descr>");
		    if (label == null) label = new String ("<no label>");
		    else if (label.length() == 0) label = new String ("<no label>");
		    
		    lm.addElement (label + " * " + descr);
		}
		
		info.setSelectedIndex(0);
		
		selPStatDlg.getContentPane().add ("South", p);
		selPStatDlg.getContentPane().add ("Center", new JScrollPane(info));
		
	    selPStatDlg.pack();
	    selPStatDlg.setVisible(true);
	    
	   if (cancelDC.wasClicked()) 
	   {
	        setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
	     
	     return -1;
	    }
	    	    
	    int sidx = info.getSelectedIndex() - 1;
	    
	    status = dvi.loadImage(studyUID, seriesUID, instanceUID,true);
	    if (status != jE_Condition.EC_Normal) 
	    {
	        Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"PS Load Failed"));
		return 0;
	    }
	    
	    if (sidx >= 0) 
	    {	
	        status = dvi.selectInstance(studyUID, seriesUID, instanceUID);
	        status = dvi.selectPState (sidx, true);
	        refreshTree();
	        if (status != jE_Condition.EC_Normal) Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"PS Load Failed"));
	    }	    	    
	    return status;
	}   
	    	
	/**
	* 
	*/
	public boolean processEvent (DSEvent e)
	{
	    if (e instanceof DbActionEvent)
	    {
            DbActionEvent de = (DbActionEvent)e;
            switch (de.type)
            {
                case DbActionEvent.LOAD_IM: 
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading Image from File"));
                                onLoadFile();
                                break;
                case DbActionEvent.LOAD_PS:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading Presentation State from File"));
                                onLoadPSFile();
                                break;
                case DbActionEvent.LOAD_SR:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading Structured Report from File"));
                                onLoadSRFile();
                                break;
                case DbActionEvent.LOAD_DB:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Loading Image"));
                                onLoad();
                                
                                break;
                case DbActionEvent.SAVE_DB:
                                
                                onSave(de.savePS);
                                break;
                case DbActionEvent.SAVE_AS:
                                OnSaveFile();
                                break;
                case DbActionEvent.SAVE_SCREEN:
                                Controller.instance().fireEvent(new RequestEvent(this,RequestEvent.REQUEST_SCREEN));
                                break;
                case DbActionEvent.REFRESH:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Refreshing Browser"));
	    	                    //root.removeAllChildren();
    	                            
    	                            loadAll();
    	                            tree.expandRow (0);	
                                
                                break;
                                
                case DbActionEvent.DELETE:
			                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Delete IOD(s)"));
                                onDelete();
                                break;
                case DbActionEvent.SENDTO:
			                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Send IOD to Network"));
                                onSend();
                                break;
                case DbActionEvent.PRINTHC:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Add Hardcopy Image to Print"));
                                    onAddtoPrintJob();
                                break;
                case DbActionEvent.PRINTSTTOPRINTER:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Print Stored Print Object"));
                                onPrintStToPrinter();
                                break;
                case DbActionEvent.PRINTST:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Add Stored Pint Object to Print Job"));
                                    onAddtoPrintJob();
                                    break;
                case DbActionEvent.DUMP:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Create Dump"));
                                onDump();
                                break;
                case DbActionEvent.CHECKIOD:
	    	                    Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.BROWSER,"Check IOD"));
                                onCheckIOD();
                                break;
                 case   DbActionEvent.LOAD_IMAGE_FOR_SR:
                                onLoadImageForSR(de.sopClassUid, de.instanceUid, de.psSOPClassUid, de.psInstanceUid, de.frames);
                        break;
                 case   DbActionEvent.LOAD_PS_FOR_SR:
                                onLoadPSForSR(de.sopClassUid, de.instanceUid);
                        break;
                 case   DbActionEvent.LOAD_SR_FOR_SR:
                                onLoadSRForSR(de.sopClassUid, de.instanceUid);
                        break;
                 case   DbActionEvent.SAVE_DB_SR:
                                onSaveSR();
                        break;
                        
                        
                                
            }
	    }
	    if (e instanceof SendScreenEvent)
	    {
	        OnSaveScreen((SendScreenEvent) e);
	    }
	    
	    if (e instanceof ChangeOptionsEvent)
	    {
                setConfiguaration (((ChangeOptionsEvent)e).getConfig(), false);
	    }
	    if (e instanceof UpdateBrowserEvent)
	    {
                refreshTree();
	    }
	    
	    return false;
	}
	/**
	* Konfiguriert.
	*/
	public void setConfiguaration(Hashtable config, boolean init)
	{

            if (config.containsKey("WarnUnsignedSrDouments"))warnUnsignedSrDouments=(((Boolean)config.get("WarnUnsignedSrDouments")).booleanValue());
            
            
            if (config.containsKey("UID"))TreeElement.showUID=(((Boolean)config.get("UID")).booleanValue());
            if (config.containsKey("Description"))TreeElement.showDescription=(((Boolean)config.get("Description")).booleanValue());
            if (config.containsKey("PatientInfo"))TreeElement.showPatientInfo=(((Boolean)config.get("PatientInfo")).booleanValue());
            if (config.containsKey("Modality"))TreeElement.showModality=(((Boolean)config.get("Modality")).booleanValue());
            if (config.containsKey("DateTime"))TreeElement.showDateTime=(((Boolean)config.get("DateTime")).booleanValue());
            if (config.containsKey("NewItems"))TreeElement.showNewWithIcon=(((Boolean)config.get("NewItems")).booleanValue());
            if (config.containsKey("Filename"))TreeElement.showFilename=(((Boolean)config.get("Filename")).booleanValue());
            if (config.containsKey("Label"))TreeElement.showLabel=(((Boolean)config.get("Label")).booleanValue());
	    treeChanged ();
            if (config.containsKey("BrowserBackgroundColor"))
            {
                Color color = (Color)config.get("BrowserBackgroundColor");
                if (color != getBackground()) 
                {
                    tree.setBackground(color);
                    updateUI();
                }
            }
            
            if (init)
            {
                if (config.containsKey("AutoUpdateStudyBrowser"))
                {
                    boolean on  = ((Boolean)config.get("AutoUpdateStudyBrowser")).booleanValue();
                    if (on) 
                    {
                        startThread();
                    }
                }
                
            }
	    
	}
	
	
    /**
     * Saves the current screen as a DICOM SC file.
     * You can save the files in different transfer syntax
     *
     * @since 30.03.1999
     */
    public void OnSaveScreen(SendScreenEvent e)
    {
	    JFileChooser saveDlg = new JFileChooser ();
	    saveDlg.setDialogTitle( "Save Current Screen as DICOM File");
	    
	    //Opens the Dialog 
	    if (oldLoadFileDir != null) saveDlg.setCurrentDirectory (oldLoadFileDir);
	    saveDlg.showSaveDialog(null);
	    oldLoadFileDir = saveDlg.getCurrentDirectory();
        
	    if (saveDlg.getSelectedFile() == null)return;
	    
	    String filename = saveDlg.getSelectedFile().getPath();
	    
	    boolean explicitVR = chooseExplicitVR ();
	    
	        dvi.saveDICOMImage (filename, e.data, 
	            e.width, 
	            e.height, 
	            1.0, explicitVR, e.instanceUID);
    }
    public synchronized void onSave(boolean savePS)
    {
            
        if (saveDisplayArea( false, savePS))
        {
        
            refreshTree ();
	        Controller.instance().fireStatus(new SignedStatusEvent(this,
		                SignedStatusEvent.LOADPS,
		                dvi.getCombinedImagePStateSignatureStatus(), 
		                dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
    		            
        }
    }
    public synchronized void onSaveSR()
    {
            
        int status = dvi.saveStructuredReport();
        if (status != 0) 
        {
            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.ALL,"Can't save SR document."));
        }
        else 
        {
	    Controller.instance().fireStatus(new SignedStatusEvent(this,
		                SignedStatusEvent.LOADPS,
		                dvi.getCombinedImagePStateSignatureStatus(), 
		                dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
            
            Controller.instance().fireStatus(new StatusLineEvent(this,StatusLineEvent.SET_DES,DSComponentType.ALL,"Save SR document."));
        }
        refreshTree ();
    }
    
    
    
    
    /**
     * Creates and shows a Dialog where you can choose the transfer syntax
     * of the saving presentation state.
     *
     * @since 30.03.1999
     */
    public boolean chooseExplicitVR ()
    {
        JRadioButton e, i;
	    JButton ok;
	    
	    JDialog expDlg = new JDialog (parent, "Choose VR", true);
	    
	    expDlg.setLocation (200, 200);
	    expDlg.getContentPane().setLayout(new GridLayout(3, 1));
	    ButtonGroup group1 = new ButtonGroup();
	    e = new JRadioButton("Explicit VR Little Endian",  true);
	    i = new JRadioButton("Implicit VR Little Endian",  false);
	    group1.add(e);
	    group1.add(i);
        expDlg.getContentPane().add(e);
        expDlg.getContentPane().add(i);
        JPanel p = new JPanel ();
        p.add (ok = new CommandJButton ("OK", new DisposeCommand (expDlg), 0));        
        expDlg.getContentPane().add(p);
        expDlg.pack();
        expDlg.show();
        
        return e.isSelected();
    }
    
    /**
     * Saves the current presentation state and the dicom image as file.
     * You can save the files in different transfer syntax
     *
     * @since 30.03.1999
     */
    public void OnSaveFile()
    {
            saveDisplayArea( true,true); 
    }
           
     /**
     * Saves the current presentation state. 
     * @param saveAsFile if true, the current presentation state and the 
     * referred images will be saved as a file. If false, the current presentation 
     * and the reffered images will be stred in the database.
     */
     public boolean saveDisplayArea(boolean saveAsFile, boolean savePS)
     
     {
            
            String fileName = null;
            
            //Open the fileOpendialog
            if (saveAsFile)
            {
	        JFileChooser saveDlg = new JFileChooser ();
	        saveDlg.setDialogTitle( "Save DICOM File");
	    
	        //Opens the Dialog 
	        if (oldLoadFileDir != null) saveDlg.setCurrentDirectory (oldLoadFileDir);
	        saveDlg.showSaveDialog(null);
	        oldLoadFileDir = saveDlg.getCurrentDirectory();
        
	        if (saveDlg.getSelectedFile() == null)return false;
	    
	        fileName = saveDlg.getSelectedFile().getPath();
	    
                
            }
            String title = "Save Presentation State to Database";
            if (saveAsFile) title = "Save Presentation State to File";
            SavePresentationStateDialog p =new SavePresentationStateDialog(parent, saveAsFile, title, savePS);
            p.setVisible(true);
           
            
            //return
            if (p.getActionValue() == SavePresentationStateDialog.ID_CANCEL) return false;
            
            
            
            
            jDVPresentationState ps = dvi.getCurrentPState();
            jIntByRef tlhcX = new jIntByRef();
            jIntByRef tlhcY = new jIntByRef();
            jIntByRef brhcY = new jIntByRef();
            jIntByRef brhcX = new jIntByRef();
                
            jIntByRef height = new jIntByRef();
            jIntByRef width = new jIntByRef();
            double magnifactionRatio= 1d;
            int sizeMode;
            
            String dcmFilename;
                
            int numImages = ps.numberOfImageReferences();
            for (int i = 0; i< numImages; i++)
            {
                if (p.saveImageSize())
                {
                        dvi.selectInstance(i);
                        magnifactionRatio = 1d;
                        ps.getImageWidth(width);
                        ps.getImageHeight(height);
                        sizeMode = ps.getDisplayedAreaPresentationSizeMode();
                        if (sizeMode == jDVPSPresentationSizeMode.DVPSD_magnify)
                        {
                            jDoubleByRef magnification = new jDoubleByRef();
                            ps.getDisplayedAreaPresentationPixelMagnificationRatio(magnification);
                            magnifactionRatio = magnification.value;
                        }
                        ps.getImageRelativeDisplayedArea( tlhcX,  tlhcY,  brhcX,  brhcY);
                        ps.setImageRelativeDisplayedArea(sizeMode, 1, 1,width.value , height.value,magnifactionRatio, jDVPSObjectApplicability.DVPSB_currentImage);
	         }       
	        if (saveAsFile)
	        {
	            if (numImages == 1)dcmFilename =fileName + ".dcm";
	            else dcmFilename =fileName + i+".dcm";
	            dvi.saveCurrentImage (dcmFilename, p.saveAsExplicit());
	        }
	        
            }
	    if (saveAsFile)
	    {
	        String PSfilename = fileName + ".pre";
                
                dvi.savePState (PSfilename, true,p.saveAsExplicit());
            }
            else dvi.savePState (true);
                
       return true;     
    }
    public int getNumberOfImages(jDVInterface dvi)
    {
        return dvi.getNumberOfImageReferences();
        
    }
    
    public int getNumberOfFrames(jDVInterface dvi)
    {
        jDVPresentationState ps = dvi.getCurrentPState();
         dvi.loadReferencedImage(0,false);
         jIntByRef value = new jIntByRef();
         int status= ps.getImageNumberOfFrames(value);
         if (status != jE_Condition.EC_Normal)return -1;
          dvi.releaseDatabase();
          return value.value;
    }
}
/*
 *  CVS Log
 *  $Log: StudyMan.java,v $
 *  Revision 1.2  2003/09/08 09:00:23  kleber
 *  move DICOMscope to folder dicomscope.
 *
 *  Revision 1.1.1.1  2001/06/06 10:32:29  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
*/
