/* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Engineous Software Inc.,
 * 2000 CentreGreen Way, Suite 100 Cary, NC 27513, U.S.A
 * All rights reserved.
 *
 * IN NO EVENT SHALL ENGINEOUS SOFTWARE INC. BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
 * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ENGINEOUS
 * SOFTWARE INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ENGINEOUS SOFTWARE INCORPORATED SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND ENGINEOUS SOFTWARE INC. HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

package examples.development.components.plate;

import com.engineous.common.i18n.IString;
import com.engineous.desktop.sdk.AbstractDesktopEditor;
import com.engineous.sdk.exception.SDKException;
import com.engineous.sdk.gui.ProgressRange;
import com.engineous.sdk.log.Log;
import com.engineous.sdk.log.SysLog;
import com.engineous.sdk.model.DtAggregateVariable;
import com.engineous.sdk.model.DtComponent;
import com.engineous.sdk.model.DtModelManager;
import com.engineous.sdk.model.DtScalarVariable;
import com.engineous.sdk.vars.EsiTypes;
import com.engineous.sdk.vars.ScalarVariable;
import com.engineous.sdk.vars.Variable;
import com.engineous.sdk.vars.VariableException;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.Vector;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

//=========================================================================
/**
 * @author Engineous Software
 *
 */
public class PlateEditor
		extends AbstractDesktopEditor {

	transient private static final Class CLASS = PlateEditor.class;

	private JPanel myPanel;
	private JComboBox shapeMenu;
	private JComboBox materialMenu;
	private JTextField thicknessEntry;

	private ScalarVariable shapeProp;
	private ScalarVariable materialProp;
	private ScalarVariable thicknessParam;

	private String theShape;

	//=========================================================================
	/**
	 * Method initialize
	 * <p><i>Implements interface <b>ComponentEditor</b></i></p>
	 * @param component
	 * @param progress
	 * @throws SDKException
	 */
	public void initEditor(DtComponent component, ProgressRange progress)
			throws SDKException {

		super.initEditor(component, progress);

		try {

			SysLog.logDebug(new IString(CLASS, 30493, "Initializing Editor for Component = {0}", component.getName()));

			shapeProp = ((DtScalarVariable)component.getProperty("Shape"));
			materialProp = ((DtScalarVariable)component.getProperty("Material"));
			thicknessParam = ((DtScalarVariable)component.getParameter("Thickness"));

		}
		catch (Throwable e) {
			throw new SDKException(e, "Error initializing component editor.");
		}
	}

	//=========================================================================
	/**
	 * Method apply
	 * <p><i>Implements interface <b>ComponentEditor</b></i></p>
	 * @throws SDKException
	 */
	public void apply()
			throws SDKException {

		try {
			SysLog.log(Log.INFO, new IString(CLASS, 65951, "Apply was clicked: Component = {0}", component.getName()));

			// keep reference to old shape value for use below
			String oldShape = theShape;
			theShape = (String)shapeMenu.getSelectedItem();

			shapeProp.getValueObj().setValue(theShape);
			materialProp.getValueObj().setValue((String)materialMenu.getSelectedItem());
			thicknessParam.getValueObj().setValue(thicknessEntry.getText());

			// if the shape has changed, need to define new dimensions to specify
			DtAggregateVariable dimensions = ((DtAggregateVariable)component.getParameter("Dimensions"));
			if (!theShape.equals(oldShape) || (dimensions.getMemberList().size() == 0)) {

				dimensions.removeAll();

				// Hard-coding this here - could actually provide in descriptor

				Vector newDimensions = new Vector();
				if (theShape.equals("circle")) {
					newDimensions.add("radius");
				}
				else if (theShape.equals("rectangle")) {
					newDimensions.add("width");
					newDimensions.add("height");
				}
				else if (theShape.equals("triangle")) {
					newDimensions.add("base");
					newDimensions.add("height");
				}

				DtScalarVariable dimensionItem;

				for (int i = 0; i < newDimensions.size(); i++) {
					dimensionItem = DtModelManager.createScalarVariable((String)newDimensions.get(i), EsiTypes.REAL, Variable.ROLE_PARAMETER,
							Variable.MODE_INPUT, null, null);
					dimensions.addMember(dimensionItem);
				}

			}

		}
		catch (Exception e) {
			throw new SDKException(e, "Failed to apply changes.");
		}

	}

	//=========================================================================
	/**
	 * Method cancel
	 * <p><i>Implements interface <b>ComponentEditor</b></i></p>
	 * @throws SDKException
	 */
	public void cancel()
			throws SDKException {

		try {
			SysLog.log(Log.INFO, new IString(CLASS, 6902, "Cancel was clicked: Component = {0}", component.getName()));
		}
		catch (Exception e) {
			throw new SDKException(e, "Failed to cancel changes.");
		}

	}

	//=========================================================================
	/**
	 * This method is called right before the component editor is shown to the user
	 * <p><i>Implements interface <b>ComponentEditor</b></i></p>
	 * @throws SDKException
	 */
	public void open()
			throws SDKException {

		try {
			SysLog.log(Log.INFO, new IString(CLASS, 87776, "Opening Editor for {0}", component.getName()));

			// First create the GUI if it is not already created
			if (myPanel == null) {
				createGUI();
			}

			// Now populate the GUI with the current configuration
			populateGUI();

		}
		catch (Exception e) {
			throw new SDKException(e, "Failed to open the editor.");
		}

	}

	//=========================================================================
	/**
	 * Method createGUI
	 * @throws Exception
	 */
	private void createGUI()
			throws Exception {

		this.setLayout(new BorderLayout());

		myPanel = new JPanel(new GridBagLayout());
		this.add(myPanel, BorderLayout.NORTH);

		JLabel instructionsText = new JLabel("This component will calculate the area, volume, and weight of a plate.");
		JLabel instructionsText2 = new JLabel("(All dimensions should be specified in meters)");

		myPanel.add(instructionsText,
					new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));
		myPanel.add(instructionsText2,
					new GridBagConstraints(0, 1, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 10, 0), 0, 0));

		// Widgets to specify shape
		JLabel shapeLabel = new JLabel("Shape");
		shapeMenu = new JComboBox(new String[]{ "circle", "rectangle", "triangle" });

		// Widgets to specify material
		JLabel materialLabel = new JLabel("Material");
		materialMenu = new JComboBox(new String[]{ "aluminum", "steel", "wood" });

		// Widgets to specify thickness
		JLabel thicknessLabel = new JLabel("Thickness");
		thicknessEntry = new JTextField(8);


		// Now add them to the panel
		myPanel.add(shapeLabel,
					new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 10, 0), 0, 0));
		myPanel.add(shapeMenu,
					new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 10, 0), 0, 0));
		myPanel.add(materialLabel,
					new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 10, 0), 0, 0));
		myPanel.add(materialMenu,
					new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 10, 0), 0, 0));
		myPanel.add(thicknessLabel,
					new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
		myPanel.add(thicknessEntry,
					new GridBagConstraints(1, 4, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));


	}

	//=========================================================================
	/**
	 * Method populateGUI
	 * @throws VariableException
	 */
	//=========================================================================
	private void populateGUI()
			throws VariableException {

		theShape = shapeProp.getValueObj().getAsString();

		shapeMenu.setSelectedItem(theShape);
		materialMenu.setSelectedItem(materialProp.getValueObj().getAsString());
	}


}
