/* coastal.c: -*- C -*-  Hack coastal uploads. */

/*  Copyright (c) 1998 Brian J. Fox
    Author: Brian J. Fox (bfox@ai.mit.edu) Fri Jan 16 14:20:49 1998.  */

#include "language.h"

static void pf_coastal_parse (PFunArgs);

static PFunDesc functab[] = {
  /*   tag	     complex? debug_level	   code    */
  { "COASTAL::PARSE",	0,	 0,		pf_coastal_parse },
  { (char *)NULL,	0,	 0,		(PFunHandler *)NULL }
};

void
module_initialize (void)
{
  register int i;
  Symbol *sym;
  static called = 0;

  if (!called)
    {
      called = 1;

      /* Install the names and pointers. */
      for (i = 0; functab[i].tag != (char *)NULL; i++)
	{
	  sym = symbol_intern_in_package (mhtml_function_package,
					  functab[i].tag);
	  sym->type = symtype_FUNCTION;
	  sym->values = (char **)(&functab[i]);
	}
    }
}

void _init (void) { module_initialize (); }

/* <coastal::parse varname> --> an array of alists for each ad. */
static void
pf_coastal_parse (PFunArgs)
{
  char *varname = mhtml_evaluate_string (get_positional_arg (vars, 0));

  if (!empty_string_p (varname))
    {
      Symbol *sym = symbol_lookup (varname);
      char *data_string = (char *)NULL;

      if (sym != (Symbol *)NULL)
	{
	  switch (sym->type)
	    {
	    case symtype_BINARY:
	      data_string = ((Datablock *)sym->values)->data;
	      break;

	    case symtype_STRING:
	      if (sym->values)
		data_string = (sym->values[0]);
	      break;

	    default:
	      break;
	    }
	}

      if (data_string)
	{
	  register int i = 0;
	  int limit = strlen (data_string);
	  int crnl_pairs = 0;

	  /* Skip until we find 4 CR/NL pairs in a row. */
	  while (i < limit)
	    {
	      if ((data_string[i] == '\r') && (data_string[i + 1] == '\n'))
		{
		  crnl_pairs++;

		  i += 2;

		  if (crnl_pairs > 4)
		    {
		      while ((i < limit) &&
			     ((data_string[i] == '\r') &&
			      (data_string[i + 1] == '\n'))) i += 2;
		      break;
		    }
		}
	      else
		{
		  crnl_pairs = 0;
		  i++;
		}
	    }

	  /* Now pointing at first byte of first record.  The format is:
	     Street-Number, Flag-D, Street-Name, Flag-P, Area, Description.
	     The Description can begin with "LOCATION:" or
	     "NEW LISTING/LOCATION:" or "NEW LISTING LOCATION:" or
	     "NEW LISTING" or none of the above. */
	  while (i < limit)
	    {
	      int dstart = 0, dend = 0;
	      static char *value = (char *)NULL;
	      static int vlen = 0;
	      int len;
	      Package *p = symbol_get_package ((char *)NULL);
	    
	      /* Advance to the next record. */
	      while ((i < limit) &&
		     ((data_string[i] == '\r') &&
		      (data_string[i + 1] == '\n'))) i += 2;

	      dstart = i;

	      /* Get the Street-Number. */
	      while (i < limit)
		if (data_string[i] == '\r')
		  break;
		else
		  i++;

	      if (i >= limit) break;

	      dend = i;
	      len = dend - dstart;

	      if ((len + 2) > vlen)
		value = (char *)xrealloc (value, (vlen = len + 50));

	      strncpy (value, data_string + dstart, len);
	      value[len] = '\0';

	      forms_set_tag_value_in_package (p, "street_number", value);

	      i += 2;

	      if (i >= limit) break;

	      /* Get Flag-D. */
	      if (data_string[i] != '\r')
		{
		  forms_set_tag_value_in_package (p, "dflag", "true");
		  while (data_string[i] != '\r') i++;
		}

	      i += 2;

	      if (i >= limit) break;

	      /* Get Street-Name. */
	      dstart = i;

	      while (i < limit)
		if (data_string[i] == '\r')
		  break;
		else
		  i++;

	      dend = i;
	      len = dend - dstart;

	      if ((len + 2) > vlen)
		value = (char *)xrealloc (value, (vlen = len + 50));

	      strncpy (value, data_string + dstart, len);
	      value[len] = '\0';
	      forms_set_tag_value_in_package (p, "street_name", value);

	      i += 2;

	      if (i >= limit) break;

	      /* Get Flag-P. */
	      if (data_string[i] != '\r')
		{
		  value[0] = data_string[i];
		  value[1] = '\0';
		  forms_set_tag_value_in_package (p, "pflag", value);
		  while (data_string[i] != '\r') i++;
		}

	      i += 2;

	      if (i >= limit) break;

	      /* Get Area. */
	      dstart = i;

	      while (i < limit)
		if (data_string[i] == '\r')
		  break;
		else
		  i++;

	      dend = i;
	      len = dend - dstart;

	      if ((len + 2) > vlen)
		value = (char *)xrealloc (value, (vlen = len + 50));

	      strncpy (value, data_string + dstart, len);
	      value[len] = '\0';
	      forms_set_tag_value_in_package (p, "area", value);

	      i += 2;

	      if (i >= limit) break;

	      /* Get Description. */
	      dstart = i;

	      while (i < limit)
		if (data_string[i] == '\r')
		  break;
		else
		  i++;

	      dend = i;
	      len = dend - dstart;

	      if ((len + 2) > vlen)
		value = (char *)xrealloc (value, (vlen = len + 50));

	      strncpy (value, data_string + dstart, len);
	      value[len] = '\0';
	      forms_set_tag_value_in_package (p, "description", value);

	      {
		char *result = package_to_alist (p, 0);
		bprintf_insert (page, start, "%s\n", result);
		start += (1 + strlen (result));
		free (result);
		symbol_destroy_package (p);
	      }
	    }
	}
    }
  *newstart = start;
}
