/*
 *
 *  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 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 the GUI vizualizing a Dicom Structured Report 
 * as an HTML document.
 * 
 * @author Klaus Kleber
 * @since 20.08.1999
 */
public class SREditTreePanel extends JPanel 
{
    /** 
    * The main tree containing all  data 
    */
    private JTree tree;
    
    
    /**
    * Tilted Boder containing the name of the SR Object
    */
    private TitledBorder titledBorder = new TitledBorder("Structured Report");
    
    /**
    * Current DVI Interface
    */
    private jDVInterface dvi;
    
    SRTreeModel srTreeModel;
    
    /**
     * Constructor
     * 
     * @param dvi jDVInterface
     */
    public SREditTreePanel( jDVInterface dvi,
                            String name ,
                            TreeSelectionListener srTreeSelectionListener
                            )
    {
        this.dvi = dvi;
        setLayout(new BorderLayout());
        srTreeModel= new SRTreeModel(new DefaultMutableTreeNode(new SRTreeElement(name,name)));
	    tree = new JTree (srTreeModel);
	    tree.setRootVisible(true);		
	    tree.setCellRenderer(new SREditTreeCellRenderer());
	    tree.setShowsRootHandles(true);		
	    tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION);
	    tree.putClientProperty("JTree.lineStyle", "Angled"); // Linien zwischen Knoten
		tree.addTreeSelectionListener(srTreeSelectionListener);		
        
        //Init MouseListener
        MouseListener ml = new MouseAdapter() // load Image on double-click!
        {
            public void mouseClicked(MouseEvent e) 
            {
                int selRow = tree.getRowForLocation(e.getX(), e.getY());
                if(selRow != -1&&selRow >1) 
                {
                    TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
                    int nodeId = ((SRTreeElement) ((DefaultMutableTreeNode)selPath.getLastPathComponent()).getUserObject()).srNodeId;
                    if(SwingUtilities.isRightMouseButton(e)) tree.setSelectionRow(selRow);
                    if(SwingUtilities.isRightMouseButton(e)) displayMenu(  selPath,selRow, e.getX(), e.getY(),nodeId);
                    
                }
            }
        };
        tree.addMouseListener(ml);        
          
