/* Copyright Dassault Systemes, 1999, 2009 */


package examples.development.components.plate;


import java.io.FileOutputStream;
import java.util.Vector;

import com.engineous.sdk.component.ComponentAPI;
import com.engineous.sdk.component.DefaultComponentAPI;
import com.engineous.sdk.exception.SDKException;
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.server.Logon;
import com.engineous.sdk.vars.EsiTypes;
import com.engineous.sdk.vars.Variable;

//=========================================================================
/**
 * Title:        PlateAPI <br>
 * Description:  Example of a component API using the Plate example
 * @author      Engineous Software
 */
//=========================================================================
public class PlateAPI
		extends DefaultComponentAPI {

	private String shape = "";
	private String oldShape = "";
	private String material = "";
	private double thickness = 0.0;

	//===============================================================
	/**
	 * This method will obtain the current value of the Calculator expression
	 * from the component so that it can be manipulated as desired.  The infrastructure
	 * will automatically call this when the component API is requested.
	 * </p>
	 * @param component
	 * @throws SDKException
	 */
	//===============================================================
	public void initialize(DtComponent component)
			throws SDKException {

		super.initialize(component);

		try {
			shape = ((DtScalarVariable)component.getProperty("Shape")).getValueObj().getAsString();
			material = ((DtScalarVariable)component.getProperty("Material")).getValueObj().getAsString();
			thickness = ((DtScalarVariable)component.getParameter("Thickness")).getValueObj().getAsReal();

			//keep track of the initial shape so we know if we need to adjust the dimensions parameter
			//in the apply method
			oldShape = shape;
		}
		catch (Exception e) {
			throw new SDKException(e, "Error intializing Plate API");
		}
	}

	//===============================================================
	/**
	 * This method will save the configuration of the component back into the model.
	 * In this case, the expression defined in the calculator will get stored.
	 * </p>
	 * @throws SDKException
	 */
	//===============================================================
	public void apply()
			throws SDKException {

		try {
			super.apply();

			((DtScalarVariable)component.getProperty("Shape")).getValueObj().setValue(shape);
			((DtScalarVariable)component.getProperty("Material")).getValueObj().setValue(material);
			((DtScalarVariable)component.getParameter("Thickness")).getValueObj().setValue(thickness);

			//Now, adjust the parameters on the component to be appropriate for the shape
			// if the shape has changed, need to define new dimensions to specify
			DtAggregateVariable dimensions = ((DtAggregateVariable)component.getParameter("Dimensions"));
			if (!shape.equals(oldShape) || (dimensions.getMemberList().size() == 0)) {

				dimensions.removeAll();

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

				Vector newDimensions = new Vector();
				if (shape.equals("circle")) {
					newDimensions.add("radius");
				}
				else if (shape.equals("rectangle")) {
					newDimensions.add("width");
					newDimensions.add("height");
				}
				else if (shape.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, "Error updating the model using the Plate component API");
		}

	}

	//===============================================================
	/**
	 * Returns the current value of the shape.
	 * @return String - the value of the shape
	 */
	//===============================================================
	public String getShape() {
		return shape;
	}

	//===============================================================
	/**
	 * Sets the value of the shape, overwriting the previous value.
	 * Note that this new shape is not yet stored in the component.
	 * You must call the apply() method on the PlateAPI to store this
	 * shape permanently.
	 * </p>
	 * @param shape
	 * @throws SDKException
	 */
	//===============================================================
	public void setShape(String shape)
			throws SDKException {
		this.shape = shape;
	}

	//===============================================================
	/**
	 * Returns the current value of the material.
	 * @return String - the value of the material
	 */
	//===============================================================
	public String getMaterial() {
		return material;
	}

	//===============================================================
	/**
	 * Sets the value of the material, overwriting the previous value.
	 * Note that this new material is not yet stored in the component.
	 * You must call the apply() method on the PlateAPI to store this
	 * material permanently.
	 * </p>
	 * @param material
	 * @throws SDKException
	 */
	//===============================================================
	public void setMaterial(String material)
			throws SDKException {
		this.material = material;
	}

	//===============================================================
	/**
	 * Returns the current value of the thickness.
	 * @return double - the value of the thickness
	 */
	//===============================================================
	public double getThickness() {
		return thickness;
	}

	//===============================================================
	/**
	 * Sets the value of the thickness, overwriting the previous value.
	 * Note that this new thickness is not yet stored in the component.
	 * You must call the apply() method on the PlateAPI to store this
	 * thickness permanently.
	 * </p>
	 * @param thickness
	 * @throws SDKException
	 */
	//===============================================================
	public void setThickness(double thickness)
			throws SDKException {
		this.thickness = thickness;
	}


	//=========================================================================
	/**
	 * This method presents an example of how an application developer might
	 * use the Plate component API to configure a Plate component instance
	 * @param args
	 */
	//=========================================================================
	public static void main(String[] args) {

		try {
			Logon.initStandalone();

			DtComponent plateComp = DtModelManager.createComponent("com.engineous.component.Plate", "My Plate");
			DtModelManager mgr = DtModelManager.createModel(plateComp);

			ComponentAPI compAPI = plateComp.getAPI();

			compAPI.set("shape", "circle");
			compAPI.set("material", "aluminum");
			compAPI.set("thickness", 0.1);
			compAPI.apply();

			mgr.saveModel(new FileOutputStream("c:\\PlateModel.zmf"));

		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}


}

