/* -*- 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) 2007-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.
 */

#include <muse.h>
#include <string.h>

/*----------------------------------------------------------------------------*/
/**
 * @defgroup tools_musefillimage            Tool muse_fill_image
 *
 * <b>muse_fill_image</b>: fill a MUSE three-extension image with constant(s).
 *
 * This is mainly for technical uses, e.g. to circumvent the need to pass
 * flat-fields to muse_scibasic by using flat-fields filled with ones and
 * minimal variance.
 *
 * <b>Command line arguments:</b>
 *   - <tt>-d datavalue</tt> (optional, default: 1.)\n
 *     constant to fill into the DATA extension of the MUSE image
 *   - <tt>-q dqvalue</tt> (optional, defaults none)\n
 *     constant to fill into the DQ extension of the MUSE image, has to be
 *     between zero and 2^31
 *     by default, the DQ extension is not touched
 *   - <tt>-s statvalue</tt> (optional, default: 0.)\n
 *     constant to fill into the STAT extension of the MUSE image, has to be
 *     non-negative
 *   - <tt><b>IMAGE_IN</b></tt>\n
 *     the filename of the image file to read
 *   - <tt><b>IMAGE_OUT</b></tt>\n
 *     the filename of the image file to write
 *
 * <b>Return values:</b>
 *   - <tt> 0</tt>\n   Success
 *   - <tt> 1</tt>\n   no filenames given
 *   - <tt> 2</tt>\n   argument <tt>-d</tt> without datavalue
 *   - <tt> 3</tt>\n   argument <tt>-q</tt> without dqvalue
 *   - <tt> 4</tt>\n   dqvalue given after <tt>-q</tt> is not valid
 *   - <tt> 5</tt>\n   argument <tt>-s</tt> without statvalue
 *   - <tt> 6</tt>\n   statvalue given after <tt>-s</tt> is negative
 *   - <tt> 9</tt>\n   unknown option given
 *   - <tt>10</tt>\n   IMAGE_IN cannot be loaded
 *   - <tt>20</tt>\n   IMAGE_OUT cannot be saved
 */
/*----------------------------------------------------------------------------*/

/**@{*/

#define PRINT_USAGE(rc)                                                        \
  fprintf(stderr, "Usage: %s [ -d datavalue ] [ -q dqvalue] [ -s statvalue ] " \
          "IMAGE_IN IMAGE_OUT\n", argv[0]);                                    \
  cpl_end(); return (rc);

int main(int argc, char **argv)
{
  cpl_init(CPL_INIT_DEFAULT);
  muse_processing_recipeinfo(NULL);

  if (argc <= 2) {
    /* filenames are needed at least */
    PRINT_USAGE(1);
  }

  char *iname = NULL, /* input image name */
       *oname = NULL; /* output image name */
  float datavalue = 1.,
        statvalue = 0.;
  /* make the dqvalue variable signed to be able to check for wrong inputs */
  cpl_size dqvalue = -1;

  /* argument processing */
  int i;
  for (i = 1; i < argc; i++) {
    if (strncmp(argv[i], "-d", 3) == 0) {
      /* skip to next arg to get datavalue */
      i++;
      if (i < argc) {
        datavalue = atof(argv[i]);
      } else {
        PRINT_USAGE(2);
      }
    } else if (strncmp(argv[i], "-q", 3) == 0) {
      /* skip to next arg to get dqvalue */
      i++;
      if (i < argc) {
        dqvalue = atoi(argv[i]);
        if (dqvalue < 0 || dqvalue > UINT_MAX) {
          PRINT_USAGE(4);
        }
      } else {
        PRINT_USAGE(3);
      }
    } else if (strncmp(argv[i], "-s", 3) == 0) {
      /* skip to next arg to get statvalue */
      i++;
      if (i < argc) {
        statvalue = atof(argv[i]);
        if (statvalue < 0) {
          PRINT_USAGE(6);
        }
      } else {
        PRINT_USAGE(5);
      }
    } else if (strncmp(argv[i], "-", 1) == 0) { /* unallowed options */
      PRINT_USAGE(9);
    } else {
      if (iname && oname) {
        break; /* we have the possible names, skip the rest */
      }
      if (!iname) {
        iname = argv[i] /* set the name for the input image */;
      } else {
        oname = argv[i] /* set the name for the output image */;
      }
    }
  } /* for i (all arguments) */

  muse_image *image = muse_image_load(iname);
  if (!image) {
    PRINT_USAGE(10);
  }
  printf("Loaded \"%s\".\n", iname);

  /* Fill the three image extensions, save the result */
  cpl_error_code rc = CPL_ERROR_NONE;
  cpl_size nx = cpl_image_get_size_x(image->data),
           ny = cpl_image_get_size_y(image->data);
  rc = cpl_image_fill_window(image->data, 1, 1, nx, ny, datavalue);
  printf("Filled DATA image with %g (rc = %d)\n", datavalue, rc);
  rc = cpl_image_fill_window(image->stat, 1, 1, nx, ny, statvalue);
  printf("Filled STAT image with %g (rc = %d)\n", statvalue, rc);
  if (dqvalue >= 0) {
    rc = cpl_image_fill_window(image->dq, 1, 1, nx, ny, dqvalue);
    printf("Filled DQ image with %u (rc = %d)\n", (unsigned int)dqvalue, rc);
  }
  if (!cpl_propertylist_has(image->header, "BUNIT")) {
    cpl_propertylist_append_string(image->header, "BUNIT", "count");
  }
  rc = muse_image_save(image, oname);

  if (rc != CPL_ERROR_NONE) {
    fprintf(stderr, "Some error occurred while saving to \"%s\" "
            "(rc = %d, %s)\n", oname, rc, cpl_error_get_message());
    rc = 20;
  } else {
    printf("Saved to \"%s\".\n", oname);
  }
  muse_image_delete(image);
  cpl_end();
  return rc;
}

/**@}*/
