Index: trunk/ippTools/src/Makefile.am
===================================================================
--- trunk/ippTools/src/Makefile.am	(revision 15577)
+++ trunk/ippTools/src/Makefile.am	(revision 15578)
@@ -6,13 +6,14 @@
 	dettool \
 	difftool \
+	flatcorr \
 	magictool \
 	pxadmin \
 	pxinject \
 	pzgetexp \
+	pzgetimfiles \
+	pztool \
 	regtool \
 	stacktool \
-	warptool \
-	pzgetimfiles \
-	pztool
+	warptool
 
 bin_SCRIPTS = \
@@ -20,32 +21,33 @@
 
 pkginclude_HEADERS = \
-	pxtoolsErrorCodes.h \
 	pxadmin.h \
+	pxcam.h \
+	pxchip.h \
+	pxconfig.h \
 	pxdata.h \
 	pxio.h \
+	pxregister.h \
 	pxtag.h \
-	pxregister.h \
-	pxchip.h \
-	pxcam.h \
-	pxconfig.h \
-	pxtree.h \
-	pxtools.h
+	pxtools.h \
+	pxtoolsErrorCodes.h \
+	pxtree.h 
 
 noinst_HEADERS = \
+	caltool.h \
 	camtool.h \
-	caltool.h \
 	chiptool.h \
 	detselect.h \
 	dettool.h \
 	difftool.h \
+	flatcorr.h \
 	guidetool.h \
 	magictool.h \
 	pxinject.h \
+	pzgetexp.h \
+	pzgetimfiles.h \
+	pztool.h \
 	regtool.h \
 	stacktool.h \
-	warptool.h \
-	pzgetexp.h \
-	pzgetimfiles.h \
-	pztool.h 
+	warptool.h
 
 lib_LTLIBRARIES = libpxtools.la
@@ -81,4 +83,10 @@
     caltool.c \
     caltoolConfig.c
+
+flatcorr_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(IPPDB_CFLAGS)
+flatcorr_LDADD = $(PSLIB_LIBS) $(PSMODULES_LIBS) $(IPPDB_LIBS) libpxtools.la
+flatcorr_SOURCES = \
+    flatcorr.c \
+    flatcorrConfig.c
 
 regtool_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(IPPDB_CFLAGS)
