package org.jcon.util.setting;

import org.jcon.df.column.ColumnDef;
import org.jcon.param.Param;
import java.util.Vector;

/**
 * This class defines a setting. A setting is a named value
 * that can be stored and retreived. A Setting is really an 
 * isolated parameter with a global name. We use the name
 * "setting" to avoid conflict with "parameter".
 * <p>
 * The properties in a SettingDef override those of the 
 * same name in its SettingType.
 * <p>
 * The SettingDef properties are: <p> <pre> 
 * Required:
 * 		Name
 *    Type - Determines SettingType
 * Optional:
 *    DisplayName, Description, InitialValue, Required
 * </pre> <p>
 * Name should be well organized and are hierarchial,
 * as defined in the parex file. Later we will move up to
 * a hierarchial table.
 *
 * @author Jack Harich
 */
public class SettingDef {

//---------- Private Fields ------------------------------
private String    name;
private String    type;

private String    displayName;
private String    description;
private String    initialValue;
private boolean   required;
private boolean   requiredDefined;

private SettingType settingType;

//---------- Initialization ------------------------------
/**
 * Creates the instance using the param.
 */
public SettingDef(String name, Param param) {
    // Required
    this.name = name;
    type = param.getString("Type");
    
    // Optional
    displayName = param.getString("DisplayName");
    if (displayName == null) displayName = name;
    
    description = param.getString("Description");
    initialValue = param.getString("InitialValue");
    
    try { // Make assumption about Param behavior
				required = param.isTrue("Required");
				requiredDefined = true;
	  } catch(Exception ex) {
	  		// Do nothing. We will get Required from SettingType	
	  }
}
//---------- Properties ----------------------------------
//----- Required getters
public String getName() {
    return name;
}
public String getType() {
	return type;
}
//----- Optional getters
public String getDisplayName() {
    return displayName;
}
public String getDescription() {
    return description;
}// Note there's no way to have SettingType InitialValue null
public String getInitialValue() {
	if (initialValue == null) {
	  	  return settingType.getInitialValue();
	  } else {
    		return initialValue;
    }
}
public boolean isRequired() {
	return (requiredDefined ? required : settingType.isRequired());
}
//----- Other
public void setSettingType(SettingType settingType) {
    this.settingType = settingType;
}
public ColumnDef getColumnDef() {
    return settingType.getColumnDef();
}
//---------- Public Methods ------------------------------
/**
 * Validates the value. Returns null for
 * okay or a String explaining the problem.
 */
public String validate(String value) {
    return settingType.validate(value);
}    
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("SettingDef" + text);
}

} // End class
