/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2000-2009 Sun Microsystems, Inc. All rights reserved. 
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License ("CDDL") (collectively, the "License").  You may
 * not use this file except in compliance with the License.  You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or mq/legal/LICENSE.txt.  See the License for the specific language
 * governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at mq/legal/LICENSE.txt.  Sun designates
 * this particular file as subject to the "Classpath" exception as provided by
 * Sun in the GPL Version 2 section of the License file that accompanied this
 * code.  If applicable, add the following below the License Header, with the
 * fields enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or  to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright holder. 
 */

/*
 * @(#)BrokerServicePropsDialog.java	1.16 06/27/07
 */ 

package com.sun.messaging.jmq.admin.apps.console;

import java.awt.Dimension;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JSeparator;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import javax.swing.JOptionPane;

import com.sun.messaging.jmq.util.admin.ServiceInfo;
import com.sun.messaging.jmq.util.ServiceState;
import com.sun.messaging.jmq.util.ServiceType;

import com.sun.messaging.jmq.admin.util.Globals;
import com.sun.messaging.jmq.admin.resources.AdminConsoleResources;
import com.sun.messaging.jmq.admin.resources.AdminResources;
import com.sun.messaging.jmq.admin.apps.console.event.BrokerAdminEvent;
import com.sun.messaging.jmq.admin.apps.console.util.LabelledComponent;
import com.sun.messaging.jmq.admin.apps.console.util.LabelValuePanel;
import com.sun.messaging.jmq.admin.apps.console.util.IntegerField;
import com.sun.messaging.jmq.admin.bkrutil.BrokerAdminUtil;

/** 
 * Implementation of the Service Properties Dialog
 */
public class BrokerServicePropsDialog extends AdminDialog implements ActionListener {
    
    private static AdminResources ar = Globals.getAdminResources();
    private static AdminConsoleResources acr = Globals.getAdminConsoleResources();
    private static String close[] = {acr.getString(acr.I_DIALOG_CLOSE)};
    private BrokerServiceCObj	svcCObj;
    private JLabel 		svcName;
    private JRadioButton	dynamicPortButton;
    private JRadioButton	staticPortButton;
    private JLabel		dynamicPortLabel;
    private IntegerField	staticPortIF;
    private JLabel 	 	svcState;
    private IntegerField 	minThreads, maxThreads;
    private JLabel 		numConnections, allocatedThreads;
    private JPanel		lvp;
    private LabelledComponent   items[];

    private ServiceInfo		svcInfo;

    private LabelledComponent	svcPortComponent;


    public BrokerServicePropsDialog(Frame parent)  {
	super(parent, acr.getString(acr.I_BROKER_SVC_PROPS), (OK | CANCEL | HELP));
	setHelpId(ConsoleHelpID.SERVICE_PROPS);
    }

