/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.financial.analytics.timeseries.sampling;

import java.util.ArrayList;
import java.util.List;

import javax.time.calendar.LocalDate;

import org.apache.commons.lang.Validate;

import com.opengamma.util.timeseries.DoubleTimeSeries;
import com.opengamma.util.timeseries.localdate.ArrayLocalDateDoubleTimeSeries;
import com.opengamma.util.timeseries.localdate.LocalDateDoubleTimeSeries;

/**
 * Pad with previous value, pad with first value in series if there is insufficient data
 */
public class PreviousAndFirstValuePaddingTimeSeriesSamplingFunction implements TimeSeriesSamplingFunction {

  @Override
  public DoubleTimeSeries<?> getSampledTimeSeries(final DoubleTimeSeries<?> ts, final LocalDate[] schedule) {
    Validate.notNull(ts, "time series");
    Validate.notNull(schedule, "schedule");
    final LocalDateDoubleTimeSeries localDateTS = ts.toLocalDateDoubleTimeSeries();
    final List<LocalDate> tsDates = localDateTS.times();
    double[] values = localDateTS.valuesArrayFast();
    
    
    final List<LocalDate> scheduledDates = new ArrayList<LocalDate>(schedule.length);
    final List<Double> scheduledData = new ArrayList<Double>(schedule.length);
    
    int j = 0;
    for (int i = 0; i < schedule.length; i++) {
      LocalDate localDate = schedule[i];
      scheduledDates.add(localDate);
      
      if (j < tsDates.size()) { //TODO break out
        if (tsDates.get(j).equals(localDate)) {
          scheduledData.add(values[j]);
          j++;
          continue;
        }
        while (j < tsDates.size() && tsDates.get(j).isBefore(localDate)) {
          j++;
        }
        if (j < tsDates.size() && tsDates.get(j).equals(localDate)) {
          scheduledData.add(values[j]);
          j++;
          continue;
        }
      }
      if (j > 0) {
        scheduledData.add(values[j - 1]); //Should never go too high
      } else {
        scheduledData.add(values[0]);
      }
    }
    
    return new ArrayLocalDateDoubleTimeSeries(scheduledDates, scheduledData);
  }
}

@@ -199,60 +199,8 @@
 g;%0A%0A
-import java.util.ArrayList;%0Aimport java.util.List;%0A%0A
 impo
@@ -984,37 +984,32 @@
 es();%0A    final 
-List%3C
 LocalDate%3E tsDat
@@ -1001,17 +1001,18 @@
 ocalDate
-%3E
+%5B%5D
  tsDates
@@ -1031,24 +1031,29 @@
 TS.times
+Array
 ();%0A    
 double%5B%5D
@@ -1044,16 +1044,22 @@
 ();%0A    
+final 
 double%5B%5D
@@ -1104,21 +1104,16 @@
 );%0A    %0A
-    %0A
     fina
@@ -1118,106 +1118,16 @@
 nal 
-List%3CLocalDate%3E scheduledDates = new ArrayList%3CLocalDate%3E(schedule.length);%0A    final List%3CD
+d
 ouble
-%3E
+%5B%5D
  sch
@@ -1147,26 +1147,15 @@
 new 
-ArrayList%3CD
+d
 ouble
-%3E(
+%5B
 sche
@@ -1165,17 +1165,17 @@
 e.length
-)
+%5D
 ;%0A    %0A 
@@ -1281,52 +1281,8 @@
 i%5D;%0A
-      scheduledDates.add(localDate);%0A      %0A
     
@@ -1299,22 +1299,22 @@
 tsDates.
-size()
+length
 ) %7B //TO
@@ -1341,31 +1341,27 @@
  if (tsDates
-.get(j)
+%5Bj%5D
 .equals(loca
@@ -1385,37 +1385,38 @@
    scheduledData
-.add(
+%5Bi%5D = 
 values%5Bj%5D);%0A    
@@ -1400,33 +1400,32 @@
 a%5Bi%5D = values%5Bj%5D
-)
 ;%0A          j++;
@@ -1474,38 +1474,38 @@
 le (j %3C tsDates.
-size()
+length
  && tsDates.get(
@@ -1499,23 +1499,19 @@
  tsDates
-.get(j)
+%5Bj%5D
 .isBefor
@@ -1579,14 +1579,14 @@
 tes.
-size()
+length
  && 
@@ -1596,15 +1596,11 @@
 ates
-.get(j)
+%5Bj%5D
 .equ
@@ -1632,37 +1632,38 @@
    scheduledData
-.add(
+%5Bi%5D = 
 values%5Bj%5D);%0A    
@@ -1655,17 +1655,16 @@
 alues%5Bj%5D
-)
 ;%0A      
@@ -1746,29 +1746,30 @@
 cheduledData
-.add(
+%5Bi%5D = 
 values%5Bj - 1
@@ -1769,17 +1769,16 @@
 s%5Bj - 1%5D
-)
 ; //Shou
@@ -1838,13 +1838,14 @@
 Data
-.add(
+%5Bi%5D = 
 valu
@@ -1849,17 +1849,16 @@
 alues%5B0%5D
-)
 ;%0A      
@@ -1928,14 +1928,8 @@
 dule
-dDates
 , sc

Use arrrays to generate less garbage and do less busywork