/**************************************************************

meandark.c (C-Munipack project)
Master-dark computation
Copyright (C) 2003 David Motl, dmotl@volny.cz

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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

**************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef _WIN32
#include <io.h>
#endif

#include "cmunipack.h"
#include "cmdline.h"
#include "cfgfile.h"
#include "utils.h"

/* Program */
AppName prog = 
{ 
	"meandark", 
	"utility for computing master-dark frames"
};

/* Options */
CmdOption opt[] =
{
	{ "configuration-file", 'p', "read parameters from configuration file", "filepath", CMD_PTYPE_FILEPATH },
	{ "set", 's', "set configuration parameter", "name=value", CMD_PTYPE_PARAMLIST },
	{ "read-dirfile", 'i', "read list of source CCD frames from specified file", "filepath", CMD_PTYPE_FILEPATH },
	{ "help", 'h', "print list of command-line parameters" },
	{ "quiet", 'q', "quiet mode; suppress all messages" },
	{ "version", 0, "print software version" },
	{ "licence", 0, "print software licence" },
	{ "verbose", 0, "verbose mode; print debug messages" },
	{ NULL }
};

/* Input files */
CmdParam flist[] = 
{
	{ "output-file", "output file name", CMD_PTYPE_FILEPATH },
	{ "files", "names of source CCD frames", CMD_PTYPE_FILELIST },
	{ NULL }
};

/* Configuration parameters */
CfgParam cfg[] = 
{
	{ "bitpix", CFG_PTYPE_INT, "output data format (0=Auto)" },
	{ "scalable", CFG_PTYPE_INT, "make scalable dark-frame (0=No, 1=Yes)" },
	{ NULL }
};

/* Command-line definition */
AppInfo cmd = 
{ 
	&prog, opt, flist, cfg
};

static void error(int status, const char *file)
{
	PrintError(&cmd, file, 0, status);
	exit(status);
}

static int mdark(CmpackMasterDark *lc, const char *srcpath)
{
	int res;
	CmpackCcdFile *ccd;

	printf("%s\n", srcpath);
	res = cmpack_ccd_open(&ccd, srcpath, CMPACK_OPEN_READONLY, 0);
	if (res!=0) {
		error(res, srcpath);
		return res;
	}
	res = cmpack_mdark_read(lc, ccd);
	cmpack_ccd_destroy(ccd);
	if (res!=0) {
		error(res, srcpath);
		return res;
	}
	return 0;
}

int main(int argc, char **argv)
{
	FILE	*din = NULL;
	int		i, bitpix, scalable, res, count, in_files = 0;
	char 	line[MAXLINE], buf1[MAXLINE];
	char	*dirfile_in, *output, *cfgfile, **files;
	CmpackMasterDark *lc;
	CmpackConsole *con;
	CmpackCcdFile *file;

	Init(&cmd);

	/* Parse command line */
	if (!cmdline_parse(argc, argv, &cmd)) {
		Clean(&cmd);
		return CMPACK_ERR_CMDLINE_ERROR;
	}

	/* Process standard options */
	if (cmdline_isdef(&cmd, "version")) {
		PrintVersion(&cmd);
		Clean(&cmd);
		return 0;
	}
	if (cmdline_isdef(&cmd, "licence")) {
		PrintLicense(&cmd);
		Clean(&cmd);
		return 0;
	}
	if (cmdline_isdef(&cmd, "help")) {
		PrintHelp(&cmd);
		Clean(&cmd);
		return 0;
	}

	/* Print program info */
	PrintPrologue(&cmd);

	lc = cmpack_mdark_init();

	/* Set callback function and output level */
	con = cmpack_con_init();
	if (cmdline_isdef(&cmd, "quiet")) 
		cmpack_con_set_level(con, CMPACK_LEVEL_QUIET);
	if (cmdline_isdef(&cmd, "verbose"))
		cmpack_con_set_level(con, CMPACK_LEVEL_DEBUG);
	cmpack_mdark_set_console(lc, con);

	/* Read configuration file */
	if (cmdline_gets(&cmd, "configuration-file", &cfgfile)) {
		res = cfgfile_read(&cmd, cfgfile);
		if (res!=0) error(res, NULL);
	}

	/* Set configuration paremeters */
	if (cfgfile_geti(&cmd, "bitpix", &bitpix))
		cmpack_mdark_set_bitpix(lc, bitpix);
	if (cfgfile_geti(&cmd, "scalable", &scalable))
		cmpack_mdark_set_scalable(lc, scalable);
	
	/* Open output file */
	if (!cmdline_getpars(&cmd, "output-file", &output))
		error(CMPACK_ERR_NO_OUTPUT_FILE, NULL);
	if (!CheckFilePath(output))
		error(CMPACK_ERR_INVALID_OUT_FILE, NULL);
	res = cmpack_ccd_open(&file, output, CMPACK_OPEN_CREATE, 0);
	if (res) error(res, output);
	res = cmpack_mdark_open(lc, file);
	if (res) error(res, output);
	cmpack_ccd_destroy(file);

	if (cmdline_gets(&cmd, "read-dirfile", &dirfile_in)) {
		/* Image names are read from a file */
		if (strcmp(dirfile_in, "@")==0) {
			din = stdin;
		} else {
			din = fopen(dirfile_in, "r");
			if (din==NULL) error(CMPACK_ERR_CANT_OPEN_DIRFILE, dirfile_in);
		}
		while (fgets(buf1, MAXLINE, din)) {
			sscanf(buf1, "%1023s", line);
			if (CheckFilePath(line)) {
				in_files++;
				mdark(lc, line);
			}
		}
		if (din && din!=stdin)
			fclose(din);
	} else {
		/* images names are given through the command line */
		if (cmdline_getparsv(&cmd, "files", &files, &count)) {
			for (i=0; i<count; i++) {
				if (CheckFilePath(files[i])) {
#ifdef _WIN32
					struct _finddata_t fd;
					intptr_t fh = _findfirst(files[i], &fd);
					if (fh!=-1) {
						do {
							if ((fd.attrib & _A_SUBDIR)==0)  {
								in_files++;
								MakeInputName(line, MAXLINE, files[i], fd.name);
								mdark(lc, line);
							}
						} while (_findnext(fh, &fd)==0);
						_findclose(fh);
					}
#else
					in_files++;
					mdark(lc, files[i]);
#endif
				}
			}
		}
	}

	/* Close output file */
	res = cmpack_mdark_close(lc);
	if (res!=0) error(res, output);

	PrintEpilogue(&cmd, in_files);

	cmpack_mdark_destroy(lc);
	cmpack_con_destroy(con);
	Clean(&cmd);

	return 0;
}