    public JPanel createWorkPanel() {

        JPanel                  workPanel;
        GridBagLayout           workGridbag;
        GridBagConstraints      workConstraints;
        LabelledComponent       tmpLabelC;
        LabelledComponent       lvpItems[];
        LabelValuePanel         lvp;
        JSeparator              sep;

        workPanel = new JPanel();
        workGridbag = new GridBagLayout();
        workPanel.setLayout(workGridbag);
        workConstraints = new GridBagConstraints();

	/*
         * Initialize.
         */
        workConstraints.gridx = 0;
        workConstraints.gridy = 0;
        workConstraints.anchor = GridBagConstraints.WEST;
        workConstraints.fill = GridBagConstraints.NONE;
        workConstraints.insets = new Insets(5, 0, 5, 0);
        workConstraints.ipadx = 0;
        workConstraints.ipady = 0;
        workConstraints.weightx = 1.0;

        lvpItems = new LabelledComponent[3];

        svcName = new JLabel();
        tmpLabelC = new LabelledComponent(
		ar.getString(ar.I_JMQCMD_SVC_NAME) + ":",
		svcName);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
	lvpItems[0] = tmpLabelC;

	// for radio buttons for dynamic / static port number
	JPanel servicePanel = new JPanel();
	GridBagLayout serviceGridbag = new GridBagLayout();
	servicePanel.setLayout(serviceGridbag);
	GridBagConstraints serviceConstraints = new GridBagConstraints();

	/*
         * Initialize.
         */
        serviceConstraints.anchor = GridBagConstraints.WEST;
	serviceConstraints.insets = new Insets(0, 0, 0, 0);

	serviceConstraints.gridx = 0;
	serviceConstraints.gridy = 0;
	dynamicPortButton = new JRadioButton();
	dynamicPortButton.addActionListener(this);
	serviceGridbag.setConstraints(dynamicPortButton, serviceConstraints);
	servicePanel.add(dynamicPortButton);

	serviceConstraints.gridx = 0;
	serviceConstraints.gridy = 1;
	staticPortButton = new JRadioButton();
	staticPortButton.addActionListener(this);
	serviceGridbag.setConstraints(staticPortButton, serviceConstraints);
	servicePanel.add(staticPortButton);

	ButtonGroup servicePortGroup = new ButtonGroup();
	servicePortGroup.add(dynamicPortButton);
	servicePortGroup.add(staticPortButton);

	serviceConstraints.gridx = 1;
	serviceConstraints.gridy = 0;
	JLabel dynamicLabel = new JLabel(acr.getString(acr.I_DYNAMIC_CAP) + ":");
	serviceGridbag.setConstraints(dynamicLabel, serviceConstraints);
	servicePanel.add(dynamicLabel);

	serviceConstraints.gridx = 1;
	serviceConstraints.gridy = 1;
	JLabel staticLabel = new JLabel(acr.getString(acr.I_STATIC_CAP) + ":");
	serviceGridbag.setConstraints(staticLabel, serviceConstraints);
	servicePanel.add(staticLabel);

	serviceConstraints.gridx = 2;
	serviceConstraints.gridy = 0;
	serviceConstraints.insets = new Insets(0, 5, 0, 0);
	dynamicPortLabel = new JLabel();
	serviceGridbag.setConstraints(dynamicPortLabel, serviceConstraints);
	servicePanel.add(dynamicPortLabel);

	serviceConstraints.gridx = 2;
	serviceConstraints.gridy = 1;
	serviceConstraints.insets = new Insets(0, 5, 0, 0);
	staticPortIF = new IntegerField(0, Integer.MAX_VALUE, 15);
	staticPortIF.setEnabled(false);
	serviceGridbag.setConstraints(staticPortIF, serviceConstraints);
	servicePanel.add(staticPortIF);

        tmpLabelC = new LabelledComponent(
                ar.getString(ar.I_JMQCMD_SVC_PORT)+":",
                servicePanel, LabelledComponent.NORTH);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
        lvpItems[1] = tmpLabelC;

	// Set this so that we can enable/disable this component
	svcPortComponent = lvpItems[1];

        svcState = new JLabel();
        tmpLabelC = new LabelledComponent(
		ar.getString(ar.I_JMQCMD_SVC_STATE)+":",
		svcState);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
	lvpItems[2] = tmpLabelC;

        lvp = new LabelValuePanel(lvpItems, 4, 0);
        workGridbag.setConstraints(lvp, workConstraints);
        workPanel.add(lvp);

        workConstraints.gridy = 1;

        sep = new JSeparator();
        workConstraints.fill = GridBagConstraints.HORIZONTAL;
        workGridbag.setConstraints(sep, workConstraints);
        workPanel.add(sep);
        /*
         * Reset
         */
        workConstraints.fill = GridBagConstraints.NONE;
        workConstraints.gridy = 2;

        lvpItems = new LabelledComponent[2];

        allocatedThreads = new JLabel();
        tmpLabelC = new LabelledComponent(
		ar.getString(ar.I_JMQCMD_SVC_CUR_THREADS) + ":",
		allocatedThreads);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
	lvpItems[0] = tmpLabelC;

        numConnections = new JLabel();
        tmpLabelC = new LabelledComponent(
		ar.getString(ar.I_JMQCMD_SVC_NUM_CXN) + ":",
		numConnections);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
	lvpItems[1] = tmpLabelC;

        lvp = new LabelValuePanel(lvpItems, 4, 0);
        workGridbag.setConstraints(lvp, workConstraints);
        workPanel.add(lvp);

        workConstraints.gridy = 3;

        sep = new JSeparator();
        workConstraints.fill = GridBagConstraints.HORIZONTAL;
        workGridbag.setConstraints(sep, workConstraints);
        workPanel.add(sep);
        /*
         * Reset
         */
        workConstraints.fill = GridBagConstraints.NONE;
        workConstraints.gridy = 4;

        lvpItems = new LabelledComponent[2];

        minThreads = new IntegerField(0, Integer.MAX_VALUE, 15);
	minThreads.addActionListener(this);
        tmpLabelC = new LabelledComponent(
                ar.getString(ar.I_JMQCMD_SVC_MIN_THREADS) + ":",
                minThreads);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
        workPanel.add(tmpLabelC);
	lvpItems[0] = tmpLabelC;

	maxThreads = new IntegerField(0, Integer.MAX_VALUE, 15);
	maxThreads.addActionListener(this);
        tmpLabelC = new LabelledComponent(
                ar.getString(ar.I_JMQCMD_SVC_MAX_THREADS) + ":",
                maxThreads);
        workGridbag.setConstraints(tmpLabelC, workConstraints);
	lvpItems[1] = tmpLabelC;

        lvp = new LabelValuePanel(lvpItems, 4, 0);
        workGridbag.setConstraints(lvp, workConstraints);
        workPanel.add(lvp);

	return workPanel;
    }