Index: trunk/ippTools/src/flatcorr.c
===================================================================
--- trunk/ippTools/src/flatcorr.c	(revision 15578)
+++ trunk/ippTools/src/flatcorr.c	(revision 15578)
@@ -0,0 +1,100 @@
+/*
+ * flatcorr.c
+ *
+ * Copyright (C) 2006-2007  Joshua Hoblitt
+ *
+ * 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; version 2 of the License.
+ *
+ * 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
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVB_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <ippdb.h>
+
+#include "pxtools.h"
+#include "flatcorr.h"
+
+static bool newrunMode(pxConfig *config);
+static bool pendingMode(pxConfig *config);
+static bool updateMode(pxConfig *config);
+
+# define MODECASE(caseName, func) \
+    case caseName: \
+    if (!func(config)) { \
+        goto FAIL; \
+    } \
+    break;
+
+int main(int argc, char **argv)
+{
+    psLibInit(NULL);
+
+    pxConfig *config = flatcorrConfig(NULL, argc, argv);
+    if (!config) {
+        psError(PXTOOLS_ERR_CONFIG, false, "failed to configure");
+        goto FAIL;
+    }
+
+    switch (config->mode) {
+        MODECASE(FLATCORR_MODE_NEWRUN,      newrunMode);
+        MODECASE(FLATCORR_MODE_PENDING,     pendingMode);
+        MODECASE(FLATCORR_MODE_UPDATE,      updateMode);
+        default:
+            psAbort("invalid option (this should not happen)");
+    }
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(EXIT_SUCCESS);
+
+FAIL:
+    psErrorStackPrint(stderr, "\n");
+    int exit_status = pxerrorGetExitStatus();
+
+    psFree(config);
+    pmConfigDone();
+    psLibFinalize();
+
+    exit(exit_status);
+}
+
+static bool newrunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    return false;
+}
+
+static bool pendingMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    return false;
+}
+
+static bool updateMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    return false;
+}
Index: trunk/ippTools/src/flatcorr.h
===================================================================
--- trunk/ippTools/src/flatcorr.h	(revision 15578)
+++ trunk/ippTools/src/flatcorr.h	(revision 15578)
@@ -0,0 +1,34 @@
+/*
+ * flatcorr.h
+ *
+ * Copyright (C) 2006-2007  Joshua Hoblitt
+ *
+ * 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; version 2 of the License.
+ *
+ * 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
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef FLATCORR_H
+#define FLATCORR_H 1
+
+#include "pxtools.h"
+
+typedef enum {
+    FLATCORR_MODE_NONE           = PXTOOL_MODE_NONE,
+    FLATCORR_MODE_NEWRUN,
+    FLATCORR_MODE_PENDING,
+    FLATCORR_MODE_UPDATE
+} flatcorrMode;
+
+pxConfig *flatcorrConfig(pxConfig *config, int argc, char **argv);
+
+#endif // FLATCORR_H
Index: trunk/ippTools/src/flatcorrConfig.c
===================================================================
--- trunk/ippTools/src/flatcorrConfig.c	(revision 15578)
+++ trunk/ippTools/src/flatcorrConfig.c	(revision 15578)
@@ -0,0 +1,148 @@
+/*
+ * flatcorrConfig.c
+ *
+ * Copyright (C) 2006-2007  Joshua Hoblitt
+ *
+ * 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; version 2 of the License.
+ *
+ * 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
+ * program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <psmodules.h>
+
+#include "pxtools.h"
+#include "flatcorr.h"
+
+pxConfig *flatcorrConfig(pxConfig *config, int argc, char **argv)
+{
+    if (!config) {
+        config = pxConfigAlloc();
+    }
+
+    pmConfigReadParamsSet(false);
+
+    // setup site config
+    config->modules = pmConfigRead(&argc, argv, NULL);
+    if (!config->modules) {
+        psError(PS_ERR_UNKNOWN, false, "Can't find site configuration");
+        psFree(config);
+        return NULL;
+    }
+
+    psTime *time = psTimeGetNow(PS_TIME_TAI);
+    psString now = psTimeToISO(time);
+    psFree(time);
+
+    // -newrun
+    psMetadata *newrunArgs = psMetadataAlloc();
+    psMetadataAddStr(newrunArgs, PS_LIST_TAIL, "-dvodb",  0,
+            "define DVO db (required)", NULL);
+
+    // -pending
+    psMetadata *pendingArgs = psMetadataAlloc();
+    psMetadataAddU64(pendingArgs, PS_LIST_TAIL, "-limit",  0,
+            "limit result set to N items", 0);
+    psMetadataAddBool(pendingArgs, PS_LIST_TAIL, "-simple", 0,
+            "use the simple output format", false);
+
+    // -update
+    psMetadata *updateArgs = psMetadataAlloc();
+
+    psFree(now);
+
+    psMetadata *argSets = psMetadataAlloc();
+    psMetadata *modes = psMetadataAlloc();
+
+    PXTOOL_ADD_MODE("-newrun",  "start a new flat correction run",
+        FLATCORR_MODE_NEWRUN,       newrunArgs);
+    PXTOOL_ADD_MODE("-pending", "show flat correction runs needing to be processed",
+        FLATCORR_MODE_PENDING,      pendingArgs);
+    PXTOOL_ADD_MODE("-update",  "change a flat calibration run's state",
+        FLATCORR_MODE_UPDATE,       updateArgs);
+
+    if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
+        psError(PS_ERR_UNKNOWN, true, "option parsing failed");
+        psFree(argSets);
+        psFree(modes);
+        psFree(config);
+        return NULL;
+    }
+
+    psFree(argSets);
+    psFree(modes);
+
+    // setup search criterion
+#define addWhereStr(name) \
+{ \
+    psString str = NULL; \
+    bool status = false; \
+    if ((str = psMetadataLookupStr(&status, config->args, "-" #name))) { \
+        if (!psMetadataAddStr(config->where, PS_LIST_TAIL, #name, 0, "==", str)) {\
+            psError(PS_ERR_UNKNOWN, false, "failed to add item " #name); \
+            psFree(config); \
+            return NULL; \
+        } \
+    } \
+}
+
+    // generate SQL where clause
+    config->where = psMetadataAlloc();
+
+    addWhereStr(det_id);
+    {
+        // XXX this is broke because you can't specify -iteration 0
+        psMetadataItem *item = psMetadataLookup(config->args, "-iteration");
+        if (item && psStrcasestr(item->comment, "found")) {
+            if (!psMetadataAddS32(config->where, PS_LIST_TAIL, "iteration", 0, "==", item->data.S32)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item iteration");
+                psFree(config);
+                return NULL;
+            }
+        }
+    }
+
+    addWhereStr(det_id);
+
+    // convert '-code' to 'fault'
+    {
+        psS16 fault = 0;
+        bool status = false;
+        if ((fault = psMetadataLookupS16(&status, config->args, "-code"))) {
+            if (!psMetadataAddS16(config->where, PS_LIST_TAIL, "fault", 0, "==", fault)) {
+                psError(PS_ERR_UNKNOWN, false, "failed to add item fault");
+                psFree(config);
+                return NULL;
+            }
+        }
+    }
+
+    if (config->where->list->n < 1) {
+        psFree(config->where);
+        config->where = NULL;
+    }
+
+    // define Database handle, if used
+    // do this last so we don't setup a connection before CLI options are
+    // validated
+    config->dbh = pmConfigDB(config->modules);
+    if (!config->dbh) {
+        psError(PS_ERR_UNKNOWN, false, "Can't configure database");
+        psFree(config);
+        return NULL;
+    }
+
+    return config;
+}
