/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * END COPYRIGHT BLOCK **/
package com.netscape.management.admserv.panel;

import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import com.netscape.management.client.util.*;
import com.netscape.management.client.console.ConsoleInfo;
import com.netscape.management.admserv.config.*;
import com.netscape.management.nmclf.SuiConstants;
/**
  *
  * @version 0.1 11/23/97
  * @author miodrag@netscape.com
  */
public class UGDirectoryConfigPanel extends PluginConfigPanel implements SuiConstants {

    IConfigDataModel _configData;

    static ResourceSet _resource;
    static String _i18nLdapURL, _i18nUseGlobal, _i18nOverrideGlobal;
    static String _i18nBindDN, _i18nBindPW;
    static String _i18nEnterBindDN, _i18nEnterBindPW;
    static String _i18nHost, _i18nHostUsage, _i18nPort, _i18nUseSSL,
    _i18nBaseDN, _i18nUGGroupbox;
    static String _i18nEnterLdapHost,
    /*_i18nEnterLdapPort,*/ _i18nEnterBaseDN, _i18nPortRange;
    static String _i18nWarnCert;

    static {
        _resource = new ResourceSet("com.netscape.management.admserv.panel.panel");
        _i18nLdapURL = _resource.getString("ldapds","LdapURL");
        _i18nBindDN = _resource.getString("ldapds","BindDN");
        _i18nBindPW = _resource.getString("ldapds","BindPW");
        _i18nUseGlobal = _resource.getString("ldapds","UseGlobal");
        _i18nOverrideGlobal = _resource.getString("ldapds","OverrideGlobal");
        _i18nEnterBindDN = _resource.getString("ldapds","EnterBindDN");
        _i18nEnterBindPW = _resource.getString("ldapds","EnterBindPW");
        _i18nHost = _resource.getString("ldapds","UGHost");
        _i18nHostUsage = _resource.getString("ldapds","UGHostUsage");
        _i18nPort = _resource.getString("ldapds","Port");
        _i18nUseSSL = _resource.getString("ldapds","UseSSL");
        _i18nBaseDN = _resource.getString("ldapds","BaseDN");
        _i18nUGGroupbox = _resource.getString("ldapds","UGGroupbox");
        _i18nEnterLdapHost = _resource.getString("ldapds","EnterHostPortList");
        //_i18nEnterLdapPort=_resource.getString("ldapds","EnterLdapPort");
        _i18nEnterBaseDN = _resource.getString("ldapds","EnterBaseDN");
        _i18nPortRange = _resource.getString("common","PortRange");
        _i18nWarnCert = _resource.getString("ldapds","WarnCert");
    }

    Help _help;

    JLabel _lblGlobalLdapURL, _lblGlobalLdapURLValue;
    JLabel _lblBindDN, _lblBindPW1;
    JRadioButton _rbUseGlobal, _rbOverrideGlobal;
    JTextField _txtBindDN;
    SingleBytePasswordField _txtBindPW1;
    JLabel _lblHost, _lblHostUsage, _lblBaseDN;

    JTextField _txtBaseDN;
    SingleByteTextField _txtHost;
    JCheckBox _cbSSL;

    public UGDirectoryConfigPanel(String title, IConfigDataModel data) {
        super(title);
        _configData = (IConfigDataModel) data;

        setLayout(new BorderLayout());
        add(makeConfigPanel(), BorderLayout.NORTH);
        _help = new Help(_resource);
    }

    public void showHelp() {
        _help.contextHelp("ugLdapHelp");
    }

    public IConfigDataModel getDataModel() {
        return _configData;
    }

    public void setDataModel(IConfigDataModel data) {
        _configData = (IConfigDataModel) data;
        if (_configData.isLoaded()) {
            setPanelContent(_configData);
        }
    }

    public void initialize() throws RemoteRequestException {
        if (!_configData.isLoaded())
            _configData.load();
        _rbUseGlobal.addItemListener(_rbListener);
        _rbOverrideGlobal.addItemListener(_rbListener);
        _cbSSL.addActionListener(_cbSSLListener);
        setPanelContent(_configData);
    }

    public void resetContent() {
        setPanelContent(_configData);
    }

    public void applyChanges() throws ConfigPanelException {
        getPanelContent(_configData);
    }

    public void registerEditComponents(EditMonitor editMonitor) {
        //editMonitor.monitor(_txtPort);
        editMonitor.monitor(_txtHost);
        editMonitor.monitor(_cbSSL);
        editMonitor.monitor(_txtBindDN);
        editMonitor.monitor(_txtBindPW1);
        editMonitor.monitor(_rbUseGlobal);
        editMonitor.monitor(_rbOverrideGlobal);
    }

