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

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import de.microtherapy.tools.text.document.dicom.*;

import main.*;
import J2Ci.*;
/**
 * This class contains the GUI vizualizing a Dicom Structured Report 
 * as an HTML document.
 * 
 * @author Klaus Kleber
 * @since 08.11.2000
 */
public class SRViewPanel extends JPanel implements HyperlinkListener
{
    
    
    
    /**
    * Contains the names of the loaded SR Objects.
    */
    private JComboBox loadedSRNamesBox;
    
    /**
    * ActionListener for the loadedSRNamesBox
    */
    private NameBoxActionListener nameBoxActionListener= new NameBoxActionListener();
    
    /**
    * The loaded SR Objects will be cached in this object
    */ 
    private Vector cachedObjects = new Vector();
    
    /**
    * Contains the SOP Instance UIDs of the loaded SR objects 
    */
    private Vector cachedInstances = new Vector();
    
    /**
    *Contains the current loded DICOMinstance
    */
    DICOMInstance currentDicomInstance = null;
    
    /**
    *Contains the current loded DICOMinstance
    */
    DICOMInstance changedDicomInstance = null;
    /**
    * Contains the JSrcollPane for the JEditorPane.
    */
    private JScrollPane scroll;
    
    /**
    * Property name for the sr-type. This property can be part of a link in a HTML-Side
    */
    private  static final String SR_TYPE = "srtype";
    
    /**
    * Property name for the SOP Class UID. This property can be part of a link in a HTML-Side
    */
    private static final String SOP_CLASS_UID = "SOP Class UID";
    
    /**
    * Property name for the SOP Instance UID. This property can be part of a link in a HTML-Side
    */
    private static final String SOP_INSTANCE_UID = "SOP Instance UID";
    
    /**
    * Property name for the Haost. This property can be part of a link in a HTML-Side
    */
     public static final String TYPE_IMAGE = "image";
     public static final String TYPE_FRAME = "frame";
     public static final String TYPE_COMPOSITE = "composite";
     public static final String TYPE_PSTATE = "pstate";
     public static final String TYPE_WAVEFORM = "waveform";
    
    private static final String HOST = "host";
    /**
    * Contains a virtual URL. If the JEditorPane 
    * will be initialized with a String anchor in the 
    * HTML side cannot be resolved. Futhermore there HyperlinksEvents 
    * doesn't contain any URL. For this reason we set this ULR as base for
    * the HTMLDocument in the JEditorPane
    */
    private String helpCodeBase = "file://help/text.html";
    JButton  verificationButton;
    JButton completeButton;
    JButton saveButton;
    JButton resetButton;
    JButton editButton;
    JButton hackerEditButton;
    JButton revisedButton;
    
    JPanel buttonPanel;
    /**
    * JEditorPane displaying the HTML document
    */
    private JReferenceEditorPane  editorPane = new JReferenceEditorPane();
    
    /**
    * HTMLEditorKit in editorPane
    */
    private HTMLEditorKit eKit;
    /**
    * HTMLDocument in editorPane
    */
    private HTMLDocument doc ;
    
    /**
    * Tilted Boder containing the name of the SR Object
    */
    private TitledBorder titledBorder = new TitledBorder("Structured Report");
    
    /**
    * Current DVI Interface
    */
    private jDVInterface dvi;
    
