/*
 * DirectoryConfigurationForm.java
 *
 * Copyright 2011 John W Dawson
 *
 * This code is distributed under the terms of the GNU General Public License, version 3
 *
 * This class implements the form used to enter the configuration data for connecting
 * to the LDAP server
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class DirectoryConfigurationForm extends AddressBookConfigurationForm
{
  
  private JTextField hostName;
  private JTextField portNumber;
  private JCheckBox ssl;
  private JComboBox authenticationSelector;
  private JTextField bindDN;
  private JPasswordField password;
  private JTextField baseDN;
  private JTextField query;
  private JTextField keepAliveInterval;
  private JTextField homeField;
  private JTextField workField;
  private JTextField mobileField;
  private JTextField otherField;
  private LdapConnection connection;
  
  private void setAuthentication (JComboBox authenticationSelector, String [] authenticationTypes)
  {
    // Get current value from configuration
    String authentication = configurationRecord.getElementValue ("ldapsecurityauthentication");
    if (authentication != null)
    {
      // Check if in list
      for (String value : authenticationTypes)
      {
        if (authentication.equals (value))
        {
          authenticationSelector.setSelectedItem (value);
          return;
        }
        // If not in list add to list and select
        authenticationSelector.addItem (authentication);
        authenticationSelector.setSelectedItem (authentication);
      }
    }
  }    
    
  public DirectoryConfigurationForm (AddressBookConfiguration configuration, LdapConnection connection, JFrame mainWindow) 
  {
    super ("Configure Directory", configuration, configuration, mainWindow);
    this.connection = connection;
  }
  
  protected void defineFields ()
  {    
    
    // Add fields for server name and port
    hostName = addTextField ("Host Name:", "ldapserver");
    portNumber = addTextField ("Port Number:", "ldapport");
    
    // Add check box for SSL connection
    ssl = new JCheckBox ("Use SSL");
    String security = configurationRecord.getElementValue ("ldapsecurityprotocol");
    if (security != null)
    {
      ssl.setSelected (security.equals ("ssl"));
    }
    ssl.addActionListener (this);
    addField ("", ssl);
    
    // Add selector for authentication type
    String [] authenticationTypes = {"simple", "Digest-MD5", "none"};
    authenticationSelector = new JComboBox (authenticationTypes);
    authenticationSelector.setEditable (true);
    setAuthentication (authenticationSelector, authenticationTypes);
    addField ("Authentication:", authenticationSelector);
    
    // Add fields for bind DN, password, base DN, query string and keep alive interval
    bindDN = addTextField ("Bind DN:", "ldapsecurityprincipal");
    password = addPasswordField ("Password:", "ldapsecuritycredentials");
    baseDN = addTextField ("Base DN:", "ldapbasedn");
    query = addTextField ("Query:", "ldapfilter");
    keepAliveInterval = addTextField ("Keep Alive Interval:", "ldapkeepaliveinterval");
    
  }
  
 
  protected void otherAction (AbstractButton source)
  {
    // Check which button was clicked
    if (source.getText().equals ("Use SSL"))
    {
      if (source.isSelected ())
      {
        // If SSL selected change default port 389 to 636
        if (portNumber.getText().equals ("389"))
        {
          portNumber.setText("636");
        }
      }
      else if (portNumber.getText().equals ("636"))
      {
        portNumber.setText("389");
      }
    }
  }
  
  protected boolean validateAndSave ()   
  {
    // Check that all required fields are filled in
    if (!checkFieldEntry (hostName, "Please enter the host name"))
    {
      return false;
    }
    if (!checkFieldEntry (portNumber, "Please enter the port number"))
    {
      return false;
    }

    String authenticationType = authenticationSelector.getSelectedItem().toString();
    if (!authenticationType.equals("none"))
    {
      // Bind DN (username) and password are required unless no authentication specified
      if (!checkFieldEntry (bindDN, "Please enter the bind name for authentication"))
      {
        return false;
      }
      if (!checkFieldEntry (password, "Please enter the password"))
      {
        return false;
      }
    }
                 
    if (!checkFieldEntry (baseDN, "Please enter the base DN for the directory search"))
    {
      return false;
    }
    if (!checkFieldEntry (query, "Please enter the LDAP query string"))
    {
      return false;
    }
    
    // Update the configuration with the entered values
    configurationRecord.addOrReplaceElement ("ldapserver", hostName.getText ());
    configurationRecord.addOrReplaceElement ("ldapport", portNumber.getText ());
    configurationRecord.addOrReplaceElement ("ldapsecurityprotocol", ssl.isSelected() ? "ssl" : "none");
    configurationRecord.addOrReplaceElement ("ldapsecurityauthentication", authenticationType);
    if (!authenticationType.equals("none"))
    {                                     
      configurationRecord.addOrReplaceElement ("ldapsecurityprincipal", bindDN.getText ());
      configurationRecord.addOrReplaceEncryptedElement ("ldapsecuritycredentials", new String (password.getPassword ()));
    }
    configurationRecord.addOrReplaceElement ("ldapbasedn", baseDN.getText ());
    configurationRecord.addOrReplaceElement ("ldapfilter", query.getText ());
    configurationRecord.addOrReplaceElement ("ldapkeepaliveinterval", keepAliveInterval.getText ());
    
    // Attemp to connect to server
    return connection.connect ();
        
  }
        
}    