    public void setPanelContent(IConfigDataModel data) {

        String inforef =
                (String) data.getAttribute(AttrNames.UGDSCONFIG_INFOREF);

        Debug.println("inforef="+inforef);
        setGlobalLdapURL(
                data.getAttribute(AttrNames.UGDSCONFIG_GLOBALDIRURL));
        boolean useGlobal = inforef != null && inforef.length() > 0;
        if (useGlobal) {
            _rbUseGlobal.setSelected(true);
            setLdapHost("");
            //setLdapPort("389");
            _cbSSL.setEnabled(false);
            setBaseDN("");
            setBindDN("");
            setBindPW1("");
        } else {
            _rbOverrideGlobal.setSelected(true);
            setLdapURL(data.getAttribute(AttrNames.UGDSCONFIG_DIRURL));
            setBindDN(data.getAttribute(AttrNames.UGDSCONFIG_BINDDN));
            //setBindPW1("");
            setBindPW1(data.getAttribute(AttrNames.UGDSCONFIG_BINDPW));

        }
    }

    ItemListener _rbListener = new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    boolean enable = true;
                    if (e.getSource() == _rbUseGlobal &&
                            _rbUseGlobal.isSelected()) {
                        enable = false;
                    }
                    _lblHost.setEnabled(enable);
                    _lblHost.repaint();
                    _lblHostUsage.setEnabled(enable);
                    _lblHostUsage.repaint();
                    _lblBaseDN.setEnabled(enable);
                    _lblBaseDN.repaint();
                    _lblBindDN.setEnabled(enable);
                    _lblBindDN.repaint();
                    _lblBindPW1.setEnabled(enable);
                    _lblBindPW1.repaint();
                    _txtHost.setEnabled(enable);
                    _txtBaseDN.setEnabled(enable);
                    _txtBindDN.setEnabled(enable);
                    _txtBindPW1.setEnabled(enable);
                    _cbSSL.setEnabled(enable);
                    Color enableBackground =
                            UIManager.getColor(enable ? "window" : "control");
                    _txtHost.setBackground(enableBackground);
                    _txtBaseDN.setBackground(enableBackground);
                    _txtBindDN.setBackground(enableBackground);
                    _txtBindPW1.setBackground(enableBackground);
                }
            };

    ActionListener _cbSSLListener = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (_cbSSL.isSelected()) {
                        ; //_txtPort.setText(_defaultSSLPort);
                    } else {
                        ; //_txtPort.setText(_defaultPort);
                    }
                }
            };

    public void setLdapHost(String host) {
        _txtHost.setText((host != null) ? host : "");
    }

    /*public void setLdapPort(String port) {
         _txtPort.setText((port != null) ? port : "");
     }*/

    public void setBaseDN(String dn) {
        if (dn == null) {
            _txtBaseDN.setText("");
        } else if (dn.startsWith("/")) {
            _txtBaseDN.setText(dn.substring(1));
        } else {
            _txtBaseDN.setText(dn);
        }
    }


    public void setLdapURL(String url) {
        String parse;
        if (url.startsWith("ldaps://")) {
            _cbSSL.setSelected(true);
            parse = url.substring(8);
        } else if (url.startsWith("ldap://")) {
            _cbSSL.setSelected(false);
            parse = url.substring(7);
        } else {
            Debug.println("ERROR: Bad Ldap url " + url);
            return;
        }

        Debug.println("parse="+parse);

        //        try {
        // Use URL for parsing. As it does not understand LDAP protoco, set http
        //            java.net.URL parseurl = new java.net.URL("http" + parse);
        //            setLdapHost(parseurl.getHost());
        //            setLdapPort(new Integer(parseurl.getPort()).toString());
        //            setBaseDN(parseurl.getFile());
        //        }
        //        catch (Exception e) {
        //            Debug.println("ERROR: Bad Ldap url " + url);
        //            return;
        //        }

        int iNextSlash = parse.indexOf('/', 8);
        setLdapHost(parse.substring(0, iNextSlash));
        setBaseDN(parse.substring(iNextSlash + 1));
    }

    private String getLdapURL() throws ValidationException {
        String host = _txtHost.getText().trim();
        String baseDN = _txtBaseDN.getText().trim();

        if (host.length() == 0) {
            throw new ValidationException("", _i18nEnterLdapHost);
        }
        else if (baseDN.length() == 0) {
            throw new ValidationException("", _i18nEnterBaseDN);
        }

        String url = _txtHost.getText().trim() + "/" +
                _txtBaseDN.getText().trim();

        if (_cbSSL.isSelected()) {
            return "ldaps://" + url;
        } else {
            return "ldap://" + url;
        }
    }

    public void setGlobalLdapURL(String url) {
        _lblGlobalLdapURLValue.setText((url != null) ? url : "");
        _lblGlobalLdapURLValue.repaint();
    }

    void setBindDN(String binddn) {
        _txtBindDN.setText(binddn == null ? "" : binddn);
    }

    void setBindPW1(String bindPW) {
        _txtBindPW1.setText(bindPW == null ? "" : bindPW);
    }

    public void getPanelContent(IConfigDataModel data)
            throws ConfigPanelException {
        if (_rbOverrideGlobal.isSelected()) {

            String url = getLdapURL();
            String bindDN = _txtBindDN.getText().trim();
            String pw1 = _txtBindPW1.getText().trim();
            boolean modified, pwdModified;

            modified = !data.getAttribute(
                    AttrNames.UGDSCONFIG_DIRURL).equals("");
            modified = modified || !url.equals(
                    data.getAttribute(AttrNames.UGDSCONFIG_DIRURL));
            modified = modified || !bindDN.equals(
                    data.getAttribute(AttrNames.UGDSCONFIG_BINDDN));
            modified = modified || !pw1.equals(
                    data.getAttribute(AttrNames.UGDSCONFIG_BINDPW));

            if (!modified)
                return;

            if (bindDN.length() == 0 && pw1.length() != 0) {
                // Can not have bindPWD and not have bindDN
                throw new ValidationException("", _i18nEnterBindDN);
            }

            // try to connect to the server
            connectAndValidate();

            data.setAttribute(AttrNames.UGDSCONFIG_DIRURL, url);
            data.setAttribute(AttrNames.UGDSCONFIG_BINDDN, bindDN);
            data.setAttribute(AttrNames.UGDSCONFIG_BINDPW, pw1);
            data.setAttribute(AttrNames.UGDSCONFIG_INFOREF, "");

        } else {
            data.setAttribute(AttrNames.UGDSCONFIG_INFOREF, "default");
        }

        if (data instanceof AdminConfigData) {
            ((AdminConfigData) data).setDialogParent(this); // For ack dialog
        }

    }

    private void connectAndValidate() throws ConfigPanelException {
        String host = _txtHost.getText().trim();
        String baseDN = _txtBaseDN.getText().trim();
        String bindPWD = _txtBindPW1.getText().trim();
        String bindDN = _txtBindDN.getText().trim();
        boolean ssl = _cbSSL.isSelected();
        int portNum = -1;

        try {
            LDAPUtil.validateLDAPParams(host, portNum, ssl, bindDN,
                    bindPWD, baseDN);
        } catch (IllegalArgumentException e) {
            throw new ValidationException("", e.getMessage());
        }
    }


    /**
      * Override BaseEditPanel.makeConfigPanel() to provide a custom panel,
      * called by baseEditPanel constructor
     */
    protected JComponent makeConfigPanel() {
        JPanel p = new JPanel();
        GBC gbc = new GBC();
        GridBagLayout gbl;
        int row = 0;

        // Indent for the group under a radio button.
        int groupIndent = 20;

        p.setBorder(BaseConfigPanel.createGroupBorder(_i18nUGGroupbox));
        p.setLayout(gbl = new GridBagLayout());

        /**
         * Create warning message for enabling SSL
         */
        gbc.setInsets(0, 0, 0, 0);
        gbc.setGrid(0, row, 3, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
                GBC.HORIZONTAL); //fill
        p.add(createInfoMessage(), gbc);
        row++;

        /**
         * Create default froup
         */
        _rbUseGlobal = new JRadioButton(_i18nUseGlobal, false);
        gbc.setInsets(0, 0, 0, 0);
        gbc.setGrid(0, row, 3, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, //anchor
                GBC.HORIZONTAL); //fill
        p.add(_rbUseGlobal, gbc);

        row++;
        _lblGlobalLdapURL = new JLabel(_i18nLdapURL);
        gbc.setInsets(0, groupIndent, 0, 0);
        gbc.setGrid(0, row, 1, 1);
        gbc.setSpace(0.0, 0.0, GBC.EAST, // anchor
                GBC.NONE); //fill
        p.add(_lblGlobalLdapURL, gbc);


        _lblGlobalLdapURLValue = new JLabel(".");
        gbc.setInsets(0, DIFFERENT_COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 2, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
                GBC.HORIZONTAL); //fill
        p.add(_lblGlobalLdapURLValue, gbc);

        /**
         * Create override group
         */
        row++;
        _rbOverrideGlobal = new JRadioButton(_i18nOverrideGlobal, false);
        gbc.setInsets(DIFFERENT_COMPONENT_SPACE, 0, 0, 0);
        gbc.setGrid(0, row, 3, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, //anchor
                GBC.HORIZONTAL); //fill
        p.add(_rbOverrideGlobal, gbc);

        row++;
        _lblHost = new JLabel(_i18nHost);
        gbc.setInsets(0, groupIndent, 0, 0);
        gbc.setGrid(0, row, 1, 1);
        gbc.setSpace(0.0, 0.0, GBC.EAST, // anchor
                GBC.NONE); //fill
        p.add(_lblHost, gbc);

        _txtHost = new SingleByteTextField(16);
        gbc.setInsets(0, DIFFERENT_COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 2, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
                GBC.HORIZONTAL); //fill
        p.add(_txtHost, gbc);
        _lblHost.setLabelFor(_txtHost);

        row++;

        _lblHostUsage = new JLabel(_i18nHostUsage);
        gbc.setInsets(0, groupIndent, 0, 0);
        gbc.setGrid(0, row, 1, 1);
        gbc.setSpace(0.0, 0.0, GBC.EAST, // anchor
                GBC.NONE); //fill
        p.add(_lblHostUsage, gbc);

        row++;

        _cbSSL = new JCheckBox(_i18nUseSSL, false);
        gbc.setInsets(COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 2, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, //anchor
                GBC.HORIZONTAL); //fill
        p.add(_cbSSL, gbc);

        row++;
        _lblBaseDN = new JLabel(_i18nBaseDN);
        _lblBaseDN.setFont(BaseConfigPanel.getLabelFont());
        gbc.setInsets(COMPONENT_SPACE, 0, 0, 0);
        gbc.setGrid(0, row, 1, 1);
        gbc.setSpace(0.0, 0.0, GBC.EAST, // anchor
                GBC.NONE); //fill
        p.add(_lblBaseDN, gbc);

        _txtBaseDN = new JTextField(16);
        gbc.setInsets(COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 2, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
                GBC.HORIZONTAL); //fill
        p.add(_txtBaseDN, gbc);
        _lblBaseDN.setLabelFor(_txtBaseDN);

        row++;
        _lblBindDN = new JLabel(_i18nBindDN);
        gbc.setInsets(COMPONENT_SPACE, groupIndent, 0, 0);
        gbc.setGrid(0, row, 1, 1);
        gbc.setSpace(0.0, 0.0, GBC.EAST, // anchor
                GBC.NONE); //fill
        p.add(_lblBindDN, gbc);

        _txtBindDN = new JTextField(16);
        gbc.setInsets(COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 2, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
                GBC.HORIZONTAL); //fill
        p.add(_txtBindDN, gbc);
        _lblBindDN.setLabelFor(_txtBindDN);

        row++;
        _lblBindPW1 = new JLabel(_i18nBindPW);
        gbc.setInsets(COMPONENT_SPACE, groupIndent, 0, 0);
        gbc.setGrid(0, row, 1, 1);
        gbc.setSpace(0.0, 0.0, GBC.EAST, //GBC.EAST, // anchor
                GBC.NONE); //fill
        p.add(_lblBindPW1, gbc);

        _txtBindPW1 = new SingleBytePasswordField(16);
        gbc.setInsets(COMPONENT_SPACE, DIFFERENT_COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 2, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
                GBC.HORIZONTAL); //fill
        p.add(_txtBindPW1, gbc);
        _lblBindPW1.setLabelFor(_txtBindPW1);

        row++;

        ButtonGroup rbGroup = new ButtonGroup();
        rbGroup.add(_rbUseGlobal);
        rbGroup.add(_rbOverrideGlobal);

        return p;
    }

    private JPanel createInfoMessage() {
        GridBagLayout gbl;
        GBC gbc = new GBC();
        JPanel group = new JPanel(gbl = new GridBagLayout());
        int row = 0;
        MultilineLabel mll;
        JLabel refLabel = new JLabel(); // unsed only for font

        gbc.setInsets(0, COMPONENT_SPACE, 0, 0);
        gbc.setGrid(1, row, 1, 1);
        gbc.setSpace(1.0, 0.0, GBC.WEST, //anchor
                GBC.HORIZONTAL); //fill
        group.add(mll = new MultilineLabel(_i18nWarnCert, 1, 36), gbc);
        mll.setFont(refLabel.getFont());
        row++;

        return group;
    }
}
