#include <stddef.h>
#include <assert.h>

#include "FTreg.h"
#include "string.h"
#include "getdate.h"
#include "memory.h"

union un1 {
  time_t t;
  char ch[sizeof(time_t)];
};

static char *parser(s)
char *s;
{
  union un1 u;
  char *temp;

  u.t = getdate(s, (struct timeb *)NULL);
  if (u.t == (time_t)-1)
    return NULL;
  temp = (char *)Memory_allocate(sizeof u);
  strncpy(temp, &(u.ch[0]), sizeof(u.ch));
  return temp;
}

static char *un_parser(s)
char *s;
{
  char *temp1, *temp2;
  union un1 u;

  strncpy(&(u.ch[0]), s, sizeof(u.ch));
  temp1 = ctime(&(u.t));
  if (temp1 == NULL)
    return NULL;
  temp2 = (char *)Memory_allocate(strlen(temp1)+1);
  strcpy(temp2, temp1);
  return temp2;
}

/* `his function doesn't work because I am getting consistantly an invalid */
 /* value back from localtime. */
static int date_equal(rule, msg)
     char *rule, *msg;
{
  union un1 uR, uM;
  struct tm *ruleT, *msgT;

  tzset();
  strncpy(&(uR.ch[0]), rule, sizeof(uR.ch));
  strncpy(&(uM.ch[0]), msg, sizeof(uM.ch));

  printf("ctime of %d is %s\n",uR.t,ctime(&(uR.t)));
  ruleT=localtime((time_t*)&(uR.t));
  msgT=localtime((time_t*)&(uM.t));
  printf("rule yday=%d year=%d mday=%d\n",
	 msgT->tm_yday,msgT->tm_year,msgT->tm_mday);

  return (ruleT->tm_yday == msgT->tm_yday &&
	  ruleT->tm_year == msgT->tm_year); 
	  
}

/* This function also does not work because date_equal does not work (see */
 /* comment above) */
static int date_not_equal(rule, msg)
     char *rule, *msg;
{
  return(!date_equal(rule,msg));
}

static int date_less(value, pattern)
char *value, *pattern;
{
  union un1 u1, u2;

  strncpy(&(u1.ch[0]), value, sizeof(u1.ch));
  strncpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u2.t > u1.t;
}

static int date_greater(value, pattern)
char *value, *pattern;
{
  union un1 u1, u2;

  strncpy(&(u1.ch[0]), value, sizeof(u1.ch));
  strncpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u2.t < u1.t;
}

static NORET date_free(data)
char *data;
{
  Memory_free(data);
}

/*  The name of the first item in each group below will appear in the */
 /*  ruleeditor menu.  All the other items are equivalent ways to name that */
 /*  field operator. */
static FieldOpArg fieldOpList[]={
  { "is before",date_less },
  { "before",date_less },
  { "<",date_less },

  { "is after",date_greater },
  { "after",date_greater },
  { ">",date_greater },

/* These are commented out because of problems in the date_equal function */
  /* (see above) */
  /*
  { "not",date_not_equal },
  { "is not equal to",date_not_equal },
  { "!=",date_not_equal },
  { "~=",date_not_equal },

  { "is equal to",date_equal },
  { "equal",date_equal },
  { "equals",date_equal },
  { "=",date_equal }, */

  { (char *)NULL, NULL}
};

static struct AlFieldTypeRegistry_str  date_FTrec={
  "Date",
  parser,
  un_parser,
  fieldOpList,
  NULL,
  NULL,
  date_free,
};

struct AlFieldTypeRegistry_str  *date_FTrecptr = &date_FTrec;