    public MainImageViewerPanel mainView;
    /**
     * Constructor
     * 
     * @param dvi jDVInterface
     */
    public SRViewPanel(jDVInterface dvi, MainImageViewerPanel mainView  )
    {
        this.dvi = dvi;
        this.mainView = mainView;
        setLayout(new BorderLayout());
        setBorder(new TitledBorder("Structured Report Viewer"));
        //CenterPanel
        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.setBorder(titledBorder);
        add (centerPanel, BorderLayout.CENTER);
        
        buttonPanel = new JPanel();
        
        
        //JEditorPane
        editorPane.setEditable(false);
        scroll = new JScrollPane(editorPane);
        centerPanel.add (scroll, BorderLayout.CENTER);
        
        editorPane.setContentType("text/html");
        editorPane.addHyperlinkListener(this);
        editorPane.setEditable(false);
        
        
        
        eKit = new HTMLEditorKit();
        editorPane.setEditorKit(eKit);
            
        //Set Base
        doc = (HTMLDocument)editorPane.getDocument(); 
        try
        
        {
            
            doc.setBase(new URL(helpCodeBase));
        }
        catch (Exception e)
        {
            System.err.println("Er: " + e);
        }
       
        
        //North
        JPanel northPanel = new JPanel(new BorderLayout(5,5));
        add(northPanel, BorderLayout.NORTH);
        
        
        
        
        
        Action[] act = editorPane.getActions();
        Hashtable actions;
        actions = new Hashtable();
        for (int i = 0; i < act.length; i++)
        {   
            actions.put(act[i].getValue(Action.NAME), act[i]);
            //System.err.println("name: " + act[i].getValue(Action.NAME));
        }
        
        
        northPanel.add(buttonPanel,BorderLayout.EAST);
        
        
        GuiComponents gui = GuiComponents.getInstance();
    
        JButton beginButton = gui.srViewBeginButton;
        beginButton.setToolTipText("Goto Begin");
        //buttonPanel.add(beginButton);
        beginButton.addActionListener(new BeginAction());
        
        JButton endButton =gui.srViewEndButton;
        endButton.setToolTipText("Goto End");
       // buttonPanel.add(endButton);
        endButton.addActionListener((Action)actions.get("selection-end"));
    
        JButton pageUpButton =gui.srViewUpButton;
        pageUpButton.setToolTipText("Page Up");
        //buttonPanel.add(pageUpButton);
        pageUpButton.addActionListener((Action)actions.get("page-up"));
        
        JButton  pageDownButton= gui.srViewDownButton;
        pageDownButton.setToolTipText("Page Down");
        //buttonPanel.add(pageDownButton);
        pageDownButton.addActionListener((Action)actions.get("page-down"));
        
        buttonPanel.add(Box.createHorizontalStrut(5));
        
        JButton copyButton = gui.srViewCopyButton;
        copyButton.setToolTipText("Copy to Clipboard");
        buttonPanel.add(copyButton);
        copyButton.addActionListener((Action)actions.get("copy-to-clipboard"));
        
        editButton = gui.srEditButton;
        editButton.setToolTipText("Edit");
        buttonPanel.add(editButton);
        editButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               editSR(false);
            }
        });
        ActionListener a = new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               editSR(true);
            }
        };
        registerKeyboardAction(a, 
                                KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.ALT_MASK, false), 
                                JComponent.WHEN_IN_FOCUSED_WINDOW);
                                
        revisedButton = gui.srRevisedButton;
        revisedButton.setToolTipText("Revise");
        //buttonPanel.add(revisedButton);
        revisedButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               revised(false);
            }
        });
        
        buttonPanel.add(Box.createHorizontalStrut(5));
        
        completeButton= gui.srCompleteButton;
        completeButton.setToolTipText("Complete Document");
        buttonPanel.add(completeButton);
        completeButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                setComplete();
            }
        });
        completeButton.setEnabled(false);
        
        verificationButton= gui.srVerificationButton;
        verificationButton.setToolTipText("Verify Document");
        verificationButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               setVerification();
            }
        });
        buttonPanel.add(verificationButton);
        verificationButton.setEnabled(false);
        
        saveButton= gui.srSaveButton;
        saveButton.setToolTipText("Save Document to database");
        saveButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               save();
            }
        });
        buttonPanel.add(saveButton);
        
        resetButton= gui.srResetButton;
        resetButton.setToolTipText("Reset Document");
        resetButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               reset();
            }
        });
        buttonPanel.add(resetButton);
        
        
        saveButton.setEnabled(false);
        resetButton.setEnabled(false);
        
        
        Box box = new Box(BoxLayout.X_AXIS );
        box.add(new JLabel("Loaded SR Objects: "));
        box.add(box.createHorizontalStrut(5));
      
        loadedSRNamesBox = new JComboBox();
        loadedSRNamesBox.addActionListener(nameBoxActionListener);
        //box.add(loadedSRNamesBox);
        loadedSRNamesBox.setAlignmentX(0.5f);
        loadedSRNamesBox.setAlignmentY(0.5f);
        northPanel.add(loadedSRNamesBox,BorderLayout.CENTER);
        
    }
    private void setVerification()
    {
        VerificationDialog vd = new VerificationDialog( dvi,  mainView,saveButton.isEnabled());
        vd.setVisible(true);
        if (vd.isVerified())
        {
                
             setChangedSR();
        }
        
    }
    public void revised(boolean hackerMode)
    {
        
        jDSRDocument sr = dvi.getCurrentReport();
        
        if (!saveButton.isEnabled())
        {
            
            sr.createRevisedVersion();
	    sr.setSpecificCharacterSetType(jDSRE_CharacterSet.CS_Latin1);
	}
	else
	{
            int res=    JOptionPane.showConfirmDialog(loadedSRNamesBox,
                            "Only saved documents can be revised.\nDo you want to save this document?",
                            "Message",
                            JOptionPane.YES_NO_OPTION );
                            
	    if (res == JOptionPane.NO_OPTION) return;
	    save();
	}
        mainView.addEditSR(hackerMode);
    }
    
    
    public void setComplete()
    {
            CompleteDialog cd = new CompleteDialog(mainView.parent);
            cd.setVisible(true);
            if (cd.cancelAction == false)
            {
                //setComplete();
                jDSRDocument sr = dvi.getCurrentReport();
        
                if (!saveButton.isEnabled())
                {   
	            sr.createNewSOPInstance();
	            sr.setSpecificCharacterSetType(jDSRE_CharacterSet.CS_Latin1);
	     
                            //System.err.println("Revised: ");
                }
                int status = sr.completeDocument(cd.descriptionText.getText());
                if (status != 0) System.err.println("Can't complete document. Status: " + status);
                setChangedSR();
                    
                
            }
    }
    public void setRevisedButton()
    {
        Component[] c = buttonPanel.getComponents();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] == editButton)
            {
                buttonPanel.remove(editButton);
                buttonPanel.add(revisedButton, i);
                buttonPanel.revalidate();
                buttonPanel.repaint();
                return;
            }
        }
        
    }
    
    
    public void setEditButton()
    {
        Component[] c = buttonPanel.getComponents();
        for (int i = 0; i < c.length; i++)
        {
            if (c[i] == revisedButton)
            {
                buttonPanel.remove(revisedButton);
                buttonPanel.add(editButton, i);
                buttonPanel.revalidate();
                buttonPanel.repaint();
                return;
            }
        }
    }
    
    public void save()
    {
        Controller.instance().fireEvent(new DbActionEvent(this,DbActionEvent.SAVE_DB_SR));
        saveButton.setEnabled(false);
        resetButton.setEnabled(false);
        
        
    }
    public void reset()
    {
        saveButton.setEnabled(false);
        resetButton.setEnabled(false);
        loadedSRNamesBox.removeActionListener(nameBoxActionListener);
        
        int index = loadedSRNamesBox.getSelectedIndex();
        loadedSRNamesBox.removeItemAt(index);
        
        cachedInstances.removeElementAt(index);
        cachedObjects.removeElementAt(index);
        loadedSRNamesBox.addActionListener(nameBoxActionListener);
        
        int instanceIndex = isInstanceInCache(changedDicomInstance.sopInstanceUid);
        loadedSRNamesBox.setSelectedIndex(instanceIndex);
        loadObject((Properties)cachedObjects.elementAt(instanceIndex));
    }
    public void delete()
    {
        //Controller.instance().fireEvent(new DbActionEvent(this,DbActionEvent.SAVE_DB_SR));
        saveButton.setEnabled(false);
        resetButton.setEnabled(false);
        loadedSRNamesBox.removeActionListener(nameBoxActionListener);
        int index = isInstanceInCache(currentDicomInstance.sopInstanceUid);
        loadedSRNamesBox.removeItemAt(index);
        cachedInstances.removeElementAt(index);
        cachedObjects.removeElementAt(index);
        loadedSRNamesBox.addActionListener(nameBoxActionListener);

        
    }
    
    public void editSR(boolean hackerMode)
    {
        
        jDSRDocument sr = dvi.getCurrentReport();
        if (!saveButton.isEnabled())
        {
            if (!hackerMode)
            {
                sr.createNewSOPInstance();
            }
	        sr.setSpecificCharacterSetType(jDSRE_CharacterSet.CS_Latin1);
	    }
        mainView.addEditSR(hackerMode);
    }
    

    
    /**
    * Sets the specified instance visible.
    * @param Specifies the index of the instance in cacheHTML and loadedSRNamesBox.
    */
    private void setInstanceVisible(int index)
    {
        //setString((String)cacheHTML.elementAt(index));
       // System.err.println("setInstanceVisible index "+index);
        loadObject((Properties)cachedObjects.elementAt(index) );
    }
                    

    /**
    * Not used yet
    */
    public void setConfiguration(Hashtable config, String orient)
    {
	   
    }
    
    /**
    * Handles the received HyperlinkEvents.
    * 
    */
    public void hyperlinkUpdate(HyperlinkEvent e) 
    {
         //System.err.println(e.getEventType() );    
        
        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) 
        {
            //Gets the selected URL
            URL url = e.getURL();
            //System.err.println("url: " + url);
            
            
            if (url != null)
            {
                //Check if URL in contains an anchor
                int index = url.toString().indexOf("#");
                if (index!= -1)
                {
                    //Switch to anchor
                    editorPane.scrollToReference(url.toString().substring(index+1));
                }
                
                //Load referenced object
                else
                {
                    Properties currentProperties = getTokens(url.toString());
                    if (currentProperties != null)
                    {
                        loadObject(currentProperties);
                    }
                }
            }
        }
        else if(e.getEventType() ==HyperlinkEvent.EventType.ENTERED) 
        { 
            Cursor c = new Cursor (Cursor.HAND_CURSOR); 
            editorPane.setCursor(c); 
        } 
        else if(e.getEventType() == HyperlinkEvent.EventType.EXITED) 
        { 

            Cursor c = new Cursor(Cursor.DEFAULT_CURSOR); 
            editorPane.setCursor(c); 

        } 

} 
    
    public void loadObject(Properties prop)
    {
        
        
        //Gets Properties form URL
        String srtype = prop.getProperty(SR_TYPE);
                        
        //Request Image
        //Request Image
        if (srtype.equals(TYPE_WAVEFORM))
        {
            JOptionPane.showMessageDialog(this, "References to Waveform objects not supported.");
        }
        //Request PS
        else if (srtype.equals(TYPE_PSTATE))
        {
            DICOMInstance instance = (DICOMInstance)prop.get(TYPE_PSTATE);
            DICOMInstance instanceImage = (DICOMInstance)prop.get(TYPE_IMAGE);
            Controller.instance().fireEvent(new DbActionEvent(
                        this,
                        DbActionEvent.LOAD_IMAGE_FOR_SR,
                        instanceImage.sopClassUid,
                        instanceImage.sopInstanceUid,
                        instance.sopClassUid,
                        instance.sopInstanceUid,
                        (int[])prop.get(TYPE_FRAME)));
        }
        else if (srtype.equals(TYPE_IMAGE))
        {
            DICOMInstance instance = (DICOMInstance)prop.get(TYPE_IMAGE);
            Controller.instance().fireEvent(new DbActionEvent(
                                            this,
                                            DbActionEvent.LOAD_IMAGE_FOR_SR,
                                            instance.sopClassUid,
                                            instance.sopInstanceUid,
                                            (int[])prop.get(TYPE_FRAME)));
        }
        else if (srtype.equals(TYPE_COMPOSITE))
        {

            DICOMInstance instance = (DICOMInstance)prop.get(TYPE_COMPOSITE);
            if (    instance.sopClassUid.equals(DICOMSOPClassUID.BASIC_TEXT_SR_UID)||
                    instance.sopClassUid.equals(DICOMSOPClassUID.ENHANCED_SR_UID)||
                    instance.sopClassUid.equals(DICOMSOPClassUID.COMPREHENSIVE_SR_UID))
            {
                    if (saveButton.isEnabled()==true)
                    {
                        int res=    JOptionPane.showConfirmDialog(loadedSRNamesBox,
                                        "The current report is not yet saved. Save it now?",
                                        "Warning",
                                        JOptionPane.YES_NO_OPTION );
                        if (res ==JOptionPane.OK_OPTION) save();
                        else delete(); 
                    }
                    
                    Controller.instance().fireEvent(new DbActionEvent(this,DbActionEvent.LOAD_SR_FOR_SR,instance.sopClassUid,instance.sopInstanceUid, null ));
            }
            else if(instance.sopClassUid.equals(DICOMSOPClassUID.PS_UID))
            {
                Controller.instance().fireEvent(new DbActionEvent(this,DbActionEvent.LOAD_PS_FOR_SR,instance.sopClassUid,instance.sopInstanceUid ,null));
            }
            
            else JOptionPane.showMessageDialog(this, "References to " + instance.sopClassUid +" objects not supported.");
        }   
        else JOptionPane.showMessageDialog(this, "SOP Class " + srtype + " not supported");
                         
    }
    
    
    /**
    * Checks if the specified SOP Instance UID is cached 
    * and returns the index in the cache.
    * @param sopInstanceUID The SOP Instance UID.
    * @return The index of the SOP Instance UID in the cache or -1 in not available
    */
    private int isInstanceInCache(String sopInstanceUID)
    {
        if (sopInstanceUID == null ||cachedInstances == null) return -1;
        for (int i = 0; i <cachedInstances.size(); i++)
        {
            if (sopInstanceUID.equals((String)cachedInstances.elementAt(i))) return i;
        }
        return -1;
    }
    
    
    /**
    * Loads a new SR object with the specified SOP Instance UID
    * @param sopInstanceUID SOP Instance UID
    */
    public void setNewSR()
    {
        saveButton.setEnabled(false);
        resetButton.setEnabled(false);
        
        loadedSRNamesBox.removeAllItems();
        
        
        cachedObjects = new Vector();
        cachedInstances = new Vector();
        setSR();
    }
    
    
    /**
    * Loads a new SR object with the specified SOP Instance UID
    * @param sopInstanceUID SOP Instance UID
    */
    public void setChangedSR()
    {
        if (!saveButton.isEnabled())
        {
            changedDicomInstance = currentDicomInstance;
            saveButton.setEnabled(true);
            resetButton.setEnabled(true);
        }
        setSR();
    }
    
    /**
    * Sets the SR and returns the Tilte of this Object
    */
    private void setSR()
    {
        jDSRDocument sr = dvi.getCurrentReport();
        String value = sr.getPatientsName();
        
        jStringByRef s = new jStringByRef();
        int status = sr.renderHTML(s, 0);
        verificationButton.setEnabled(false);
        int completeStatus = sr.getCompletionFlag();
        if (completeStatus == jDSRE_CompletionFlag.CF_invalid)
        {
            setEditButton();
            
            System.err.println("undefined complete flag");
        }
        else if (completeStatus == jDSRE_CompletionFlag.CF_Partial)
        {
            completeButton.setEnabled(true);
            setEditButton();
        }
        else 
        {
            
            setRevisedButton();
            completeButton.setEnabled(false);
            int verifyStatus = sr.getVerificationFlag();
            if (verifyStatus == jDSRE_VerificationFlag.VF_invalid)
            {
                System.err.println("undefined verification flag");
            }
        
            else verificationButton.setEnabled(true);
         
        
        }
        
        
        if (status != 0) JOptionPane.showMessageDialog( SwingUtilities.getRoot(this),"Can't create HTML document. Please check log file", "Error", JOptionPane.ERROR_MESSAGE);
       
        DICOMInstance dicomInstance =new DICOMInstance(sr.getSOPClassUID(),sr.getSOPInstanceUID());
       int index = isInstanceInCache(dicomInstance.sopInstanceUid);
        loadedSRNamesBox.removeActionListener(nameBoxActionListener);
        String title=  setString(s.value);
       if (index== -1)
       {
            Properties p = new Properties();
            p.put(SR_TYPE,TYPE_COMPOSITE);
            p.put(TYPE_COMPOSITE,dicomInstance);
            cachedInstances.add(dicomInstance.sopInstanceUid);   
            cachedObjects.add(p);
            loadedSRNamesBox.addItem(new String(title + "/" + dicomInstance.sopInstanceUid ));
            loadedSRNamesBox.setSelectedIndex(loadedSRNamesBox.getItemCount()-1);
            
       }
       else
       {
        loadedSRNamesBox.setSelectedIndex(index);
            
       }
       currentDicomInstance = dicomInstance;
        loadedSRNamesBox.addActionListener(nameBoxActionListener);
       
       
    }
    
    private String setString(String s)
    {
        if (s == null) return  "";
        editorPane.setText(s);
        String title = doc.getProperty(Document.TitleProperty).toString();
        titledBorder.setTitle(title);
        editorPane.select(0,0);
        JScrollBar v = scroll.getVerticalScrollBar();
        v.setValue(0);
        v.repaint();
        if (title == null) title = "untitled";
        return title;
    }
    
    /**
    * Loads a Composite SR object with the specified SOP Instance UID
    */
    public void setNewCompositeSR()
    {
        
        setSR();
    }
    
    /**
    * Splits the URL into his components and returns a Property object
    * containing the values. Each URL contains of 4 values after the protocol type
    * (e.g http://): The values can be accessed by the following keys:
    * <i>"host", "srtype", "SOP Class UID", "SOP Instance UID"</i>.
    * @param s String containing the URL
    * @return The comonets of the URL. NULL if error;
    */
    public Properties getTokens(String s)
    {
        Properties returnValue = new Properties();
        int index = s.indexOf("?")+1;
        if (index >= s.length())
        {
            System.err.println("Error in link: " + s);
            return null;
        }
        String parse = s.substring(index);
        
        StringTokenizer st = new StringTokenizer (parse, "&");
        
        while (st.hasMoreTokens()) 
        {
            String token = st.nextToken();
            String type =null;
            if (token.startsWith(TYPE_IMAGE)) type = TYPE_IMAGE;
            else if (token.startsWith(TYPE_FRAME)) type = TYPE_IMAGE;
            else if (token.startsWith(TYPE_COMPOSITE)) type = TYPE_COMPOSITE;
            else if (token.startsWith(TYPE_PSTATE)) type = TYPE_PSTATE;
            else if (token.startsWith(TYPE_WAVEFORM)) type = TYPE_WAVEFORM;
            
            if (type == null)
            {
                System.err.println("Error in link: " + s);
                return null;
                
            }
            returnValue.put(SR_TYPE,type);
            if (type != TYPE_FRAME)
            {
                int index1 = token.indexOf("+");
                String classUID = token.substring(type.length()+1,index1);
                String instanceUID = token.substring(index1+1);
                //System.err.println("Type: " + type  +" SOP Class UID" + classUID + " SOP Instance UID:" + instanceUID);
                returnValue.put(type,new DICOMInstance(classUID,instanceUID));
            }
            else
            {
                StringTokenizer fTokenizer = new StringTokenizer(token.substring(type.length()+1), "+");
                try
                {
                    int[] frameIds = new int[fTokenizer.countTokens()];
                    int i = 0;
                    while (fTokenizer.hasMoreTokens()) 
                    {
                        String fToken = fTokenizer.nextToken();
                        frameIds[i] = new Integer(fToken).intValue();
                        i++;
                    }
                    returnValue.put(type,frameIds);
                }
                catch (Exception e)
                {
                    System.err.println("Error in link: " + s+ "\n" +e);
                    return null;
                }
                
            }
         
        }

        return returnValue;
    }
    /**
    * Return the position of an anchor or -1 if the anchor is not in the HTML code
    * @param anchor HTML Anchor name
    * @return GetStartOffset of the HTML anchor or -1 if  not found
    */
    public int getAnchorPositon(String anchor)
    {
        HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);
        while (it.isValid())
        {
            AttributeSet as =it.getAttributes();
            String thisref = (String) as.getAttribute(HTML.Attribute.NAME);
            if (thisref != null &&thisref.equals(anchor))
            {
                return it.getStartOffset();
            }
            it.next();
        }
        return -1;
    }
         /**
         * Go to the begin of the HTMLDocument
         */
          private class BeginAction extends AbstractAction 
          {
                public void actionPerformed(ActionEvent e)
                {
                    editorPane.select(0,0);
                    JScrollBar v = scroll.getVerticalScrollBar();
                    v.setValue(0);
                    v.repaint();
                    
                }
          }
          
          public class CompleteDialog extends JDialog
          {
            public JTextArea descriptionText = new JTextArea(4,16);
            public boolean cancelAction = true;
            
            public CompleteDialog(Component parent)
            {
                super((JFrame)(null), "Complete Document", true);
                getContentPane().setLayout(new BorderLayout(5,5));
                Point p = completeButton.getLocationOnScreen();
                //System.err.println(p);
                setLocation(new Point(p.x-100, p.y+100));
                
                JButton okButton = new JButton("Complete");
	        okButton.setToolTipText ("Set Completion Flag");
                okButton.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        setVisible(false);
                        cancelAction = false;
                        dispose();
                    }
                });
                JButton cancelButton = new JButton("Cancel");
	        cancelButton.setToolTipText ("Cancel");
                cancelButton.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        setVisible(false);
                        dispose();
                    }
                });
                JPanel centerPanel = new JPanel(new BorderLayout(5,5));
                centerPanel.setBorder(new TitledBorder("Description"));
                descriptionText.setDocument(new LODocument());
                descriptionText.setLineWrap(true);
                descriptionText.setWrapStyleWord(true);
                centerPanel.add(descriptionText, BorderLayout.CENTER);
                
                
                getContentPane().add(centerPanel, BorderLayout.CENTER);
                
                JPanel bPanel = new JPanel();
                bPanel.add(okButton);
                bPanel.add(cancelButton);
                
                getContentPane().add(bPanel, BorderLayout.SOUTH);
                
                pack();
            }
          }
         public class NameBoxActionListener implements java.awt.event.ActionListener
        {
            public void actionPerformed(java.awt.event.ActionEvent e)
            {
                
                //System.err.println("actionPerformed");
                if (loadedSRNamesBox.getItemCount() > 1)
                {
                    setInstanceVisible(loadedSRNamesBox.getSelectedIndex());
                }
                        
                
            }
        }
             public Dimension getPreferredSize()
             {
                return new Dimension (10,10);
             }
             public Dimension getMinimumSize()
             {
                return new Dimension (10,10);
             }
             public Dimension getMaximumSize()
             {
                return new Dimension (10,10);
             }
        
}
/*
 *  CVS Log
 *  $Log: SRViewPanel.java,v $
 *  Revision 1.1.1.1  2001/06/06 10:32:30  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
*/