        add("Center", new JScrollPane(tree));
        tree.expandRow (0);
        tree.setSelectionRow(1);
        
    }   
    /**
    *
    */
    public void displayMenu(    TreePath selPath,
                                int selRow, 
                                int x, 
                                int y,
                                int nodeId)
    {
        JPopupMenu popup = new JPopupMenu();
        if (selRow>2) popup.add(new DeleteAction());
        
        createMenu( selPath,popup,nodeId);
        
        popup.addSeparator();
        jDSRDocument sr = dvi.getCurrentReport();
        jDSRDocumentTree documentTree = sr.getTree();
        documentTree.gotoNode(nodeId);
        if (documentTree.isCurrentItemMarked())
            popup.add(new JMenuItem(new UnSignAction( selPath, nodeId)));
        else 
            popup.add(new JMenuItem(new SignAction( selPath, nodeId)));
        popup.show(tree, x,y);
        
    }
    public void createMenu( TreePath selPath,
                            JPopupMenu menu, 
                            int nodeId)
    {
        jDSRDocument sr = dvi.getCurrentReport();
        jDSRDocumentTree documentTree = sr.getTree();
        documentTree.gotoNode( nodeId);
            
            Hashtable modes = jDSRE_AddMode.names;
            for (Enumeration modeKeys = modes.keys() ; modeKeys.hasMoreElements() ;) 
            {
                int mode = ((Integer)modeKeys.nextElement()).intValue();
                JMenu modeMenu = null;
            
            
            
            Hashtable relations = jDSRE_RelationshipType.names;
            for (Enumeration relationKeys = relations.keys() ; relationKeys.hasMoreElements() ;) 
            {
                int relation = ((Integer)relationKeys.nextElement()).intValue();
                Hashtable types = jDSRE_ValueType.vtNames;
                JMenu relationMenu = null;
                for (Enumeration typeKeys = types.keys() ; typeKeys.hasMoreElements() ;) 
                {
                    int type = ((Integer)typeKeys.nextElement()).intValue();
                    if (documentTree.canAddContentItem(relation,type,mode))
                    {
                        if (modeMenu == null)
                        {
                            modeMenu = new JMenu(jDSRE_AddMode.getName(mode));
                            menu.add(modeMenu);
                        }
                        if (relationMenu == null)
                        {
                            relationMenu = new JMenu(jDSRE_RelationshipType.getName(relation));
                            modeMenu.add(relationMenu);
                        }
                        relationMenu.add(new JMenuItem(new InsertAction(selPath, 
                                                                        relation,
                                                                        type,
                                                                        mode))) ;  
                    }
                
                }
            }
            }

    }
    
    /**
    * Deletes the seleected row in the tree and in the
    * and the jDSRDocumentTree. The first two rows 
    * in the tree are not deletable. 
    * <p>
    * After deletion the row above the deletet row
    * will be selected.
    * @param srTree jDSRDocumentTree
    */
    public void deleteSelectedElement( jDSRDocumentTree srTree)
    {
        int row = tree.getMaxSelectionRow();
        if(row>=2)
        {
            DefaultMutableTreeNode node =
                (DefaultMutableTreeNode)tree.getSelectionPath().getLastPathComponent();
            
            srTreeModel.removeNodeFromParent(node);
                
            SRTreeElement srTreeElement =(SRTreeElement)node.getUserObject();
                srTree.gotoNode(srTreeElement.srNodeId);
                srTree.removeCurrentContentItem();
            int[] nextSelection = new int[1];
            nextSelection[0] = row-1;
            tree.setSelectionRows(nextSelection);
                
        }


    }
    public class SRTreeModel extends DefaultTreeModel
    {
        public SRTreeModel(DefaultMutableTreeNode root)
        {
                super(root);
                jDSRDocument sr = dvi.getCurrentReport();
                DefaultMutableTreeNode srDocument =new DefaultMutableTreeNode( new SRTreeElement("Header","Header"));
                root.add(srDocument);
                
                jDSRDocumentTree srTree = sr.getTree();
                int status; 
                status = srTree.gotoRootNode();
                if (status == 0) 
                {
                    System.err.println("Empty sr tree.");
                    return;
                }
                int valueType =srTree.getCurrentValueType();
                String valueTypeName = valueTypeName= jDSRE_ValueType.getVTName(srTree.getCurrentValueType());
                //System.err.println("Value type : " + valueType+ ", Name: " + valueTypeName);
                int signStatus = 0;
                if (srTree.isCurrentItemMarked()) signStatus = 1;
                DefaultMutableTreeNode srRoot =new DefaultMutableTreeNode( new SRTreeElement(   valueTypeName,
                                                                                                srTree.getCurrentNodeID(),
                                                                                                valueType,
                                                                                                signStatus));
                root.add(srRoot);
                createDefaultMutableTreeNodeFromSRTree(srRoot, srTree);
                
                
                
        }
        
    }
    /**
    * Creates and returns a DefaultMutableTreeNode from the current node in the 
    * specified jDSRDocumentTree. Returns NULL if the node in the jDSRDocumentTree
    * in invalid.
    * @param srTree The jDSRDocumentTree which refers to a node. 
    * @return DefaultMutableTreeNode from the current node in the 
    * specified jDSRDocumentTree. Returns NULL if the node in the jDSRDocumentTree
    * in invalid.
    */
    public DefaultMutableTreeNode createNode( jDSRDocumentTree srTree)
    {
            int valueType= srTree.getCurrentValueType();
            if (valueType == jDSRE_ValueType.VT_invalid)
            {
                System.err.println("Node " + srTree.getCurrentNodeID() + " is invaild");
                return null;
            }
            String valueTypeName = valueTypeName= jDSRE_ValueType.getVTName(srTree.getCurrentValueType());
            //System.err.println("Value type : " + valueType+ ", Name: " + valueTypeName);
            
            int signStatus = 0;
            if (srTree.isCurrentItemMarked()) signStatus = 1;
            return new DefaultMutableTreeNode( new SRTreeElement(   valueTypeName, 
                                                                    srTree.getCurrentNodeID(),
                                                                    jDSRE_RelationshipType.getTreeName( srTree.getCurrentRelationshipType()),
                                                                    valueType,signStatus)
                                                                   );
        
    }
    
    /**
    * Creates the DefaultMutableTreeNode of all childs of the  current node in the 
    * specified jDSRDocumentTree and a appends them in the specified root.
    * @param root The root in which all created DefaultMutableTreeNode will be inserted.
    * @param srTree The jDSRDocumentTree which refers to a node. 
    */
    public void createDefaultMutableTreeNodeFromSRTree(DefaultMutableTreeNode root, jDSRDocumentTree srTree )
    {
            
            //Gets the node of the first child
            int nodeId= srTree.gotoFirstChildNode();
            if ( nodeId == 0) return;
            
            
            DefaultMutableTreeNode currentRootNode =createNode(srTree);
            if (currentRootNode != null) 
            {
                root.add(currentRootNode);
                createDefaultMutableTreeNodeFromSRTree(currentRootNode, srTree);
            }
            srTree.gotoNode(nodeId);
            
            nodeId =srTree.gotoNextNode();
            
            while (nodeId != 0)
            {
               // System.err.println("nextNodeId: " + nodeId);
                currentRootNode =createNode(srTree);
                if (currentRootNode != null) 
                {
                    root.add(currentRootNode);
                    createDefaultMutableTreeNodeFromSRTree(currentRootNode, srTree);
                }
                srTree.gotoNode(nodeId);
                nodeId= srTree.gotoNextNode();   
            }
                //System.err.println("nodeId: " + nodeId);
        
    }
    public void gotoSRNode(int nodeId)
    {
        DefaultMutableTreeNode root = (DefaultMutableTreeNode)srTreeModel.getRoot();
        if (((SRTreeElement)root.getUserObject()).srNodeId == nodeId)
        {
                TreePath path = new TreePath(root);
                tree.setSelectionPath(path);
                tree.expandPath(path);
                tree.scrollPathToVisible(path);
            
        }
        else
        {
            for (Enumeration bf = root.breadthFirstEnumeration() ; bf.hasMoreElements() ;) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode)bf.nextElement();
                if (((SRTreeElement)node.getUserObject()).srNodeId == nodeId)
                {
                        TreePath path = new TreePath(node.getPath());
                        tree.expandPath(path);
                        tree.scrollPathToVisible(path);
                        tree.setSelectionPath(path);
                        return;
                    
                }
            }
        }


    }
    
    
    /**
    * CloseAction
    */
    public class DeleteAction extends AbstractAction
    {
        public DeleteAction()
        {
            super("Delete");
        }
        public void actionPerformed(ActionEvent e)
        {
                jDSRDocument sr = dvi.getCurrentReport();
                jDSRDocumentTree documentTree = sr.getTree();
                deleteSelectedElement(documentTree);
        }
    }
    /**
    * CloseAction
    */
    public class SignAction extends AbstractAction
    {
        TreePath selTree;
        int nodeId;
        public SignAction(TreePath selTree, int nodeId)
        {
            super("Sign");
            this.nodeId= nodeId;
            this.selTree = selTree;
            
        }
        public void actionPerformed(ActionEvent e)
        {
                jDSRDocument sr = dvi.getCurrentReport();
                jDSRDocumentTree documentTree = sr.getTree();
                documentTree.gotoNode(nodeId);
                documentTree.setCurrentItemMark(true);
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)selTree.getLastPathComponent();
                SRTreeElement treeElement =(SRTreeElement) selectedNode.getUserObject();
                
                treeElement.setSignStatus(1);
                tree.repaint();
                
        }
    }
    /**
    * CloseAction
    */
    public class UnSignAction extends AbstractAction
    {
        TreePath selTree;
        int nodeId;
        public UnSignAction(TreePath selTree, int nodeId)
        {
            super("UnSign");
            this.nodeId= nodeId;
            this.selTree = selTree;
            
        }
        public void actionPerformed(ActionEvent e)
        {
                jDSRDocument sr = dvi.getCurrentReport();
                jDSRDocumentTree documentTree = sr.getTree();
                documentTree.gotoNode(nodeId);
                documentTree.setCurrentItemMark(false);
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)selTree.getLastPathComponent();
                SRTreeElement treeElement =(SRTreeElement) selectedNode.getUserObject();
                
                treeElement.setSignStatus(0);
                tree.repaint();
                
        }
    }
    /**
    * CloseAction
    */
    public class InsertAction extends AbstractAction
    {
        int relation;
        int valueType;
        int mode;
        TreePath selPath;
        
        public InsertAction(TreePath selPath,
                            int relation, 
                            int valueType, 
                            int mode)
        {
            super(jDSRE_ValueType.getVTName(valueType));
            this.mode = mode;
            this.relation = relation;
            this.valueType= valueType;
            this.selPath = selPath;
            
            
        }
        public void actionPerformed(ActionEvent e)
        {
            jDSRDocument sr = dvi.getCurrentReport();
            jDSRDocumentTree documentTree = sr.getTree();
            int nodeId = documentTree.addContentItem(relation, valueType, mode);
            if (nodeId >=1)
            {
            
                int signStatus = 0;
                if (documentTree.isCurrentItemMarked()) signStatus = 1;
                SRTreeElement te = new SRTreeElement(jDSRE_ValueType.getVTName(valueType),
                                                     nodeId,
                                                     jDSRE_RelationshipType.getTreeName( relation),
                                                     valueType,
                                                     signStatus);
                  DefaultMutableTreeNode node = new  DefaultMutableTreeNode  (te);                                
                  DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)selPath.getLastPathComponent();
                  if (mode ==   jDSRE_AddMode.AM_afterCurrent)
                  {
                    srTreeModel.insertNodeInto( node,(DefaultMutableTreeNode)selectedNode.getParent(),selectedNode.getParent().getIndex(selectedNode)+1);
                    
                    //tree.setSelectionRow(tree.getMaxSelectionRow()+1);
                  }
                  else if (mode == jDSRE_AddMode.AM_beforeCurrent)
                  {
                    srTreeModel.insertNodeInto( node,(DefaultMutableTreeNode)selectedNode.getParent(),selectedNode.getParent().getIndex(selectedNode));
                    //tree.setSelectionRow(tree.getMaxSelectionRow()-1);
                  }
                  else if (mode == jDSRE_AddMode.AM_belowCurrent)
                  {
                    srTreeModel.insertNodeInto( node,selectedNode,0);
                    //tree.expandRow(tree.getMaxSelectionRow());
                    //tree.setSelectionRow(tree.getMaxSelectionRow()+1);


                  }
                   gotoSRNode(nodeId);
                }

                //tree.repaint();
        }
    }

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