felix@1047: package de.intevation.flys.artifacts;
felix@1047: 
felix@1047: import java.util.ArrayList;
felix@1047: import java.util.List;
felix@1047: 
felix@1047: import org.apache.log4j.Logger;
felix@1047: 
felix@1047: import org.w3c.dom.Document;
felix@1047: 
ingo@1095: import de.intevation.artifactdatabase.data.DefaultStateData;
felix@1078: import de.intevation.artifactdatabase.state.Facet;
felix@1078: import de.intevation.artifactdatabase.state.DefaultOutput;
felix@1078: import de.intevation.artifactdatabase.state.State;
felix@1078: 
felix@1065: import de.intevation.artifacts.Artifact;
felix@1047: import de.intevation.artifacts.ArtifactFactory;
felix@1047: import de.intevation.artifacts.CallMeta;
ingo@1095: 
ingo@1095: import de.intevation.flys.model.Gauge;
ingo@1095: import de.intevation.flys.model.MainValue;
ingo@1095: import de.intevation.flys.model.River;
felix@1078: 
felix@1101: import de.intevation.flys.artifacts.model.Calculation;
felix@1089: import de.intevation.flys.artifacts.model.MainValuesQFacet;
felix@1085: import de.intevation.flys.artifacts.model.MainValuesWFacet;
felix@1089: import de.intevation.flys.artifacts.model.NamedDouble;
felix@1101: import de.intevation.flys.artifacts.model.WstValueTable;
felix@1101: import de.intevation.flys.artifacts.model.WstValueTableFactory;
felix@1101: 
felix@1072: import de.intevation.flys.artifacts.states.StaticState;
felix@1112: import de.intevation.flys.artifacts.resources.Resources;
felix@1101: 
ingo@1095: import de.intevation.flys.utils.FLYSUtils;
felix@1078: 
felix@1047: 
felix@1047: /**
felix@1047:  * Artifact to access names of Points Of Interest along a segment of a river.
felix@1072:  * This artifact neglects (Static)FLYSArtifacts capabilities of interaction
felix@1072:  * with the StateEngine by overriding the getState*-methods.
felix@1047:  */
felix@1047: public class MainValuesArtifact
felix@1047: extends      StaticFLYSArtifact
sascha@1059: {
felix@1047:     /** The logger for this class. */
felix@1065:     private static Logger logger = Logger.getLogger(MainValuesArtifact.class);
felix@1047: 
felix@1047:     /** The name of the artifact. */
felix@1065:     public static final String ARTIFACT_NAME = "mainvalue";
felix@1072: 
felix@1078:     /** One and only state to be in. */
felix@1078:     protected transient State state = null;
felix@1078: 
felix@1072: 
felix@1072:     /**
felix@1072:      * Trivial Constructor.
felix@1072:      */
felix@1047:     public MainValuesArtifact() {
felix@1072:         logger.debug("MainValuesArtifact.MainValuesartifact()");
felix@1047:     }
felix@1047: 
felix@1072: 
felix@1047:     /**
felix@1047:      * Gets called from factory, to set things up.
felix@1047:      */
felix@1047:     @Override
felix@1047:     public void setup(
felix@1047:         String          identifier,
felix@1047:         ArtifactFactory factory,
felix@1047:         Object          context,
felix@1047:         CallMeta        callMeta,
felix@1047:         Document        data)
felix@1047:     {
felix@1072:         logger.debug("MainValuesArtifact.setup");
felix@1112:         state = new StaticState("state.mainvalue.static", "state.mainvalue.static");
felix@1112:         List<Facet> fs = new ArrayList<Facet>();
felix@1112:         Facet qfacet = new MainValuesQFacet(Resources.getMsg(callMeta,
felix@1112:                    "facet.discharge_curves.mainvalues.q",
felix@1112:                    "facet.discharge_curves.mainvalues.q"));
felix@1112:         Facet wfacet = new MainValuesWFacet(Resources.getMsg(callMeta,
felix@1112:                    "facet.discharge_curves.mainvalues.w",
felix@1112:                    "facet.discharge_curves.mainvalues.w"));
felix@1112:         fs.add(qfacet);
felix@1112:         fs.add(wfacet);
felix@1112:         facets.put(state.getID(), fs);
felix@1112:         spawnState();
felix@1072:         super.setup(identifier, factory, context, callMeta, data);
felix@1080:     }
felix@1080: 
felix@1112:     protected State spawnState() {
felix@1112:         state = new StaticState("state.mainvalue.static", "state.mainvalue.static");
felix@1112:         List<Facet> fs = (List<Facet>) facets.get("state.mainvalue.static");
felix@1112:         DefaultOutput mainValuesOutput2 = new DefaultOutput(
felix@1112:                     "computed_discharge_curve",
felix@1112:                     "output.computed_discharge_curve", "image/png",
felix@1112:                     fs,
felix@1112:                     "chart");
felix@1112: 
felix@1112:         state.getOutputs().add(mainValuesOutput2);
felix@1112:         return state;
felix@1112:     }
felix@1112: 
felix@1080: 
felix@1080:     @Override
felix@1080:     protected void initialize(Artifact artifact, Object context, CallMeta meta) {
felix@1080:         logger.debug("MainValuesArtifact.initialize");
felix@1080:         WINFOArtifact winfo = (WINFOArtifact) artifact;
ingo@1095:         double location = FLYSUtils.getLocations(winfo)[0];
felix@1085:         addData("location", new DefaultStateData("location", null, null,
felix@1085:                     String.valueOf(location)));
felix@1085:         addData("river", winfo.getData("river"));
felix@1047:     }
felix@1047: 
felix@1047: 
felix@1047:     /**
felix@1072:      * Get a list containing the one and only State.
felix@1085:      * @param  context ignored.
felix@1072:      * @return list with one and only state.
felix@1047:      */
felix@1072:     @Override
felix@1072:     protected List<State> getStates(Object context) {
felix@1072:         ArrayList<State> states = new ArrayList<State>();
felix@1112:         states.add(getState());
felix@1072:         return states;
felix@1072:     }
felix@1047: 
felix@1047: 
felix@1072:     /**
felix@1072:      * Get the "current" state.
felix@1072:      * @param cc ignored.
felix@1072:      * @return the "current" state.
felix@1072:      */
felix@1072:     @Override
felix@1072:     protected State getCurrentState(Object cc) {
felix@1072:         return getState();
felix@1072:     }
felix@1072: 
felix@1072: 
felix@1072:     /**
felix@1072:      * Get the only possible state.
felix@1072:      * @return the state.
felix@1072:      */
felix@1072:     protected State getState() {
felix@1072:         return getState(null, null);
felix@1072:     }
felix@1072: 
felix@1072: 
felix@1072:     /**
felix@1072:      * Get the state.
felix@1072:      * @param context ignored.
felix@1072:      * @param stateID ignored.
felix@1072:      * @return the state.
felix@1072:      */
felix@1072:     @Override
felix@1072:     protected State getState(Object context, String stateID) {
felix@1112:         if (state != null)
felix@1112:             return state;
felix@1112:         else
felix@1112:             return spawnState();
felix@1078:     }
felix@1078: 
felix@1093: 
felix@1085:     /**
felix@1089:      * Access the Gauge that the mainvalues are taken from.
felix@1089:      * @return Gauge that main values are taken from or null in case of
felix@1089:      *         invalid parameterization.
felix@1089:      */
felix@1085:     protected Gauge getGauge() {
felix@1100:         River river = FLYSUtils.getRiver(this);
felix@1065: 
felix@1085:         if (river == null) {
felix@1085:             return null;
felix@1072:         }
felix@1065: 
felix@1085:         double location = Double.parseDouble(
felix@1100:                 getDataAsString("location"));
felix@1079: 
felix@1085:         return river.determineGaugeByPosition(location);
felix@1085:     }
felix@1085: 
felix@1089: 
felix@1089:     /**
felix@1101:      * Get current location.
felix@1101:      * @return the location.
felix@1089:      */
felix@1101:     public double getLocation() {
felix@1101:         double location = Double.parseDouble(
felix@1101:                 (String)getData("location").getValue());
felix@1101:         return location;
felix@1089:     }
felix@1089: 
felix@1089: 
felix@1089:     /**
felix@1089:      * Get a list of "Q" main values.
felix@1089:      * @return list of Q main values.
felix@1089:      */
felix@1089:     public List<NamedDouble> getMainValuesQ() {
felix@1089:         List<NamedDouble> filteredList = new ArrayList<NamedDouble>();
felix@1085:         Gauge gauge = getGauge();
felix@1101:         WstValueTable interpolator = WstValueTableFactory.getTable(FLYSUtils.getRiver(this));
felix@1101:         Calculation c = new Calculation();
felix@1101:         double w_out[] = {0.0f};
felix@1101:         double q_out[] = {0.0f};
felix@1101:         double kms[] = {getLocation()};
felix@1101:         double gaugeStation = gauge.getStation().doubleValue();
felix@1085:         if (gauge != null) {
felix@1085:             List<MainValue> orig = gauge.getMainValues();
felix@1085:             for (MainValue mv : orig) {
felix@1085:                 if (mv.getMainValue().getType().getName().equals("Q")) {
felix@1101:                     interpolator.interpolate(mv.getValue().doubleValue(),
felix@1101:                             gaugeStation, kms, w_out, q_out, c);
felix@1089:                     filteredList.add(new NamedDouble(
felix@1089:                                 mv.getMainValue().getName(),
felix@1101:                                 q_out[0]
felix@1089:                                 ));
felix@1085:                 }
felix@1085:             }
felix@1065:         }
felix@1085:         return filteredList;
felix@1085:     }
felix@1085: 
felix@1089: 
felix@1089:     /**
felix@1089:      * Get a list of "W" main values.
felix@1089:      * @return list of W main values.
felix@1089:      */
felix@1089:     public List<NamedDouble> getMainValuesW() {
felix@1089:         List<NamedDouble> filteredList = new ArrayList<NamedDouble>();
felix@1085:         Gauge gauge = getGauge();
felix@1101:         WstValueTable interpolator = WstValueTableFactory.getTable(FLYSUtils.getRiver(this));
felix@1101:         Calculation c = new Calculation();
felix@1101:         double gaugeStation = gauge.getStation().doubleValue();
felix@1101:         double w_out[] = {0.0f};
felix@1101:         double q_out[] = {0.0f};
felix@1101:         double kms[] = {getLocation()};
felix@1085:         if (gauge != null) {
felix@1085:             List<MainValue> orig = gauge.getMainValues();
felix@1085:             for (MainValue mv : orig) {
felix@1101:                 // We cannot interpolate the W values, so derive them
felix@1101:                 // from given Q values.
felix@1101:                 if (mv.getMainValue().getType().getName().equals("Q")) {
felix@1101:                     interpolator.interpolate(mv.getValue().doubleValue(),
felix@1101:                             gaugeStation, kms, w_out, q_out, c);
felix@1089:                     filteredList.add(new NamedDouble(
felix@1101:                                 "W(" + mv.getMainValue().getName() +")",
felix@1101:                                 w_out[0]
felix@1089:                                 ));
felix@1085:                 }
felix@1085:             }
felix@1065:         }
felix@1085:         return filteredList;
felix@1065:     }
felix@1047: }