felix@1085: package de.intevation.flys.artifacts.model;
felix@1085: 
ingo@1679: import java.util.ArrayList;
ingo@1679: import java.util.List;
ingo@1679: 
felix@2778: import org.apache.log4j.Logger;
felix@2778: 
felix@1085: import de.intevation.artifacts.Artifact;
felix@1085: import de.intevation.artifacts.CallContext;
felix@2778: import de.intevation.artifacts.DataProvider;
ingo@1679: 
felix@1085: import de.intevation.artifactdatabase.state.DefaultFacet;
ingo@1679: 
ingo@1679: import de.intevation.flys.artifacts.MainValuesArtifact;
felix@2778: import de.intevation.flys.artifacts.math.Linear;
ingo@1679: import de.intevation.flys.jfree.FLYSAnnotation;
ingo@1679: import de.intevation.flys.jfree.StickyAxisAnnotation;
felix@1085: 
felix@2163: import de.intevation.flys.exports.DurationCurveGenerator;
felix@2163: 
felix@2778: 
felix@1085: /**
felix@1085:  * Facet to show Main Q Values.
felix@2161:  * TODO Join with W implementation.
felix@1085:  */
felix@1085: public class MainValuesQFacet
felix@1085: extends      DefaultFacet
felix@1085: implements   FacetTypes {
felix@1085: 
felix@2778:     /** Own logger. */
sascha@3778:     private static Logger logger = Logger.getLogger(MainValuesQFacet.class);
felix@2778: 
felix@1957:     /** Do we want MainValues at Gauge (not interpolated)? */
felix@1957:     protected boolean isAtGauge;
felix@1957: 
felix@3442: 
felix@1085:     /** Trivial Constructor. */
felix@1957:     public MainValuesQFacet(String name, String description, boolean atGauge) {
felix@1112:         this.description = description;
felix@2163:         this.name        = name;
felix@2163:         this.index       = 0;
felix@2163:         this.isAtGauge   = atGauge;
felix@1085:     }
felix@1085: 
felix@3442: 
felix@2778:     /**
felix@2778:      * Set the hit-point in Q where a line drawn from the axis would hit the
felix@2778:      * curve in WQDay (if hit).
felix@2778:      * Employ linear interpolation.
felix@2778:      */
felix@2778:     protected static void setHitPoint(WQDay wqday, StickyAxisAnnotation annotation) {
felix@2778:         int idx = 0;
felix@2778:         float q = annotation.getPos();
felix@2778:         boolean qIncreases = wqday.getQ(0) < wqday.getQ(wqday.size()-1);
felix@2778:         if (qIncreases) {
felix@2778:             while (idx < wqday.size() && wqday.getQ(idx) < q) {
felix@2778:                 idx++;
felix@2778:             }
felix@2778:         }
felix@2778:         else {
felix@2778:             idx = wqday.size() -1;
felix@2778:             while (idx > 0 && wqday.getQ(idx) > q) {
felix@2778:                 idx--;
felix@2778:             }
felix@2778:         }
felix@2778: 
felix@2778:         double day = 0d;
felix@2778:         int mod = (qIncreases) ? -1 : +1;
felix@2778:         if (idx != 0 && idx <= wqday.size()-1) {
felix@2778:             day = Linear.linear(q, wqday.getQ(idx +mod), wqday.getQ(idx),
felix@2778:                 wqday.getDay(idx+mod), wqday.getDay(idx));
felix@2778:             annotation.setHitPoint((float)day);
felix@2778:         }
felix@2778:         else {
felix@2778:             logger.debug("StickyAnnotation does not hit wqday curve");
felix@2778:         }
felix@2778:     }
felix@2778: 
felix@1085: 
felix@1085:     /**
felix@1085:      * Returns the data this facet requires.
felix@1085:      *
felix@1085:      * @param artifact the owner artifact.
felix@1085:      * @param context  the CallContext (ignored).
felix@1085:      *
felix@1085:      * @return the data.
felix@1085:      */
felix@1085:     @Override
felix@1085:     public Object getData(Artifact artifact, CallContext context) {
felix@1085:         MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact;
ingo@1679: 
felix@2163:         List<NamedDouble>          qs = mvArtifact.getMainValuesQ(isAtGauge);
felix@2161:         List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
ingo@1679: 
felix@2778:         WQDay wqdays = null;
felix@2778:         List<DataProvider> providers = context.
felix@2778:             getDataProvider(DurationCurveFacet.BB_DURATIONCURVE);
felix@2778:         if (providers.size() < 1) {
felix@2778:             logger.warn("Could not find durationcurve data provider.");
felix@2778:         }
felix@2778:         else {
felix@2778:             wqdays = (WQDay) providers.get(0).provideData(
felix@2778:                 DurationCurveFacet.BB_DURATIONCURVE,
felix@2778:                 null,
felix@2778:                 context);
felix@2778:         }
felix@2778: 
felix@2163:         // Rather specific case, Q-Annotations at a maybe second yaxis.
felix@2778:         StickyAxisAnnotation annotation = null;
felix@2163:         if (this.name.equals(DURATION_MAINVALUES_Q)) {
felix@2163:             for (NamedDouble q: qs) {
felix@2778:                 annotation =
felix@2778:                     new StickyAxisAnnotation(
felix@2778:                         q.getName(),
felix@2778:                         (float) q.getValue(),
felix@2778:                         StickyAxisAnnotation.SimpleAxis.Y_AXIS,
felix@2778:                         DurationCurveGenerator.YAXIS.Q.idx);
felix@2778:                 xy.add(annotation);
felix@2778:                 if (wqdays != null) {
felix@2778:                     setHitPoint(wqdays, annotation);
felix@2778:                 }
felix@2163:             }
felix@2163:         }
felix@2163:         else {
felix@2163:             for (NamedDouble q: qs) {
felix@2778:                 annotation =
felix@2778:                     new StickyAxisAnnotation(
felix@2778:                         q.getName(),
felix@2778:                         (float) q.getValue(),
felix@2778:                         StickyAxisAnnotation.SimpleAxis.X_AXIS);
felix@2778:                 xy.add(annotation);
felix@2778:                 if (wqdays != null) {
felix@2778:                     setHitPoint(wqdays, annotation);
felix@2778:                 }
felix@2163:             }
ingo@1679:         }
ingo@1679: 
ingo@1679:         return new FLYSAnnotation(description, xy);
felix@1085:     }
felix@1085: 
felix@1085: 
felix@1085:     /**
felix@1085:      * Create a deep copy of this Facet.
felix@1085:      * @return a deep copy.
felix@1085:      */
felix@1085:     @Override
felix@1085:     public MainValuesQFacet deepCopy() {
felix@1957:         MainValuesQFacet copy = new MainValuesQFacet(this.name,
felix@1957:             description, this.isAtGauge);
felix@1085:         copy.set(this);
felix@1085:         return copy;
felix@1085:     }
felix@1085: }
felix@1809: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :