/*
 *
 *  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 java.util.*;
import java.net.*;
import  de.microtherapy.tools.text.document.dicom.*;

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 javax.swing.tree.*;

import main.*;
import J2Ci.*;

/**
 * This class contains an abstract class
 * for editing a Content Item in a SR.
 * Each Content Item contains of a Concept Name
 * and an optional ObservationDateTime.
 * This class is a JPanel with a BorderLayout.
 * In the north the GUI for visualising and changing the
 * Concept Name is placed. In the south the
 * field for the Observation Date Time is placed
 * <p>
 * In the constructor the JPanel is build. Each extending class 
 * have to implement the {@link initContentItemGUI} method. This method is used
 * for placing the returned component in the center of this panel.
 *
 * @author Klaus Kleber
 * @since 20.08.1999
 */
public class SRCodeChangePanel extends JPanel 
{
    
    /**
    * Enable/disable the Listener
    */
    protected boolean isListenerEnabled = false;
    
   
    /**
    * Contains the documentTree.
    */ 
    protected jDSRDocumentTree documentTree;
    
    
    /**
    * Contains box with the available codes
    */
    private JComboBox codeValueBox;
    
    
    
    /**
    * The identification of the Content Item  type.
    */
    protected int type;
    
    /**
    * The name of the context group 
    */
    private String contextGroupName;
    int nodeId;
    
    public static final int CONCEPT_NAME = 0;
    public static final int NUMERIC_CODE = 1;
    public static final int CODE = 2;
    
