package org.csstudio.trends.databrowser.model;

import org.csstudio.archive.util.TimestampUtil;
import org.csstudio.platform.util.ITimestamp;
import org.csstudio.swt.chart.ChartSampleSearch;

/** Helper for merging archived samples.
 *  @author Kay Kasemir
 */
public class ModelSampleMerger
{
    /** Merge samples to 'add' into 'old' list of samples.
     *  <p>
     *  Any overlap gets resolved in favor of the new samples.
     *  @param old Existing list of samples.
     *  @param add New samples to add.
     *  @return The merged samples.
     *          Typically, that is the modified 'old' array,
     *          but it could also be the 'add' array, in case that
     *          completely replaces the old samples.
     */
    @SuppressWarnings("nls")
    static ModelSampleArray merge(ModelSampleArray old,
                    ModelSampleArray add)
    {   // If one is empty, return the other as is:
        if (old == null  ||  old.size() <= 0)
            return add;
        if (add == null  ||  add.size() <= 0)
            return old;
        // Both lists have at least one sample.
        // Determine start/end times.
        ITimestamp old_start = TimestampUtil.fromDouble(old.get(0).getX());
        ITimestamp old_end = TimestampUtil.fromDouble(old.get(old.size()-1).getX());
        ITimestamp add_start = TimestampUtil.fromDouble(add.get(0).getX());
        ITimestamp add_end = TimestampUtil.fromDouble(add.get(add.size()-1).getX());

        /*
        System.out.print("Have samples " + old_start.toString());
        System.out.print(" to " + old_end.toString());
        System.out.println(" (" + old.size() + ")");

        System.out.print("New Samples  " + add_start.toString());
        System.out.print(" to " + add_end.toString());
        System.out.println(" (" + add.size() + ")");
         */
        
        // Assume old samples are this:  +=============+
        // new samples could be
        // Before    +--------+,
        if (add_end.isLessOrEqual(old_start))
        {
            ModelSampleArray result =
                new ModelSampleArray(add.size() + old.size());
            // result.addAll(add);
            int N = add.size();
            for (int i=0; i<N; ++i)
                result.add(add.get(i));            
            // result.addAll(old);
            N = old.size();
            for (int i=0; i<N; ++i)
                result.add(old.get(i));
            return result;
        }
        //                               +=============+
        // after existing sample                        +--------+,
        if (add_start.isGreaterOrEqual(old_end))
        {
            ModelSampleArray result =
                new ModelSampleArray(old.size() + add.size());
            // result.addAll(old);
            int N = old.size();
            for (int i=0; i<N; ++i)
                result.add(old.get(i));
            // result.addAll(add);
            N = add.size();
            for (int i=0; i<N; ++i)
                result.add(add.get(i));
            return result;
        }
        //                               +=x===========+
        // before with overlap    +--------+
        if (add_start.isLessOrEqual(old_start) &&
            add_end.isGreaterOrEqual(old_start) &&
            add_end.isLessOrEqual(old_end))
        {
            // Determine the first sample to use from the old list
            int x = ChartSampleSearch.findSampleGreaterOrEqual(old, add_end.toDouble());
            
            ModelSampleArray result =
                new ModelSampleArray(add.size() + old.size()-x);
            // result.addAll(add);
            int N = add.size();
            for (int i=0; i<N; ++i)
                result.add(add.get(i));
            // result.addAll(old[x, ... N-1]);
            N = old.size();
            for (int i=x; i<N; ++i)
                result.add(old.get(i));
            return result;
        }
        //                               +=========x===+
        // after with overlap                      +--------+
        if (add_start.isGreaterOrEqual(old_start) &&
            add_start.isLessOrEqual(old_end) &&
            add_end.isGreaterOrEqual(old_end))
        {
            // Determine the last sample to use from the old list
            int x = ChartSampleSearch.findSampleGreaterOrEqual(old, add_start.toDouble());
            ModelSampleArray result = new ModelSampleArray(x + add.size());
            // result.addAll(old[0 ... x-1]);
            for (int i=0; i<x; ++i)
                result.add(old.get(i));
            // result.addAll(add);
            int N = add.size();
            for (int i=0; i<N; ++i)
                result.add(add.get(i));
            return result;
        }
        //                               +===l=====r===+
        // within                            +-----+
        if (add_start.isGreaterOrEqual(old_start) &&
            add_end.isLessOrEqual(old_end))
        {
            // Determine the left/right indices of the section within 'old'.
            int l = ChartSampleSearch.findSampleLessOrEqual(old, add_start.toDouble());
            int r = ChartSampleSearch.findSampleGreaterOrEqual(old, add_end.toDouble());
            ModelSampleArray result =
                new ModelSampleArray(l+1 + add.size() + old.size()-r);
            // result.addAll(old[0 ... l]);
            for (int i=0; i<=l; ++i)
                result.add(old.get(i));
            // result.addAll(add);
            int N = add.size();
            for (int i=0; i<N; ++i)
                result.add(add.get(i));
            // result.addAll(old[r ... N-1]);
            N = old.size();
            for (int i=r; i<N; ++i)
                result.add(old.get(i));
            return result;
        }
        //                               +=============+
        // complete replacement    +------------------------+
        if (add_start.isLessOrEqual(old_start) &&
            add_end.isGreaterOrEqual(old_end))
            return add;

        throw new Error("Cannot handle this case");
    }
}

@@ -45,56 +45,8 @@
 l;%0A%0A
-import org.csstudio.archive.util.TimestampUtil;%0A
 impo
@@ -1122,50 +1122,39 @@
 t = 
-TimestampUtil.fromDouble(old.get(0).getX()
+old.get(0).getSample().getTime(
 );%0A 
@@ -1185,33 +1185,8 @@
 d = 
-TimestampUtil.fromDouble(
 old.
@@ -1202,27 +1202,41 @@
 ize()-1).get
-X()
+Sample().getTime(
 );%0A        I
@@ -1261,50 +1261,39 @@
 t = 
-TimestampUtil.fromDouble(add.get(0).getX()
+add.get(0).getSample().getTime(
 );%0A 
@@ -1324,33 +1324,8 @@
 d = 
-TimestampUtil.fromDouble(
 add.
@@ -1349,11 +1349,25 @@
 .get
-X()
+Sample().getTime(
 );%0A%0A

Operate on Timestamp, not 'X'