/*>>> santag.c: SAN project tag environment routines */

/* Revised: 1993.11.25 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "sandef.h"
#include "sanvar.h"

#include "sandsp.h"
#include "santag.h"
#include "sanutl.h"

/*--> SANTagFormat: format an allocated tag value display */
nonstatic
charptrT
SANTagFormat (tagptrT tagptr)
{
  charptrT s;

  s = SANMemGrab (strlen (tagptr->tag_name) + strlen (tagptr->tag_value) + 7);
  (void) sprintf (s, "[%s \"%s\"]", tagptr->tag_name, tagptr->tag_value);

  return (s);
}

/*--> SANTagFormatReserved: format a reserved tag value */
nonstatic
charptrT
SANTagFormatReserved (rsvtagT rsvtag)
{

  return (SANTagFormat (SANTagLocate (rsvtagv[rsvtag])));
}

/*--> SANTagCreate: create and assign storage for a new tag pair */
nonstatic
tagptrT
SANTagCreate (charptrT name, charptrT value, tagfT tagf)
{
  tagptrT tagptr;

  tagptr = (tagptrT) SANMemGrab (sizeof (tagT));
  tagptr->tag_name = SANStrGrab (name);
  tagptr->tag_value = SANStrGrab (value);
  tagptr->tag_prev = tagptr->tag_next = NULL;
  tagptr->tag_flag = tagf;

  return (tagptr);
}

/*--> SANTagLocate: locate the indicated tag record by name */
nonstatic
tagptrT
SANTagLocate (charptrT name)
{
  tagptrT tagptr0, tagptr1;

  tagptr0 = head_tagptr;
  tagptr1 = NULL;
  while ((tagptr0 != NULL) && (tagptr1 == NULL))
    if (strcmp (tagptr0->tag_name, name) == 0)
      tagptr1 = tagptr0;
    else
      tagptr0 = tagptr0->tag_next;

  return (tagptr1);
}

/*--> SANTagDelete: delete the indicated tag record */
nonstatic
void
SANTagDelete (tagptrT tagptr)
{
  if (tagptr->tag_prev == NULL)
    head_tagptr = tagptr->tag_next;
  else
    tagptr->tag_prev->tag_next = tagptr->tag_next;

  if (tagptr->tag_next == NULL)
    tail_tagptr = tagptr->tag_prev;
  else
    tagptr->tag_next->tag_prev = tagptr->tag_prev;

  SANMemFree (tagptr->tag_name);
  SANMemFree (tagptr->tag_value);
  SANMemFree (tagptr);

  return;
}

/*--> SANTagInsert: insert the indicated tag record */
nonstatic
void
SANTagInsert (tagptrT tagptr)
{
/* insert at end of list */

  if (head_tagptr == NULL)
    {
      head_tagptr = tagptr;
      tagptr->tag_prev = NULL;
    }
  else
    {
      tail_tagptr->tag_next = tagptr;
      tagptr->tag_prev = tail_tagptr;
    };
  tagptr->tag_next = NULL;
  tail_tagptr = tagptr;

  return;
}

/*--> SANTagUpdate: update the indicated tag record */
nonstatic
void
SANTagUpdate (tagptrT tagptr, charptrT value)
{
  SANMemFree (tagptr->tag_value);
  tagptr->tag_value = SANStrGrab (value);

  return;
}

/*--> SANTagInitTag: initialize a tag */
static
void
SANTagInitTag (rsvtagT rsvtag, charptrT name, charptrT value, tagfT tagf)
{
  rsvtagv[rsvtag] = name;
  SANTagInsert (SANTagCreate (rsvtagv[rsvtag], value, tagf));

  return;
}

/*--> SANTagClear: clear a single tag value */
nonstatic
void
SANTagClear (tagptrT tagptr)
{
  SANTagUpdate (tagptr, "");

  return;
}

/*--> SANTagClearAll: clear all tag values */
nonstatic
void
SANTagClearAll (void)
{
  tagptrT tagptr;

  tagptr = head_tagptr;
  while (tagptr != NULL)
    {
      SANTagClear (tagptr);
      tagptr = tagptr->tag_next;
    };

  return;
}

/*--> SANTagInit: one time initialization for tag subsystem */
nonstatic
void
SANTagInit (void)
{
/* clear the head and tail pointers */

  head_tagptr = tail_tagptr = NULL;

/* insert the reserved tags */

  SANTagInitTag (rsvtag_event, "Event", "", tagf_perm);
  SANTagInitTag (rsvtag_site, "Site", "", tagf_perm);
  SANTagInitTag (rsvtag_round, "Round", "", tagf_perm);
  SANTagInitTag (rsvtag_date, "Date", "", tagf_perm);
  SANTagInitTag (rsvtag_white, "White", "", tagf_perm);
  SANTagInitTag (rsvtag_black, "Black", "", tagf_perm);
  SANTagInitTag (rsvtag_result, "Result", "", tagf_perm);

  return;
}

/*--> SANTagTerm: one time termination for tag subsystem */
nonstatic
void
SANTagTerm (void)
{
/* release tag storage */

  while (head_tagptr != NULL)
    SANTagDelete (head_tagptr);

  return;
}

/*<<< santag.c: EOF */
