package org.jcon.test;

import org.jcon.param.Param;
import org.jcon.param.ParamDriven;
import org.jcon.param.ParamDrivenInfo;
import org.jcon.util.DataLib;
import org.jcon.util.GenLib;
import java.awt.*;
import java.util.Hashtable;
import java.util.Vector;

/**
 * Provides a panelful of components using a GridBagLayout
 * and initialized via a Param. Do not attempt to use this
 * class until setParam() has been called.
 *
 * *** May implement ComponentContainer or such later ***
 * with getComponent(name), for use in data framework
 * *** In evolution
 *
 * @author Jack Harich
 */
public class ParamPanel extends Panel
    implements ParamDriven {

//---------- Private Fields ------------------------------
private Param param;
private Hashtable components = new Hashtable();

//---------- ParamDriven Implementation ------------------
public void setParam(Param param) {
    this.param = param;
    // Empty myself
    this.removeAll();
    components.clear();
    // Prepare layout
    GridBagLayout gbl = new GridBagLayout();
    this.setLayout(gbl);
    // Add each component in the param
    Vector compVector = param.getVector("Components");
    for (int i = 0; i < compVector.size(); i++) {
        Param compParam;
        try {
            compParam = (Param)compVector.elementAt(i);
        } catch(Exception ex) {
            continue; // Must be a comment
        }
        Component comp = createComponent(compParam);
        this.add(comp);
        gbl.setConstraints(comp,
            createConstraint(comp, compParam));

        String name = compParam.getString("Name");
//print("name " + name);
        if (name != null) components.put(name, comp);
    }
    // Done
    this.invalidate();
}
public Param getParam() {
    return param;
}
public boolean applyNewParam(Param newParam) {
    setParam(newParam);
    this.validate();
    return true;
}
public ParamDrivenInfo getParamDrivenInfo() {
    return null;
}
//---------- Public Methods ------------------------------
public Component getComponent(String name) {
    return (Component)components.get(name);
}
public int getNamedComponentCount() {
    return components.size();
}
//---------- Private Methods -----------------------------
private Component createComponent(Param param) {
    String className = param.getString("Class");
    Component comp = (Component)GenLib.createInstance(className);

    if (comp instanceof Label) {
        if (param.hasProperty("Text")) {
            ((Label)comp).setText(param.getString("Text"));
        }
    }
    if (comp instanceof TextField) {
        if (param.hasProperty("Columns")) {
            ((TextField)comp).setColumns(param.getInt("Columns"));
        } else {
            ((TextField)comp).setColumns(10); // Default
        }
    }
    return comp;
}
private GridBagConstraints createConstraint(
        Component component, Param param) {
    GridBagConstraints con = new GridBagConstraints();
    String name = param.getString("Name"); // For errors
    //----- *** Set defaults here ***

    //----- Required properties
    // Row and column - "Next" or int
    String rowColumn = param.getString("RowColumn");

    String row = DataLib.getDelimitedField(rowColumn, 1, ",").trim().intern();
    if (row == "Next") {
        // Do nothing
    } else if (row == "Rest") {
        con.gridheight = GridBagConstraints.REMAINDER;
    } else if (DataLib.isInt(row)) {
        con.gridy = Integer.valueOf(row).intValue() - 1;
    } else {
        GenLib.error("ParamGridBagPanel.createConstraint()",
            "Unknown Row value '" + row + "', element name '" + name + "'");
    }

    String column = DataLib.getDelimitedField(rowColumn, 2, ",").trim().intern();
    if (column == "Next") {
        // Do nothing
    } else if (column == "Rest") {
        con.gridwidth = GridBagConstraints.REMAINDER;
    } else if (DataLib.isInt(column)) {
        con.gridx = Integer.valueOf(column).intValue() - 1;
    } else {
        GenLib.error("ParamGridBagPanel.createConstraint()",
            "Unknown Column value '" + column + "', element name '" + name + "'");
    }
    //----- Optional properties
    // Alignment, called anchor by GridBagConstraints
    String alignment = param.getString("Alignment");
    if (alignment == null) {
        // Set defaults
        if (component instanceof Label) {
            alignment = "Right";
        } else if (component instanceof TextField) {
            alignment = "Left";
        }
    }
    if (alignment != null) {
        if (alignment == "Left") {
            con.anchor = GridBagConstraints.WEST;
        } else if (alignment == "Right") {
            con.anchor = GridBagConstraints.EAST;
        } else {
        GenLib.error("ParamGridBagPanel.createConstraint()",
            "Unknown Alignment value '" + alignment + "', element name '" + name + "'");
        }
    }
    // Spacing - Pixels above and below Component
    int spacing = 3; // Default
    if (param.hasProperty("Spacing")) {
        spacing = param.getInt("Spacing");
    }
    //if (component instanceof TextField) {
        // (top, left, bottom, right)
        con.insets = new Insets(spacing, 0, spacing, 0);
    //}
    //----- Done
    return con;
}
//--- Std
private static void print(String text) {
    System.out.println("ParamGridBagPanel" + text);
}

} // End class