    public void doOK() { 
	int portValue = -1;
	int minThreadsValue = -1;
	int maxThreadsValue = -1;

	if (staticPortButton.isSelected()) {
	    String portText = staticPortIF.getText();

	    if (!"".equals(portText)) {
		portValue = Integer.parseInt(portText);
	    } else {
                JOptionPane.showOptionDialog(this,
                    acr.getString(acr.E_NO_STATIC_PORT),
                    acr.getString(acr.I_BROKER_SVC_PROPS) + ": "
                        + acr.getString(acr.I_ERROR_CODE, acr.E_NO_STATIC_PORT),
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.ERROR_MESSAGE, null, close, close[0]);
                return;
	    }

	} else if (dynamicPortButton.isSelected()) {
	    // New protocol.
	    // If the port number is not used for this service it
	    // is set to -1.  If the port number was -1 do not change it.
	    if (svcInfo.port == -1)
		portValue = -1;		
	    // Set it to 0 for dynamic otherwise
	    else
	        portValue = 0;
	}

	minThreadsValue = Integer.parseInt(minThreads.getText());
	maxThreadsValue = Integer.parseInt(maxThreads.getText());

        /*
	 * Rollback the following fix.  The check is now done
	 * by the broker.	 
	 *
         * Fix for bug 4432483: jmqcmd, jmqadmin: setting admin max 
         * threads = 0 is allowed & hangs
         *
         * Display a warning if service type != admin.
         * Disallow the operation if service type == admin.
	if (maxThreadsValue <= 0) {
	    if (ServiceType.ADMIN == svcInfo.type) {
                JOptionPane.showOptionDialog(this,
                    acr.getString(acr.E_ADMIN_MAX_THREAD),
                    acr.getString(acr.I_BROKER_SVC_PROPS) + ": "
                        + acr.getString(acr.I_ERROR_CODE, acr.E_ADMIN_MAX_THREAD),
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.ERROR_MESSAGE, null, close, close[0]);
                return;

	    } else {
        	int result = JOptionPane.showConfirmDialog(this,
      		    acr.getString(acr.Q_SET_MAX_THREAD_ZERO, svcInfo.name),
                    acr.getString(acr.I_BROKER_SVC_PROPS),
               	    JOptionPane.YES_NO_OPTION);

        	if (result == JOptionPane.NO_OPTION)
            	    return;
	    }
	}
	*/

        BrokerAdminEvent bae = 
	    new BrokerAdminEvent(this, BrokerAdminEvent.UPDATE_SVC);

	bae.setPort(portValue);
	bae.setMinThreads(minThreadsValue);
	bae.setMaxThreads(maxThreadsValue);

        bae.setOKAction(true);
        fireAdminEventDispatched(bae);
    }

