/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set sw=2 sts=2 et cin: */
/*
 * This file is part of the MUSE Instrument Pipeline
 * Copyright (C) 2009-2014 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>

#include <muse.h>

cpl_error_code
eval(void *aData, cpl_array *aPar, cpl_array *aRetval) {
  cpl_table *t = aData;
  int nrow = cpl_table_get_nrow(t);
  cpl_array *lambda = muse_cpltable_extract_column(t, "lambda");
  cpl_array *data = muse_cpltable_extract_column(t, "data");
  cpl_array_fill_window(aRetval, 0, nrow, 0.0);
  cpl_array_add(aRetval, lambda);
  muse_cplarray_poly1d(aRetval, aPar);
  cpl_array_subtract(aRetval, data);
  cpl_array_unwrap(lambda);
  cpl_array_unwrap(data);
  return CPL_ERROR_NONE;
}


/*----------------------------------------------------------------------------*/
/**
   @brief test program to check that all the functionmuse_cpl_optimize_lvmq()
   works OK.
 */
/*----------------------------------------------------------------------------*/
int main(int argc, char **argv) {
  UNUSED_ARGUMENTS(argc, argv);
  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_DEBUG);
  
  cpl_error_reset();
  cpl_msg_set_component_on();
  
  muse_cpltable_def def[] = {
    { "lambda", CPL_TYPE_DOUBLE, "Angstrom", "%.1f", NULL, CPL_TRUE  },
    { "data", CPL_TYPE_DOUBLE, NULL, "%3.0f", NULL, CPL_TRUE  },
    { "function", CPL_TYPE_DOUBLE, NULL, "%3.0f", NULL, CPL_TRUE  },
    { NULL, 0, NULL, NULL, NULL, CPL_FALSE  }
  };

  cpl_table *t = muse_cpltable_new(def, 5);
  cpl_table_set(t, "lambda", 0, 4500.);
  cpl_table_set(t, "data", 0, 100.);
  cpl_table_set(t, "lambda", 1, 4800.);
  cpl_table_set(t, "data", 1, 120.);
  cpl_table_set(t, "lambda", 2, 5200.);
  cpl_table_set(t, "data", 2, 150.);
  cpl_table_set(t, "lambda", 3, 5500.);
  cpl_table_set(t, "data", 3, 130.);
  cpl_table_set(t, "lambda", 4, 5800.);
  cpl_table_set(t, "data", 4, 115.);

  cpl_array *p = cpl_array_new(3, CPL_TYPE_DOUBLE);
  cpl_array_set(p, 0, 0.0);
  cpl_array_set(p, 1, 0.0);
  cpl_array_set(p, 2, 130.0);

  cpl_error_code r = muse_cpl_optimize_lvmq(t, p, cpl_table_get_nrow(t), eval,
                                            NULL);

  cpl_msg_debug(__func__, "r=%i", r);
  cpl_array *lambda = muse_cpltable_extract_column(t, "lambda");
  cpl_table_fill_column_window(t, "function", 0, 5, 0.0);
  cpl_array *function = muse_cpltable_extract_column(t, "function");
  cpl_array_add(function, lambda);
  muse_cplarray_poly1d(function, p);
  cpl_array_unwrap(function);
  cpl_array_unwrap(lambda);
  cpl_table_dump(t, 0, 5, NULL);

  cpl_table_delete(t);
  cpl_array_delete(p);
  return cpl_test_end(0);
}