    int codeType = 0;
    /**
     * Constructor. Be aware that initContentItemGUI()
     * will be called for placing the returned JComponent
     * in the center of this panel
     * @param documentTree jDSRDocumentTree
     * @param nodeId Contains id of the node
     * @param type The identification of the Content Item  type.
     * @param contextGroupName The name of the context group 
    */
    public SRCodeChangePanel( jDSRDocumentTree documentTree, 
                                        int nodeId, 
                                        int type, 
                                        String contextGroupName,
                                        int codeType)
    {
        this.documentTree = documentTree;
        this.nodeId = nodeId;
        this.type = type;
        this.contextGroupName = contextGroupName;
        this.codeType = codeType;
        
        
        setLayout(new BorderLayout(5,5));
        add(getCodePanel(), BorderLayout.CENTER);
        
        updateCode();
        
        codeValueBox.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                changeCode();
            }
        });
        
    }
    /**
    * Change the code. The value in the codeValueBox will be
    * inserted in the jDSRDocumentTree.
    */
    private void changeCode()
    {
            isListenerEnabled= false;
            //codeValueBox.removeAllItems();
            //If the selected Index is "no value"
            if (!isLastValueValidSRCode()) 
            {
                int index = codeValueBox.getItemCount()-1;
                //If the selected Index is "no value"
                if (codeValueBox.getSelectedIndex() == index)
                {
                    isListenerEnabled= false;
                    return;
                }
                codeValueBox.removeItemAt(index);
            }
            
            
            documentTree.gotoNode(getNodeId());
            SRCode code = (SRCode)codeValueBox.getSelectedItem();
            if (code != null)   setCodeValue(code.getCodeValue(),
                                                code.getCodingSchemeDesignator(),
                                                code.getCodingSchemeVersion(),
                                                code.getCodeMeaning());
            
            isListenerEnabled= true;
        
    }
    /**
    * Returns the node id oft the Content Item. This
    * value will be used for changing the value in node of the
    * jDSRDocumentTree 
    * @return Returns the node id of the Content Item.
    */
    public int getNodeId()
    {
        return nodeId;
    }
    
    /**
    * Return the name of the Context Group.
    * @Return the name of the Context Group.
    */
    public String getContextGroupName()
    {
        return contextGroupName;
    }
    
    
    
    /**
    * Sets the name of the Context Group.
    * @param the name of the Context Group.
    */
    public void setContextGroupName(String contextGroupName)
    {
         this.contextGroupName = contextGroupName;
        changeCode();
    }
    
    private SRCode getCodeValue()
    {
        switch (codeType)
        {
            case NUMERIC_CODE:
                            jDSRNumericValue numValue = documentTree.getCurrentNumValue();
                            
                            if(     numValue != null&& 
                                    numValue.getMeasurementUnitCodeValue()!= null && 
                                    !numValue.getMeasurementUnitCodeValue().equals("")) 
                              return new SRCode("", numValue.getMeasurementUnitCodingSchemeDesignator(),
                                                       numValue.getMeasurementUnitCodingSchemeVersion(),
                                                       numValue.getMeasurementUnitCodeValue(),
                                                       numValue.getMeasurementUnitCodeMeaning());
                            else return null;   
                               
                              
            case CODE:
                       jDSRCodeValue codeValue = documentTree.getCurrentCodeValue();
                        
                        if( codeValue != null&& 
                            codeValue.getCodeValue()!= null && 
                            !codeValue.getCodeValue().equals("")) 
                       return new SRCode("", codeValue.getCodingSchemeDesignator(),
                                                       codeValue.getCodingSchemeVersion(),
                                                       codeValue.getCodeValue(),
                                                       codeValue.getCodeMeaning());
                      else return null;   
                               
                               
            default: 
                       jDSRCodeValue code = documentTree.getCurrentConceptName();
                        
                        if( code != null&& 
                            code.getCodeValue()!= null && 
                            !code.getCodeValue().equals("")) 
                       return new SRCode("", code.getCodingSchemeDesignator(),
                                                       code.getCodingSchemeVersion(),
                                                       code.getCodeValue(),
                                                       code.getCodeMeaning());
                      else return null;   
                                                       
                               
        }
    }
    private int  setCodeValue(String codeValue, 
                                String codingSchemeDesignator,
                                String codingSchemeVersion,
                                String codeMeaning)
    {
        switch (codeType)
        {
            case NUMERIC_CODE:
               jDSRNumericValue numValue = documentTree.getCurrentNumValue();
                return numValue.setMeasurementUnit(
                                codeValue,
                                codingSchemeDesignator,
                                codingSchemeVersion,
                                codeMeaning);
                               
                              
            case CODE:
                jDSRCodeValue code = documentTree.getCurrentCodeValue();
                return code.setCode( codeValue,
                                    codingSchemeDesignator,
                                    codingSchemeVersion,
                                    codeMeaning);
                         
            default:
                jDSRCodeValue conceptCode = documentTree.getCurrentConceptName();
                return conceptCode.setCode( codeValue,
                                    codingSchemeDesignator,
                                    codingSchemeVersion,
                                    codeMeaning);
                               
        }
       
    }
    
    
                
    
    /**
    * Updates the codeValueBox and the observationLabelthe srEditComponent with
    * values from the node
    * <p>
    * For updating the srEditComponet the update() 
    * method of this object will be called
    */
        public void updateCode()
    {
        //diable the listeners
        isListenerEnabled = false;
        
        
        documentTree.gotoNode(getNodeId());
        
        //Gets the current node
        SRCode codeValue = getCodeValue();
        
        if(codeValue != null)
        {
            //Gtes the index in the Context Group
            int index = SRCodeList.getIndexCode(MainContext.instance().codeList.getContextGroup(getContextGroupName()),  
                        codeValue.getIdentifier());
            
            //If not avilable in the Context Group
            //insert it in the Context Group of the Content Item
            if (index == -1) 
            {
               codeValue.setContextGroup(getContextGroupName()); 
                codeValue.setDefault(false);
                codeValueBox.addItem( codeValue);
                MainContext.instance().codeList.instertCode(codeValue);
                
                codeValueBox.setSelectedIndex(codeValueBox.getItemCount()-1);                                         
            }
            else codeValueBox.setSelectedIndex(index);
            
        
        }
        else
        {
            if (codeValueBox.getItemCount()==0)  codeValueBox.addItem(new String("no value"));
            else 
            {
                if (isLastValueValidSRCode()) 
                {
                    codeValueBox.addItem(new String("no value"));
                    codeValueBox.setSelectedItem("no value");
                }
                
            }
        }
        
        
        
        isListenerEnabled= true;
    }
    
    /**
    * Checks if last item in the codeValueBox is
    * not a valid SRCode. In this case the last 
    * value is a String value representing that
    * no code is choosen in the Content Item.
    * @return true if the last item is a SRCode, else false
    */
    private boolean isLastValueValidSRCode()
    {
         int index = codeValueBox.getItemCount()-1;
         
         if (index >= 0 && codeValueBox.getItemAt(index) instanceof String) return false;
         else return true;
    }
    
    /**
    * Opens a Dialog in which the user can inserted a new SRCode
    */
    private void insertCode()
    {
        isListenerEnabled = false;
        //SRCode c = (SRCode)codeValueBox.getSelectedItem();
        SRCodeEditDialog d = new SRCodeEditDialog(  this, 
                                                getContextGroupName()); 
        d.setVisible(true);
        if (!d.cancelAction)
        {
            
            int status= setCodeValue(d.getCodeValue(), d.getSchemeDesignator(), d.getSchemeVersion(), d.getCodeMeaning());
            if (status != 0) 
            {
                System.err.println("Error while setting code. Status: " + status);
                return ;
            }
            if (!isLastValueValidSRCode()) 
            {
                //I do'nt know why, but there will be an exception 
                //if i try to delete the last element of the codeValueBox
                //with removeItemAt
                if (codeValueBox.getItemCount()<= 1) codeValueBox.removeAllItems();
                else codeValueBox.removeItemAt(codeValueBox.getItemCount()-1);
            }
            SRCode cNew = new SRCode(getContextGroupName(), 
                                                       d.getSchemeDesignator(),
                                                       d.getSchemeVersion(),
                                                       d.getCodeValue(),
                                                       d.getCodeMeaning());
            cNew.setDefault(false);
            
            codeValueBox.addItem( cNew);
            codeValueBox.setSelectedItem(cNew);
            MainContext.instance().codeList.instertCode(cNew);
            
        }
        isListenerEnabled = true;
        
    }
    /**
    * Displays all Code Information 
    */
    private void showCodeInfo()
    {
        if (isLastValueValidSRCode())
        {
            SRCode c = (SRCode)codeValueBox.getSelectedItem();
            
            SRCodeEditDialog d = new SRCodeEditDialog(  this, 
                                                    false,
                                                    getContextGroupName(), 
                                                    c.getCodeValue(), 
                                                    c.getCodeMeaning(), 
                                                    c.getCodingSchemeDesignator(),
                                                    c.getCodingSchemeVersion());
            d.setVisible(true);
        }
    }
    
          
    /***
    * Creates and returns the GUI for the code handling
    * @return GUI for the code handling
    */
    private JPanel getCodePanel()
    {
        //Adds the  code 
        JPanel codePanel = new JPanel(new BorderLayout(5,5));
        
        if (codeType == CONCEPT_NAME)
        {
            codePanel.setBorder(new TitledBorder("Concept Name"));
        }
        //
        Vector v = (Vector)MainContext.instance().codeList.getContextGroup(getContextGroupName()); 
        if (v== null) v= new Vector();
        else v=(Vector)v.clone();
        
        //Be carful with the next two lines:
        //If you change the next two lines in 
        //codeValueBox = new JComboBox(v)
        //be aware that some methods of the JComobBox does
        //not work any more. 
        //{@link JComboBox.removeElementAt}
        codeValueBox = new JComboBox();
        for(int i = 0; i < v.size(); i++) codeValueBox.addItem(v.elementAt(i));
        
        codePanel.add(codeValueBox, BorderLayout.CENTER);
        
        
        JPanel buttonPanel = new JPanel();
        jToolkit.io.IconRetriever ir = new jToolkit.io.IconRetriever ();
	 
        JButton showCodeButton = new JButton(ir.getIcon(main.MainContext.iconPath+"showcode.gif"));
        showCodeButton.setMargin(new Insets(0,0,0,0));
        showCodeButton.setToolTipText("Show Code");
        showCodeButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               showCodeInfo();
            }
        });
        buttonPanel.add(showCodeButton);
        
        JButton insertCodeButton = new JButton(ir.getIcon(main.MainContext.iconPath+"insertcode.gif"));
        insertCodeButton.setMargin(new Insets(0,0,0,0));
        insertCodeButton.setToolTipText("Insert Code");
        insertCodeButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
               insertCode();
            }
        });
        buttonPanel.add(insertCodeButton);
        
        
        codePanel.add(buttonPanel, BorderLayout.EAST);
        return codePanel;
    }
}
/*
 *  CVS Log
 *  $Log: SRCodeChangePanel.java,v $
 *  Revision 1.1.1.1  2001/06/06 10:32:30  kleber
 *  Init commit for DICOMscope 3.5
 *  Create new CVS
 *
*/