    public void doApply()  { }
    public void doReset() { }
    public void doCancel() { hide(); }

    public void doClose() { 
	hide(); 
	doClear();
    }

    public void doClear() { 
	svcName.setText(" ");
	dynamicPortButton.setSelected(true);
	staticPortButton.setSelected(false);
	dynamicPortLabel.setText(" ");
	staticPortIF.setText("");
	svcState.setText(" ");
	minThreads.setText("0");
	maxThreads.setText("0");
	allocatedThreads.setText("0");
	numConnections.setText("0");
	svcPortComponent.setEnabled(true);
    }

    public void show(ServiceInfo svcInfo)  {

	this.svcInfo = svcInfo;

	if (svcInfo == null) {
	    doClear();
	    return;
	}

	svcName.setText(svcInfo.name);

	// The port number is not applicable to this service
	if (svcInfo.port == -1)
	    enableServicePort(false);
	else {
	    enableServicePort(true);

	    if (svcInfo.dynamicPort) {
	        dynamicPortButton.setSelected(true);
	        staticPortIF.setEnabled(false);
	        staticPortIF.setText("");

                switch (svcInfo.state) {
                    case ServiceState.UNKNOWN:
		        dynamicPortLabel.setText(" ");
                        break;
                    default:
		        dynamicPortLabel.setText(new Integer(svcInfo.port).toString());
                }
            } else {
	        staticPortButton.setSelected(true);
	        staticPortIF.setEnabled(true);
	        staticPortIF.setText(new Integer(svcInfo.port).toString());
	        dynamicPortLabel.setText(" ");
	    }
	}
	//svcState.setText(ServiceState.getString(svcInfo.state));
	svcState.setText(BrokerAdminUtil.getServiceState(svcInfo.state));
	minThreads.setText(new Integer(svcInfo.minThreads).toString());
	maxThreads.setText(new Integer(svcInfo.maxThreads).toString());
	allocatedThreads.setText(new Integer(svcInfo.currentThreads).toString());
	numConnections.setText(new Integer(svcInfo.nConnections).toString());
	super.show();
    }

    /*
     * BEGIN INTERFACE ActionListener
     */
    public void actionPerformed(ActionEvent e)  {
        Object source = e.getSource();

        if (source == dynamicPortButton)  {
            doDynamicPortButton();

        } else if (source == staticPortButton)  {
            doStaticPortButton();

        } else  {
            super.actionPerformed(e);
        }
    }
    /*
     * END INTERFACE ActionListener
     */

    private void doDynamicPortButton() {
	staticPortIF.setEnabled(false);
    }

    private void doStaticPortButton() {
	staticPortIF.setEnabled(true);
    }

    private void enableServicePort(boolean b) {
	svcPortComponent.setEnabled(b);
	if (!b) {
            dynamicPortButton.setSelected(true);
            staticPortButton.setSelected(false);
            dynamicPortLabel.setText(" ");
            staticPortIF.setText("");
	}
    }

    /*
     * Not used.
    private void makeReadOnly() {
        svcName.setEditable(false);
        svcPort.setEditable(false);
        svcState.setEditable(false);
        minThreads.setEditable(false);
        maxThreads.setEditable(false);
        allocatedThreads.setEditable(false);
        numConnections.setEditable(false);
    }
     */
}
