Index: /trunk/ippTools/src/Makefile.am
===================================================================
--- /trunk/ippTools/src/Makefile.am	(revision 6980)
+++ /trunk/ippTools/src/Makefile.am	(revision 6981)
@@ -1,12 +1,13 @@
-bin_PROGRAMS = pxadmin pzsearch p2search p0search pzgetexp pzgetimfiles
+bin_PROGRAMS = pxadmin pzsearch p0search p1search p2search pzgetexp pzgetimfiles
 
 include_HEADERS = pxtools.h
 noinst_HEADERS = \
+	slurp.h \
+	pxadmin.h \
 	pzgetexp.h \
 	pzgetimfiles.h \
-	slurp.h \
-	pxadmin.h \
 	pzsearch.h \
 	p0search.h \
+	p1search.h \
 	p2search.h
 
@@ -42,4 +43,10 @@
     p0searchConfig.c
 
+p1search_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(METADATADB_CFLAGS) $(pxtools_CFLAGS)
+p1search_LDADD = $(PSLIB_LIBS) $(PSMODULES_LIBS) $(METADATADB_LIBS) $(top_builddir)/src/libpxtools.la
+p1search_SOURCES = \
+    p1search.c \
+    p1searchConfig.c
+
 p2search_CFLAGS = $(PSLIB_CFLAGS) $(PSMODULES_CFLAGS) $(METADATADB_CFLAGS) $(pxtools_CFLAGS)
 p2search_LDADD = $(PSLIB_LIBS) $(PSMODULES_LIBS) $(METADATADB_LIBS) $(top_builddir)/src/libpxtools.la
