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

import main.*;
import J2Ci.*;
/**
 * This class contains the GUI the verification of a
 * a Dicom Structured Report
 * @author Klaus Kleber
 * @since 11.11.200
 */
  public class VerificationDialog extends JDialog
  {
        boolean holdVerifyingObserver = true;
        boolean holdPreDocuments = true;


        /**
        * Current DVI Interface
        */
        private jDVInterface dvi;

        /**
        * Parent
        */
        private  MainImageViewerPanel mainView;

        /**
        * Table for seleting an user
        */
        private JTable table;

        /**
        *Model for the Tabel
        */
        private TableData tableData; // die Tabellendaten

        /**
        * If true at least one user has verified the document
        */
        private boolean verified = false;

        private boolean sortUp = false;
        /**
        * column identifies
        */
        private static Vector  columnIdentifiers;


        private JRadioButton verifyRadioButton = new JRadioButton("Verify",true);
        private JRadioButton signContentRadioButton = new JRadioButton("Verify and Sign");
        private JRadioButton signAllRadioButton = new JRadioButton("Verify and Sign (finalize)");

        private boolean isRevised = false;
        static
        {
            columnIdentifiers = new Vector();
            columnIdentifiers.add("Login");
            columnIdentifiers.add("Name");
            columnIdentifiers.add("Organization");
            columnIdentifiers.add("Code Value");
            columnIdentifiers.add("Code Meaning");
            columnIdentifiers.add("Coding Scheme Designator");
            columnIdentifiers.add("Coding Scheme Version");
            columnIdentifiers.add("DICOM Name");
            columnIdentifiers.add("Id");
        }

        /**
        * Constructor
        * @param dvi Current jDVInterface.
        * @param mainView Parent component.
        */
        public VerificationDialog(jDVInterface dvi, MainImageViewerPanel mainView,boolean isRevised)
        {
            super(mainView.parent, "Verify Document", true);
            this.dvi = dvi;
            this.mainView = mainView;
            this.isRevised = isRevised;

            getContentPane().setLayout(new BorderLayout(5,5));
            setLocationRelativeTo(mainView.parent);

            //Verify Button
            JButton okButton = new JButton("Verify");
            okButton.setToolTipText ("Verification");
            okButton.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {

                    verify();

                }
            });


            //Close
            JButton closeButton = new JButton("Close");
            closeButton.setToolTipText ("Close");
            closeButton.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    setVisible(false);
                    dispose();
                }
            });
            JPanel centerPanel = new JPanel(new BorderLayout(5,5));



        //init model
        tableData = new TableData( getUserData(),columnIdentifiers); // Konstruktion der zufälligen Tabellendaten

        // init table
        table = new JTable(tableData); // Konstruktion der sichtbaren Tabelle
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("Login"));
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("Code Value"));
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("Code Meaning"));
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("Coding Scheme Designator"));
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("Coding Scheme Version"));
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("Id"));
        table.getTableHeader().getColumnModel().removeColumn(table.getColumn("DICOM Name"));
    table.setAutoResizeMode (table.AUTO_RESIZE_LAST_COLUMN);
    table.setAutoCreateColumnsFromModel (false);


    //table.getColumnModel ().getColumn (0).setPreferredWidth (150);
    table.getColumnModel ().getColumn (0).setPreferredWidth (200);
    table.getColumnModel ().getColumn (1).setPreferredWidth (300);
    //table.getColumnModel ().getColumn (3).setPreferredWidth (100);
    //table.getColumnModel ().getColumn (4).setPreferredWidth (100);
    //table.getColumnModel ().getColumn (5).setPreferredWidth (100);
    //table.getColumnModel ().getColumn (6).setPreferredWidth (50);


        // init selection
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // immer nur eine Zeile auswählbar
        table.addMouseListener(new VerifyMouseAdapter());

        // init Mouse Listener
        table.getTableHeader().addMouseListener(new TableMouseListener()); // Mausaktion im Header abfangen

        centerPanel.add(new JScrollPane(table), BorderLayout.CENTER);

            JPanel typePanel = new JPanel();
            typePanel.setLayout(new FlowLayout(FlowLayout.CENTER));
            typePanel.setBorder(new EtchedBorder());
            ButtonGroup bg = new ButtonGroup();
            bg.add(verifyRadioButton);
            bg.add(signContentRadioButton);
            bg.add(signAllRadioButton);

            JPanel gridPanel = new JPanel (new GridLayout(3,1));
            gridPanel.add(verifyRadioButton);
            gridPanel.add(signContentRadioButton);
            gridPanel.add(signAllRadioButton);
            typePanel.add(gridPanel, BorderLayout.CENTER);
            centerPanel.add(typePanel, BorderLayout.SOUTH);



            getContentPane().add(centerPanel, BorderLayout.CENTER);

            JPanel bPanel = new JPanel();
            bPanel.add(okButton);
            bPanel.add(closeButton);

            getContentPane().add(bPanel, BorderLayout.SOUTH);

            setSize(450,300);
        }
    /**
    * This class extends the DefaultTableModel do that the needed
    * columnIdentifiers
    *
    */
    private class TableData extends DefaultTableModel
    {

        int[][] sortMatrix = {
            { 0, 0, 0, 0, 0,0,0,0,0 }  /* second column: second sort criterion */
        };

        /**
        * Checks if row1< row2. The type of comparison is defined by cols.
        * @return 0 if equals, -1 if row1 < row2, 1 if row1>row2.
        */
        public int compareTo(int col, int row1, int row2)
        {
            int secondCriterion=sortMatrix[0][col];

            int result = ((Comparable)tableData.getValueAt(row1, col)).compareTo((tableData.getValueAt(row2, col)));
            if (result == 0) result = ((Comparable)tableData.getValueAt(row1, secondCriterion)).compareTo((tableData.getValueAt(row2, secondCriterion)));
            return result;
        }

        /**
        * Constructor. Sets the colum identifiers.
        * @param columnIdentifiers column identifiers
        */
        public TableData(Vector dataValues,Vector columnIdentifiers)
        {
            super(dataValues, columnIdentifiers);
        }

        /**
        * Sets an editable
        */
        public boolean isCellEditable(int row, int cols)
        {
            return false;
        }

        /**
        * Returns the index of the invislibe cols
        */
        public int[] getInvisibleColumns()
        {

            //Number of cols in the model
            int cols = getColumnCount(); // Anzahl der Spalten merken

            //init array with size of invisible cols
            //( cols of the modle - cols of the table
            int[] invisible = new int[cols - table.getColumnCount()];

            //Fills array
            for(int i = 0, j = 0; i < cols; i++) //
            {
                if(table.convertColumnIndexToView(i) < 0)
                {
                    invisible[j++] = i;
                }
            }
            return invisible;
        }

        public void setRowCount(int index)
        {
            super.setRowCount(index);
        }

        /**
        * Swaps the rows.
        * @param row1 First row
        * @param row2 Secound row
        */
        public void swapRows(int row1, int row2)
        {
            Vector dummy = (Vector)dataVector.elementAt(row1);
            dataVector.setElementAt(dataVector.elementAt(row2), row1);
            dataVector.setElementAt(dummy, row2);
        }
    }



      /**
      * Gets the User Data form the interface
      */
      private Vector getUserData()
      {
            //jDSRDocument sr = dvi.getCurrentReport();
            int numberOfUsers = dvi.getNumberOfUsers();
            Vector list = new Vector();
            for (int i = 0; i< numberOfUsers; i++)
            {
                //Load ID
                String id = dvi.getUserID(i);

                //Init User Data
                Vector  user = new Vector();
                user.add(dvi.getUserLogin(id));
                user.add(dvi.getUserName(id));
                user.add(dvi.getUserOrganization(id));
                user.add(dvi.getUserCodeValue(id));
                user.add(dvi.getUserCodeMeaning(id));
                user.add(dvi.getUserCodingSchemeDesignator(id));
                user.add(dvi.getUserCodingSchemeVersion(id));
                user.add(dvi.getUserDICOMName(id));

                user.add(id);

                list.add(user);

            }
            return list;

      }

       public void verify()
       {
            int index = table.getSelectedRow();
            if (index == -1)    JOptionPane.showMessageDialog (   this,
                                                                "Please select User",
                                        "ERROR",
                                                            JOptionPane.ERROR_MESSAGE);
        else
        {
            String pwd = login((String)tableData.getValueAt(index, tableData. getColumnCount()-1),(String)tableData.getValueAt(index, 0));
            if (pwd!=null)
            {

                jDSRDocument sr = dvi.getCurrentReport();
                String name = (String)tableData.getValueAt(index,7);
                if (name == null) name = "";

                String organisation = (String)tableData.getValueAt(index,2);
                if (organisation == null) organisation = "";

                String codeValue = (String)tableData.getValueAt(index,3);
                if (codeValue == null) codeValue = "";

                String codeMeaning = (String)tableData.getValueAt(index,4);
                if (codeMeaning == null) codeMeaning = "";

                String codingSchemeDesignator = (String)tableData.getValueAt(index,5);
                if (codingSchemeDesignator == null) codingSchemeDesignator = "";

                String codingSchemeVersion = (String)tableData.getValueAt(index,6);
                if (codingSchemeVersion == null) codingSchemeVersion = "";
                int status=0;
        //verifyRadioButton
        //signContentRadioButton
        //signAllRadioButton
                /*status = sr.verifyDocument(name,
                                        codeValue,
                                        codingSchemeDesignator,
                                        codingSchemeVersion,
                                        codeMeaning,
                                        organisation);
                                        */
                 int mode = 0;;
                 if (verifyRadioButton.isSelected())mode = jDVPSVerifyAndSignMode.DVPSY_verify;
                 else if (signContentRadioButton.isSelected())mode = jDVPSVerifyAndSignMode.DVPSY_verifyAndSign;
                 else if (signAllRadioButton.isSelected())mode = jDVPSVerifyAndSignMode.DVPSY_verifyAndSign_finalize;
                 System.err.println("isFinalized (before): " + sr.isFinalized());
                 if (sr.isFinalized())
                 {
                    int result = JOptionPane.showConfirmDialog (this,"This operation destroys all current digital signatures. \n Do you really want this?", "Warning",
                    JOptionPane.OK_CANCEL_OPTION,
                    JOptionPane.WARNING_MESSAGE);
                    if (result != JOptionPane.OK_OPTION)return;
                 }

                 if (!isRevised)
                 {
                    sr.createNewSOPInstance();
                    sr.setSpecificCharacterSetType(jDSRE_CharacterSet.CS_Latin1);
                 }
                 //System.err.println("UID: " +sr.getSOPInstanceUID());

                 status = dvi.verifyAndSignStructuredReport((String)tableData.getValueAt(index, tableData. getColumnCount()-1),
                                                            pwd,
                                                            mode);
                 // NB: a new sr object has been created internally
                 sr = dvi.getCurrentReport();
                 System.err.println("isFinalized (after): " + sr.isFinalized());
                 
                 Controller.instance().fireStatus(new SignedStatusEvent(this,
                            SignedStatusEvent.LOADSR,
                            dvi.getCombinedImagePStateSignatureStatus(),
                            dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport)));
                 System.err.println("signed: " + dvi.getCurrentSignatureStatus(jDVPSObjectType.DVPSS_structuredReport));

                 if (status != 0)
                    System.err.println("Can't verify document. Status:  " +status);
                 else
                 {                   
                    verified = true;
                    setVisible(false);
                    dispose();
                 }
            }
        }

       }


    /**
    * This class listens for the selelction of rows and set the
    * text of the specified row (which presents a DicomScopeMessage)
    * to a TextField
    */
    private  class VerifyMouseAdapter extends MouseAdapter
    {

        public void mouseClicked(MouseEvent e)
        {
            if (e.getClickCount()== 2)
            {
                verify();
            }
        }

   }



       /**
       * Opens a password dialog and verifies the given password for the given user ID.
       * Returns true if the user was verified. This function returns false only if the user has
       * select the cancel button
       */
       public String login(String login, String name)
       {
        String pwd;

            while (true)
            {
            JPanel p = new JPanel (new BorderLayout ());

            JPanel westPanel = new JPanel (new GridLayout (2, 1));
            JPanel centerPanel = new JPanel (new GridLayout (2, 1));

            westPanel.add (new JLabel("Login: "));
            westPanel.add (new JLabel("Password: "));

            JLabel loginTxt = new JLabel(name);
            JPasswordField pw = new JPasswordField ();

            centerPanel.add (loginTxt);
            centerPanel.add (pw);

            p.add ("West", westPanel);
            p.add ("Center", centerPanel);

            int res = JOptionPane.showConfirmDialog (this,
                             p,
                             "Login",
                             JOptionPane.OK_CANCEL_OPTION,
                             JOptionPane.PLAIN_MESSAGE);

            if (res ==  JOptionPane.CANCEL_OPTION) return null;


           // if (( pw == null) || (pw.getPassword ().length ==0))
           // JOptionPane.showMessageDialog (this, "Please type your password");
           // else
            {
            pwd =new String(pw.getPassword());
            if (!dvi.verifyUserPassword(login, pwd))JOptionPane.showMessageDialog (this, "Wrong Password");
            else return pwd;
        }
        }

       }
       public boolean isVerified()
       {
            return verified;
       }
    /**
    * Testet auf Klicks in den Tabellenheader
    */
    private class TableMouseListener extends MouseAdapter

    {
        public void mouseClicked(MouseEvent e)
        {

            if(SwingUtilities.isRightMouseButton(e)) // nur mit der rechten Maustaste zulassen
            {
                TableColumnModel tcm = table.getTableHeader().getColumnModel(); // schon mal das Spaltenmodell holen
                int index = tcm.getColumnIndexAtX(e.getX()); // Index der angeklickten Spalte ermitteln

                if(index >= 0) // wurde tatsächlich eine Spalte angeklickt...
                {
                    int modelIndex =  table.convertColumnIndexToModel(index); // ...hole Spaltenindex des Modells

                    sort(modelIndex);
                }
            }
        }
    }
    /**
    * Sort the table.
    * @param index Specifies the colum to be sorted
    */
    private void sort (int index)
    {
            if (sortUp)
            {// Bubblesort
                for(int i = 0; i < tableData.getRowCount(); i++)
                {
                    for(int j = i + 1; j < tableData.getRowCount(); j++)
                    {
                        if (tableData.compareTo(index, i, j) > 0)
                        {
                            tableData.swapRows(i, j);
                        }
                    }
                }
                sortUp = false;
            }
             else
             {
                for(int i = 0; i < tableData.getRowCount(); i++)
                {
                    for(int j = i + 1; j < tableData.getRowCount(); j++)
                    {
                        if (tableData.compareTo(index, i, j) < 0)
                        {
                            tableData.swapRows(i, j);
                        }
                    }
                }
                sortUp = true;

             }
            repaint(); // Tabelle neuzeichnen

    }

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