/* next.c -- routines for next and prev */
#include "he.h"

extern HE_PRED *he_predicates;

int HEnext(cmd)
    HE_CMD *cmd;
{
    int tmp;
    HE_PRED *predicates;
    HE_PRED *parsePred();

    if (cmd->argc == 2 && !strcmp(cmd->argv[1],"-help"))
    {
	puts("next [<prediactes>]");
	puts("\tMove to the next element that satisfies the predicate");
	return HE_OK;
    }

    if (!fileOpen())
    {
	noFile();
        return HE_FAIL;
    }

    predicates = parsePred(cmd->argc, cmd->argv);

    /* the following code assumes that parsePred() returns NULL if error, */
    /* a predicate struct with no key if empty predicate list */
    if (!predicates) return HE_FAIL;

    /* replace this only if it is non-empty */
    if (predicates[0].key != 0)
    {
	if (he_predicates) free(he_predicates);
	he_predicates = predicates;
    }

    tmp = he_currDesc;
    do
    {
	if (tmp >= he_numDesc - 1)
	{
	    fprintf(stderr, "Reached end of file. Not moved.\n");
	    return HE_FAIL;
	}
	tmp++;
    } while (he_desc[tmp].tag == DFTAG_NULL ||
	     !satPred(he_desc + tmp, he_predicates));

    he_currDesc = tmp;

    return HE_OK;
}

int HEprev(cmd)
    HE_CMD *cmd;
{
    int tmp;
    HE_PRED *predicates;
    HE_PRED *parsePred();

    if (cmd->argc == 2 && !strcmp(cmd->argv[1],"-help"))
    {
	puts("prev [<prediactes>]");
	puts("\tMove to the next element that satisfies the predicate");
	return HE_OK;
    }

    if (!fileOpen())
    {
        noFile();
        return HE_FAIL;
    }

    predicates = parsePred(cmd->argc, cmd->argv);

    /* the following code assumes that parsePred() returns NULL if error,
       a predicate struct with no key if empty predicate list */
    if (!predicates) return HE_FAIL;

    if (predicates[0].key != 0)
    {
	if (he_predicates) free(he_predicates);
	he_predicates = predicates;
    }

    tmp = he_currDesc;
    do
    {
	if (tmp <= 0)
	{
	    fprintf(stderr, "Reached beginning of file. Not moved.\n");
	    return HE_FAIL;
	}
	tmp--;
    } while (he_desc[tmp].tag == DFTAG_NULL ||
	     !satPred(he_desc + tmp,he_predicates));
    he_currDesc = tmp;

    return HE_OK;
}

/* end of next.c */
