package org.jcon.param.util;

import org.jcon.param.Param;
import org.jcon.param.ParamAccessor;
import org.jcon.param.ParamStore;
import org.jcon.param.ParamStoreResource;
import java.util.Vector;

/**
 * This class configures files containing Params. If uses
 * Param files containing directives to do this.
 *
 * @author Jack Harich
 */ // java org.jcon.param.util.ConfigFiles
public class ConfigParamFiles {

//---------- Private Fields ------------------------------
private ConfigParam configParam = new ConfigParam();
private ParamStore  paramStore;

//---------- Initialization ------------------------------
/**
 * Runs the unit test for this class, using this class and
 * the command line arguments as resourceNames. If the
 * resourceNames are empty a default of "TestModDef.parex"
 * is supplied.
 */
public static void main(String resourceNames[]) {
    // Run unit test
    if (resourceNames.length == 0) {
        resourceNames = new String[] {"TestModDefs.parex"};
    }
    ConfigParamFiles test = new ConfigParamFiles();
    test.modifyResources(test, resourceNames);
}    
//---------- Properties ----------------------------------
/**
 * Sets the ParamStore to be used. If not provided a
 * ParamStoreResource is used.
 */
public void setParamStore(ParamStore paramStore) {
    this.paramStore = paramStore;
}   
public ParamStore getParamStore() {
    return paramStore;   
}
//---------- Public Methods ------------------------------
/**
 * Modifies the Param resourceNames which are located relative
 * to the markerClass. This flexible approach allows the files
 * to be located anywhere, as long as they are relative to
 * the markerClass. This avoids fixed full file names, 
 * which are not platform portable and are hard to manage.
 */
public void modifyResources(Object markerClass, String[] resourceNames) {
    if (paramStore == null) paramStore = new ParamStoreResource();
    for (int i = 0; i < resourceNames.length; i++) {
        String resourceName = resourceNames[i];
        print(" ------ Processing " + resourceName);
        modifyResource(markerClass, resourceName);
    }    
    print(" - Done. That didn't take so long, did it?");
}    
/**
 * Same as modifyResources() except just one resource.
 */
public void modifyResource(Object markerClass, String resourceName) {
    // Create modFileParam
    ParamAccessor modAcc = new ParamAccessor(markerClass, resourceName);
    Param modFileParam = paramStore.readParam(modAcc);
    
    // Create modValuesParam
    Param modValuesParam = modFileParam.getParam("ModValues");
    
    // Process each element, which is one Param to modify
    Vector mods = modFileParam.getVector("ModFiles");
    for (int i = 0; i < mods.size(); i++) {
        Param mod = (Param)mods.elementAt(i);
        processModDef(mod, modValuesParam);    
    }   
}    
//---------- Private Methods -----------------------------
private void processModDef(Param modDefParam, Param modValuesParam) {
    // Create targetParam, the file to be modified
    String markerClass = modDefParam.getString("MarkerClass");
    String resourceName = modDefParam.getString("ResourceName");
    ParamAccessor acc = new ParamAccessor(markerClass, resourceName);
    Param targetParam = paramStore.readParam(acc);
    print(" - " + markerClass + " " + resourceName);
    
    // Use each element in modFileParam to mod targetParam
    Vector modDefs = modDefParam.getVector("ModDefs");
    for (int i = 0; i < modDefs.size(); i++) {
        Param modDef = (Param)modDefs.elementAt(i);
        configParam.modifyParam(targetParam, modDef, modValuesParam);   
    }
    // Save modified targetParam 
    paramStore.writeParam(targetParam, null);   
}    
//--- Std
private static void print(String text) {
    System.out.println("ConfigParamFiles" + text);
}

} // End class