Index: /trunk/ippTools/src/guidetool.c
===================================================================
--- /trunk/ippTools/src/guidetool.c	(revision 6981)
+++ /trunk/ippTools/src/guidetool.c	(revision 6981)
@@ -0,0 +1,240 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "pxtools.h"
+#include "p1search.h"
+
+static bool pendingMode(pxConfig *config);
+static bool updateMode(pxConfig *config);
+static psArray *newFrameSearchPending(pxConfig *config);
+static p1PendingExpRow *newToP1PendingExp(newExpRow *newExp);
+static p2PendingExpRow *newToP2PendingExp(newExpRow *newExp);
+
+int main(int argc, char **argv)
+{
+    pxConfig *config = p1searchConfig(NULL, argc, argv);
+
+    switch (config->mode) {
+        case PX_MODE_PENDING:
+            if (!pendingMode(config)) {
+                goto FAIL;
+            }
+            break;
+        case PX_MODE_UPDATE:
+            if (!updateMode(config)) {
+                goto FAIL;
+            }
+            break;
+        default:
+            psAbort(argv[0], "invalid option (this should not happen)");
+    }
+
+    exit(EXIT_SUCCESS);
+
+FAIL:
+    psFree(config);
+    exit(EXIT_FAILURE);
+}
+
+static bool pendingMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psArray *new = newFrameSearchPending(config);
+    if (!new) {
+        psError(PS_ERR_UNKNOWN, false, "no newFrames found");
+        return false;
+    }
+
+    bool status = newFramePrint(stdout, config, new);
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false,"newFramePrint() failed");
+        return false;
+    }
+
+    return true;
+}
+
+static bool updateMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psArray *new = newFrameSearchPending(config);
+    if (!new) {
+        psError(PS_ERR_UNKNOWN, false, "no newFrames found");
+        return true;
+    }
+
+    // insert 'new' rawScience & detrendframes
+    if (new->n > 0) {
+        for (long i = 0; i < new->n; i++) {
+            newFrame *newFrame = new->data[i];
+            if (strcmp(newFrame->exposure->exp_type, "object") == 0) {
+                // it's a science frame
+                rawScienceFrame *rawScienceFrame = newToRawScienceFrame(newFrame);
+                if (!rawScienceFrameInsert(config, rawScienceFrame)) {
+                    // error
+                }
+            } else {
+                // it's a detrend frame
+                rawDetrendFrame *rawDetrendFrame = newToRawDetrendFrame(newFrame); 
+                if (!rawDetrendFrameInsert(config, rawDetrendFrame)) {
+                    // error
+                }
+            }
+            
+            /*
+            // lookup camera name in p0CameraConfig
+            psMetadata *where = psMetadataAlloc();
+            //bool status = false;
+            psMetadataAddStr(where, PS_LIST_TAIL, "camera", 0, NULL,
+                newFrame->exposure->camera);
+            psArray *configs = p0CameraConfigSelectRowObjects(config->dbh, where, MAX_ROWS);
+            psFree(where);
+            // if there is no match then we default to sending into into p2
+            if (!configs) {
+                // convert newFrame->exposure to p2PendingExp 
+                p2PendingExpRow *p2PendingExp = newToP2PendingExp(
+                    newFrame->exposure
+                );
+                p2PendingExpInsertObject(config->dbh, p2PendingExp);
+                psFree(p2PendingExp);
+                continue;
+            }
+
+            // only use the first match
+            int pX = ((p0CameraConfigRow *)configs->data[0])->phase;
+            switch (pX) {
+                case 1:
+                    // convert newFrame->exposure to p1PendingExp 
+                {
+                    p1PendingExpRow *p1PendingExp = newToP1PendingExp(
+                        newFrame->exposure
+                    );
+                    p1PendingExpInsertObject(config->dbh, p1PendingExp);
+                    psFree(p1PendingExp);
+                }
+                    break;
+                case 2:
+                    // convert newFrame->exposure to p2PendingExp 
+                {
+                    p2PendingExpRow *p2PendingExp = newToP2PendingExp(
+                        newFrame->exposure
+                    );
+                    p2PendingExpInsertObject(config->dbh, p2PendingExp);
+                    psFree(p2PendingExp);
+                }
+                    break;
+                default:
+                    // XXX add argv[0] to pxConfig
+                    psAbort("foo", "invalid phase (this should not happen)");
+            }
+
+            psFree(configs);
+            */
+        }
+        psFree(new);
+    }
+
+    return true;
+}
+
+static psArray *newFrameSearchPending(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    psArray *new = newFrameSearch(config);
+    if (!new) {
+        psError(PS_ERR_UNKNOWN, false, "no newFrames found");
+        return false;
+    }
+
+    psArray *raw = rawScienceFrameSearch(config);
+    if (!raw) {
+        psError(PS_ERR_UNKNOWN, false, "no rawScienceFrames found");
+    //    return false;
+    }
+
+    psArray *rawDetrend = rawDetrendFrameSearch(config);
+    if (!rawDetrend) {
+        psError(PS_ERR_UNKNOWN, false, "no rawDetrendFrames found");
+    //    return false;
+    }
+
+    // ignore duplicate raw frames
+    if (raw) {
+        for (long i = 0; i < new->n; i++) {
+            newFrame *newFrame = new->data[i];
+            for (long j = 0; j < raw->n; j++) {
+                rawScienceFrame *rawScienceFrame = raw->data[j];
+                if (strcmp(newFrame->exposure->exp_id,
+                           rawScienceFrame->exposure->exp_id) == 0) {
+                    psArrayRemove(new, newFrame);
+                    // dec the counter as the array just got shorter
+                    //and we don't want to skip elemnts
+                    i--;
+                    break;
+                }
+            }
+        }
+        psFree(raw);
+    }
+
+    // ignore duplicate rawDetrend frames
+    if (rawDetrend) {
+        for (long i = 0; i < new->n; i++) {
+            newFrame *newFrame = new->data[i];
+            for (long j = 0; j < rawDetrend->n; j++) {
+                rawDetrendFrame *rawDetrendFrame = rawDetrend->data[j];
+                if (strcmp(newFrame->exposure->exp_id,
+                           rawDetrendFrame->exposure->exp_id) == 0) {
+                    psArrayRemove(new, newFrame);
+                    // dec the counter as the array just got shorter
+                    //and we don't want to skip elemnts
+                    i--;
+                    break;
+                }
+            }
+        }
+        psFree(rawDetrend);
+    }
+
+    return new;
+}
+
+
+static p1PendingExpRow *newToP1PendingExp(newExpRow *newExp)
+{
+    return p1PendingExpRowAlloc(
+        newExp->exp_id,
+        newExp->camera,
+        newExp->telescope,
+        newExp->exp_type,
+//        newExp->class,
+        newExp->imfiles,
+        "my filter",
+        "my stats",
+        "my recipe",
+        0xff // XXX calc version number
+    );
+}
+
+static p2PendingExpRow *newToP2PendingExp(newExpRow *newExp)
+{
+    return p2PendingExpRowAlloc(
+        newExp->exp_id,
+        newExp->camera,
+        newExp->telescope,
+        newExp->exp_type,
+//        newExp->class,
+        newExp->imfiles,
+        "my filter", 
+        "my stats",
+        "my recipe",
+        0xff, // XXX calc version number
+        0xff // XXX calc version number
+    );
+}
Index: /trunk/ippTools/src/guidetool.h
===================================================================
--- /trunk/ippTools/src/guidetool.h	(revision 6981)
+++ /trunk/ippTools/src/guidetool.h	(revision 6981)
@@ -0,0 +1,8 @@
+#ifndef P1SEARCH_H
+#define P1SEARCH_H 1
+
+#include "pxtools.h"
+
+pxConfig *p1searchConfig(pxConfig *config, int argc, char **argv);
+
+#endif // P1SEARCH_H
Index: /trunk/ippTools/src/guidetoolConfig.c
===================================================================
--- /trunk/ippTools/src/guidetoolConfig.c	(revision 6981)
+++ /trunk/ippTools/src/guidetoolConfig.c	(revision 6981)
@@ -0,0 +1,196 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pmConfig.h>
+
+#include "pxtools.h"
+
+bool p1searchConfig(pxConfig *config, int argc, char **argv) {
+    if (!config) {
+        config = pxConfigAlloc();
+    }
+
+    if (! pmConfigRead(&config->site, &config->camera, &config->recipe, &argc, argv, RECIPE)) {
+        psError(PS_ERR_UNKNOWN, false, "Can't find site configuration!\n");
+        exit(EXIT_FAILURE);
+    }
+
+    int N;
+    config->mode = PX_MODE_NONE;
+    if ((N = psArgumentGet (argc, argv, "-pending"))) {
+        psArgumentRemove (N, &argc, argv);
+        if (config->mode) {
+            psError(PS_ERR_UNKNOWN, true, "only one mode selection is allowed");
+        }
+        config->mode = PX_MODE_PENDING;
+    }
+    if ((N = psArgumentGet (argc, argv, "-update"))) {
+        psArgumentRemove (N, &argc, argv);
+        if (config->mode) {
+            psError(PS_ERR_UNKNOWN, true, "only one mode selection is allowed");
+        }
+        config->mode = PX_MODE_UPDATE;
+    }
+    
+    // paul's argument parsing convention requires: -key value 
+    // Parse other command-line arguments
+    psMetadata *args = psMetadataAlloc();
+    psMetadataAddStr(args , PS_LIST_TAIL, "-pending", 0,
+        "examine pending image table, write ppImage output", "");
+    psMetadataAddStr(args , PS_LIST_TAIL, "-update",  0,
+        "update pending image table", "");
+
+
+    // -pending search
+    psMetadata *pendingArgs = psMetadataAlloc();
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-exp_id",  0,
+        "define exposure ID", "");
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-inst",  0,
+        "define camera of interest", "");
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-telescope",  0,
+        "define camera of interest", "");
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-exp_type",  0,
+        "define class", "");
+    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-class",  0,
+        "define class", "");
+
+
+    // -update inputs
+    psMetadata *updateArgs = psMetadataAlloc();
+    psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-exp_id",  0,
+        "define class", "");
+    psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-filter",  0,
+        "define filter of interest", "");
+    psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-stat",  0,
+        "define URL", "");
+    psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-recipe",  0,
+        "define URL", "");
+    psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-mosiac",  0,
+        "define URL", "");
+
+    bool argErr = false;
+    if (config->mode == PX_MODE_NONE) {
+        argErr = true;
+        fprintf (stderr, "mode argument is required\n");
+    } else if (! psArgumentParse(args, &argc, argv) || argc != 1) {
+        argErr = true;
+        fprintf (stderr, "error parsing arguments\n");
+    }
+
+    if (argErr) {
+        printf("\nPan-STARRS Phase 0 Search Tool\n");
+        printf("Usage: %s <mode> [<options>]\n\n", argv[0]);
+        printf(" <mode> : -pending | -update\n\n");
+        fprintf (stdout, "-pending ");
+        psArgumentHelp(pendingArgs);
+        fprintf (stdout, "-update ");
+        psArgumentHelp(updateArgs);
+        psFree(args);
+        psFree(pendingArgs);
+        psFree(updateArgs);
+        exit(EXIT_FAILURE);
+    }
+
+    // XXX why is "" being returned when -[foo] isn't specified?
+#define EMPTY_TO_NULL_STRING(var) \
+    if (var != NULL && strcmp(var, "") == 0) { \
+        var = NULL; \
+    }
+
+    switch (config->mode) {
+        bool status;
+        case PX_MODE_PENDING:
+            // -exp_id
+            config->exp_id = psMetadataLookupStr(&status, args, "-exp_id");
+            psMemIncrRefCounter(config->exp_id);
+            EMPTY_TO_NULL_STRING(config->exp_id);
+            // -inst
+            config->camera_name = psMetadataLookupStr(&status, args, "-inst");
+            psMemIncrRefCounter(config->camera_name);
+            EMPTY_TO_NULL_STRING(config->camera_name);
+            // -telescope
+            config->camera_name = psMetadataLookupStr(&status, args,
+                "-telescope");
+            psMemIncrRefCounter(config->telescope);
+            EMPTY_TO_NULL_STRING(config->telescope);
+            // -exp_type
+            config->class = psMetadataLookupStr(&status, args, "-exp_type");
+            psMemIncrRefCounter(config->exp_type);
+            EMPTY_TO_NULL_STRING(config->exp_type);
+            // -class
+            config->class = psMetadataLookupStr(&status, args, "-class");
+            psMemIncrRefCounter(config->class);
+            EMPTY_TO_NULL_STRING(config->class);
+            break;
+        case PX_MODE_UPDATE:
+            // -exp_id
+            config->exp_id = psMetadataLookupStr(&status, args, "-exp_id");
+            psMemIncrRefCounter(config->exp_id);
+            EMPTY_TO_NULL_STRING(config->exp_id);
+            // -filter
+            config->filter = psMetadataLookupStr(&status, args, "-filter");
+            psMemIncrRefCounter(config->filter);
+            EMPTY_TO_NULL_STRING(config->filter);
+
+            break;
+        default:
+            psAbort(argv[0], "invalid option (this should not happen)");
+    }
+
+    psFree(args);
+    psFree(pendingArgs);
+    psFree(updateArgs);
+
+
+    psMetadata *where = psMetadataAlloc();
+
+    if (config->camera_name != NULL) {
+        if (!psMetadataAddStr(where, PS_LIST_TAIL, "camera", 0, "==",
+            config->camera_name)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add item camera");
+            psFree(where);
+            return NULL;
+        }
+    }
+    if (config->filter != NULL) {
+        psMetadataAddStr(where, PS_LIST_TAIL, "filter", 0, "==",
+            config->filter);
+    }
+    if (config->exp_id != NULL) {
+        psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==",
+            config->exp_id);
+    }
+    if (config->class != NULL) {
+        psMetadataAddStr(where, PS_LIST_TAIL, "class", 0, "==",
+            config->class);
+    }
+    if (config->class_id != NULL) {
+        psMetadataAddStr(where, PS_LIST_TAIL, "class_id", 0, "==",
+             config->class_id);
+    }
+
+    /*
+    // psMetadataConfig does not support times yet
+    if (!psTimeIsZero(config->start) && !psTimeIsZero(config->stop)) {
+        psMetadataAddTime (where, PS_LIST_TAIL, "TIME_START", 0, "<", config->stop);
+        psMetadataAddTime (where, PS_LIST_TAIL, "TIME_STOP", 0, ">", config->start);
+    }
+    */
+
+    if (where->list->n < 1) {
+        psFree(where);
+        where = NULL;
+    }
+
+    config->where = where;
+
+
+    // add the input and output images to the args list
+    //psMetadataAddStr (args, PS_LIST_TAIL, "-output", 0, "Name of the output image", argv[1]);
+
+    // define Database handle, if used
+    config->dbh = pmConfigDB(config->site);
+
+    return true;
+} 
