package org.jcon.param.util;

import org.jcon.param.Param;
import org.jcon.util.DataLib;
import org.jcon.util.GenLib;
import java.util.Vector;

/**
 * This class configures a single param, given a "modDef"
 * param. Not threadsafe.
 *
 * @author Jack Harich
 */
public class ConfigParam {
    
//---------- Private Fields ------------------------------
private Param param;
private Param configDefParam;
private Param modValuesParam;
    
//---------- Public Methods ------------------------------
public void modifyParam(Param param,
        Param configDefParam, Param modValuesParam) {  
            
    this.param = param;
    this.configDefParam = configDefParam;
    this.modValuesParam = modValuesParam;             
            
    String pathType = configDefParam.getString("PathType");
    print(" - Modifying PathType " + pathType);
    
    if (pathType == "NameValue") {
        modifyNameValue();
                
    } else if (pathType == "StringVector") {
        modifyStringVector();

    } else if (pathType == "ParamVector") {
        modifyParamVector();
        
    } else {
         throw new IllegalArgumentException(
             "Unknown PathType '" + pathType + "'.");   
    }
}   
//---------- Private Methods -----------------------------
// Most common and easiest. Change the named value.
// Ignore possibility it doesn't exist, which allows us
// to add new named values.
private void modifyNameValue() {
    String name = configDefParam.getString("NamePath");
    String valueName = configDefParam.getString("NewValue");
    String value = getValue(valueName);
    param.put(name, value);
} 
// Param has StringVector. Replace occurances.
private void modifyStringVector() {
    String name = configDefParam.getString("NamePath");
    if (! param.hasProperty(name)) return;
    Vector lines = param.getVector(name);
    //if (lines == null) return;
    
    Vector replaceDefs = configDefParam.getVector("ReplaceDefs");
    for (int i = 0; i < replaceDefs.size(); i++) {
         Param replaceDefParam = (Param)replaceDefs.elementAt(i);
         modifyStringVectorValue(lines, replaceDefParam);
    }
    param.put(name, lines);
} 
private void modifyStringVectorValue(Vector lines,
        Param replaceDefParam) {
            
    String startsWith = replaceDefParam.getString("StartsWith");
    String valueName = replaceDefParam.getString("NewEnding");
    String newEnding = getValue(valueName);
    
    // Replace all occurances in lines
    // Simplistic, may improve
    for (int i = 0; i < lines.size(); i++) {
        String line = (String)lines.elementAt(i);
        //String newLine = DataLib.replaceToken(line,
        //    targetValue, newValue);
        if (line.startsWith(startsWith)) {
            String newLine = startsWith + newEnding;
            lines.setElementAt(newLine, i);            
        }
    }        
}
// Param has a Vector of Param elements. Replace occurances
// using criteria to find proper element.
// Only works for "is:" values
private void modifyParamVector() {
    String name = configDefParam.getString("NamePath");
    Vector elements = param.getVector(name);
    if (elements == null) return;
    
    Vector valueDefs = configDefParam.getVector("ValueDefs");
    for (int i = 0; i < valueDefs.size(); i++) {
         Param valueDefParam = (Param)valueDefs.elementAt(i);
         modifyParamVectorElement(elements, valueDefParam);
    }
    param.put(name, elements);
} 
private void modifyParamVectorElement(Vector elements,
        Param valueDefParam) {
    String criteriaName = valueDefParam.getString("CriteriaName");            
    String criteriaValue = valueDefParam.getString("CriteriaValue");
    for (int i = 0; i < elements.size(); i++) {
         Param param = (Param)elements.elementAt(i);
         if (param.hasProperty(criteriaName)) {
            String oldValue = param.getString(criteriaName);
            if (oldValue.equals(criteriaValue)) {
                String name = valueDefParam.getString("ReplacementName");
                String valueName = valueDefParam.getString("ReplacementValue");
                String value = getValue(valueName);
                param.put(name, value);
            }                 
         }   
    }          
}  
private String getValue(String valueName) {
    //print(" - " + valueName + " = " + modValuesParam.getString(valueName));
    return modValuesParam.getString(valueName);
}
//--- Std
private static void print(String text) {
    System.out.println("ConfigParam" + text);
}

} // End class
