/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Darren Marvin
//      Created date:           2003/08/19
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.gemss.utils.signalhandlers;

import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import eu.gemss.signals.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;

import eu.gemss.signals.security.CredentialRequest;

/**
 * Sample Signal handler for CredentialRequest signals
 */
public class CredentialRequestGUIHandler extends JPanel implements SignalHandler {

    private static final String mTitleString = "GEMSS Security Context: Keystore Security Token Provider";
    private CommandAction mSubmitAction;
    private JButton mSubmitButton;
    private JPasswordField mKeystorePassField;
    private JTextField mPrivateKeyAliasField;
    private JPasswordField mPrivateKeyPassField;
    private CredentialRequest mCredentialRequest;

    private static final String KEYSTORE_PASSPHRASE_LABEL = "Keystore Passphrase:";
    private static final String PRIVATE_KEY_ALIAS_LABEL = "Private Key Alias:";
    private static final String PRIVATE_KEY_PASSPHRASE_LABEL = "Private Key Passphrase:";
    private static final String KEYSTORE_PATH_DEFAULT_STRING = "Path to keystore, please use separator '/' rather than '\'";

    private JFrame mFrame;
    private boolean mFirstTime = true;

    public CredentialRequestGUIHandler() {

    }

    /**
     * Retrieve the title string for the gui window
     * @return title
     */
    public String getTitleString() {
        return mTitleString;
    }

    /**
     * Process the signal supplied by the Component Framework
     * @param signal signal to process
     */
    public void process(Signal signal) {
        //set this as visible
        if(signal instanceof eu.gemss.signals.security.CredentialRequest) {
            mCredentialRequest = (eu.gemss.signals.security.CredentialRequest) signal;
            if(mFirstTime) {
                initPane();
                initialiseWindow();
                mFirstTime = false;
            }
			mFrame.toFront();
            mFrame.setVisible(true);
        }
        //else ignore

    }

    private void initPane() {

        setBorder(new TitledBorder(new EtchedBorder(), mTitleString));
        setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        int x = 0;
        int y = 0;
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.weightx = 0.0;
        constraints.weighty = 0.0;
        constraints.anchor = GridBagConstraints.WEST;
        constraints.fill = GridBagConstraints.VERTICAL;

        constraints.gridy = 0;
        constraints.gridx = 0;
        JLabel keystorePassLabel = new JLabel(this.KEYSTORE_PASSPHRASE_LABEL);
        add(keystorePassLabel,constraints);
        constraints.gridx = 1;
        this.mKeystorePassField = new JPasswordField(15);
        add(this.mKeystorePassField,constraints);
        constraints.gridy = 1;
        constraints.gridx = 0;
        JLabel privateKeyAliasLabel = new JLabel(this.PRIVATE_KEY_ALIAS_LABEL);
        add(privateKeyAliasLabel,constraints);
        constraints.gridx = 1;
        this.mPrivateKeyAliasField = new JTextField(15);
        add(this.mPrivateKeyAliasField,constraints);
        constraints.gridy = 2;
        constraints.gridx = 0;
        JLabel privateKeyPassLabel = new JLabel(this.PRIVATE_KEY_PASSPHRASE_LABEL);
        add(privateKeyPassLabel,constraints);
        constraints.gridx = 1;
        this.mPrivateKeyPassField = new JPasswordField(15);
        add(this.mPrivateKeyPassField,constraints);
        constraints.gridy = 3;
        constraints.gridx = 0;
        mSubmitButton = new JButton("OK");
        mSubmitButton.addActionListener(mSubmitAction = new CommandAction("Submit"));
        add(mSubmitButton,constraints);

    }

    private class CommandAction extends AbstractAction {
        public CommandAction(String name) {
            super(name);
        }

         public void actionPerformed(ActionEvent e) {
            String name = (String) getValue(NAME);

            if (name.equals(mSubmitAction.getValue(NAME))) {
                //retrieve the textfield values and set the appropriate
                //credential request values
                //validate inputs
                char[] keyStorePassChars = mKeystorePassField.getPassword();
                char[] privateKeyPassChars = mPrivateKeyPassField.getPassword();
                String keystorePass = null;
                if(keyStorePassChars!=null && keyStorePassChars.length>0)
                     keystorePass = new String(keyStorePassChars).trim();
                String privateKeyAlias = mPrivateKeyAliasField.getText().trim();
                String privateKeyPass = null;
                if(privateKeyPassChars!=null && privateKeyPassChars.length>0)
                    privateKeyPass = new String(privateKeyPassChars).trim();
                if(keystorePass!=null && !keystorePass.equals("") &&
                   privateKeyAlias!=null && !privateKeyAlias.equals("") &&
                   privateKeyPass!=null && !privateKeyPass.equals("")) {
                       //set values
                       mCredentialRequest.setKeystorePassword(keystorePass);
                       mCredentialRequest.setPrivateKeyAlias(privateKeyAlias);
                       mCredentialRequest.setPrivateKeyPassword(privateKeyPass);
                       //clear the password
                       for(int i=0;i<keyStorePassChars.length;i++) {
                           keyStorePassChars[i] = '0';
                       }
                       for(int i=0;i<privateKeyPassChars.length;i++) {
                           privateKeyPassChars[i] = '0';
                       }
                       mFrame.setVisible(false);
                   }
            }
         }
    }

    private void initialiseWindow() {
        initFrames();
    }

    private void initFrames() {
        mFrame = new JFrame() {
                    protected void processWindowEvent(WindowEvent e) {
                        super.processWindowEvent(e);
                        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
                            System.exit(0);
                        }
                    }

                    public synchronized void setTitle() {
                        super.setTitle(mTitleString);
                        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
                    }
                };
        mFrame.getContentPane().add(this, BorderLayout.CENTER);

        mFrame.setSize(400, 200);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

        mFrame.setLocation((d.width - mFrame.getSize().width) / 2, (d.height - mFrame.getSize().height) / 2);

        mFrame.setVisible(true);
    }
}
