/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package usda.weru.weps;

import java.beans.PropertyVetoException;
import java.util.Date;
import javax.measure.Measurable;
import javax.measure.quantity.Duration;
import javax.measure.quantity.Length;
import javolution.text.Text;
import org.apache.log4j.Logger;
import org.jscience.geography.coordinates.LatLong;
import usda.weru.tools.propertyboilerplate.PropertyBoilerPlate;
import usda.weru.util.ExceptionEventQueue;
import usda.weru.util.PropertyStackContext;
import usda.weru.weps.location.ElevationMode;
import usda.weru.weps.location.LatLongSiteController;
import usda.weru.weps.location.Site;
import usda.weru.weps.location.Station;
import usda.weru.weps.location.StationMode;
import usda.weru.weps.location.StationModeSelectionController;

/**
 * This bean class is for transitoning away from the web of PropertyChangeEvents
 * used to set and get values with RunFileData.  This bean is also strictly typed.
 * This means that instead of using Strings for every value, the bean allows for
 * getting and setting objects.
 *
 * To simplify writing the property code, RunFileBean uses the PropertyBoilerPlate
 * annotation.  Public static String constants (used for the property names) that
 * are annotated will cause getter/setter code to be generated at compile time in
 * the RunFileBean_PropertyBoilerPlate class.
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class RunFileBean extends RunFileBean_PropertyBoilerPlate{

    @PropertyBoilerPlate(valueClass=Site.class)
    public static final String PROP_SITE = "site";

    @PropertyBoilerPlate(valueClass=ElevationMode.class, hook=true)
    public static final String PROP_ELEVATION_MODE = "elevationMode";

    @PropertyBoilerPlate(valueClass=Measurable.class, valueGenericClasses={Length.class})
    public static final String PROP_ELEVATION = "elevation";

    @PropertyBoilerPlate(valueClass=StationMode.class, hook=true)
    public static final String PROP_CLIGEN_STATION_MODE = "cligenStationMode";

    @PropertyBoilerPlate(valueClass=Station.class)
    public static final String PROP_CLIGEN_STATION = "cligenStation"; 

    @PropertyBoilerPlate(valueClass=StationMode.class, hook=true)
    public static final String PROP_WINDGEN_STATION_MODE = "windgenStationMode";

    @PropertyBoilerPlate(valueClass=Station.class)
    public static final String PROP_WINDGEN_STATION= "windgenStation";

    @PropertyBoilerPlate(valueClass=LatLong.class)
    public static final String PROP_LATLONG = "latLong";

    @PropertyBoilerPlate(valueClass=Text.class)
    public static final String PROP_NOTES= "notes";

    @PropertyBoilerPlate(valueClass=String.class)
    public static final String PROP_CLIENT_NAME= "clientName";

    @PropertyBoilerPlate(valueClass=String.class)
    public static final String PROP_CLIENT_FARM= "clientFarm";

    @PropertyBoilerPlate(valueClass=String.class)
    public static final String PROP_CLIENT_TRACT = "clientTract";

    @PropertyBoilerPlate(valueClass=String.class)
    public static final String PROP_CLIENT_FIELD= "clientField";

    @PropertyBoilerPlate(valueClass=RunMode.class)
    public static final String PROP_RUN_MODE= "runMode";

    @PropertyBoilerPlate(valueClass=Measurable.class, valueGenericClasses={Duration.class})
    public static final String PROP_ROTATION_LENGTH= "rotationLength";

    @PropertyBoilerPlate(valueClass=Integer.class)
    public static final String PROP_CYCLE_COUNT= "cycleCount";

    @PropertyBoilerPlate(valueClass=Date.class)
    public static final String PROP_SIMULATION_START_DATE= "simulationStartDate";

    @PropertyBoilerPlate(valueClass=Date.class)
    public static final String PROP_SIMULATION_END_DATE= "simulationEndDate";

    @PropertyBoilerPlate(valueClass=Integer.class)
    public static final String PROP_TIME_STEPS= "timeSteps";


    
  

    //class variables
    private static final Logger LOGGER = Logger.getLogger(RunFileBean.class);

    /**
     * Required for this to be a true Bean
     */
    public RunFileBean(){
        LatLongSiteController.install(this);
        StationModeSelectionController.install(this);
    }

    //ELEVATION
    @Override
    protected void hookElevationMode(ElevationMode oldValue, ElevationMode newValue) {
        if(oldValue != null){
            oldValue.uninstallModel(this);
        }
        if(newValue != null){
            newValue.installModel(this);
        }
    }
    //END ELEVATION

    
    //CLIGEN
    @Override
    protected void hookCligenStationMode(StationMode oldValue, StationMode newValue) {
        if(oldValue != null){
            oldValue.uninstallModel(this, StationType.Cligen);
        }
        if(newValue != null){
            newValue.installModel(this, StationType.Cligen);
        }
    }
    //END CLIGEN

    //WINDGEN
    @Override
    protected void hookWindgenStationMode(StationMode oldValue, StationMode newValue) {
        if(oldValue != null){
            oldValue.uninstallModel(this, StationType.Windgen);
        }
        if(newValue != null){
            newValue.installModel(this, StationType.Windgen);
        }
    }
    //END WINDGEN

    @Override
    protected void enterSetter(String propertyName) {
        PropertyStackContext.enter(this, propertyName);
    }

    @Override
    protected void exitSetter(String propertyName) {
        PropertyStackContext.exit(this, propertyName);
    }

    @Override
    protected void handlePropertyVeto(PropertyVetoException pve){
        if(pve instanceof Runnable){
            Runnable task = (Runnable) pve;
            ExceptionEventQueue.invokeLater(task);
        }
    }

    

    public void clear(){
        clear(false);
    }

    /**
     * The default values for the RunFile.  Used when the user creates a new RunFile
     */
    public void initilizeDefaultValues(){

    }
    

    public static enum StationType{
        Cligen("Cligen"),
        Windgen("Windgen");

        private final String c_displayName;

        private StationType(String displayName) {
            c_displayName = displayName;
        }

        public String getDisplayName(){
            return c_displayName;
        }


    }


}
