#include "assert.h"   /* must be first for use eith hc2 */
#include "ArgPack.h"
#include "useful.h"
#include "memory.h"
#include "assert.h"
#include "debug.h"
#include "registry.h"

static Registry args=NULL;

/*--------------*/
ArgPack ArgPack_create()  /* use this tyo get the ArgPack that you */
{                              /*  pass to the other functions */
  ArgPack w;
#ifdef ARGPACK_DEBUG
  if (args==NULL) 
    args=Registry_create(Registry_ptrcmp,Registry_ptrhash);
#endif
  w=(struct ArgPack_str *)Memory_allocate(sizeof(struct ArgPack_str));
  w->Count=0;
  w->args=NULL;
#ifdef ARGPACK_DEBUG
  Registry_add(args,w,w);
#endif
  return(w);
}
/*----------*/
void ArgPack_add_arg(AP,resource,value)
     ArgPack AP;
     char *resource;
     XtArgVal value; 
{
  int Count;
  assert(AP);
#ifdef ARGPACK_DEBUG
  assert(Registry_get(args,AP));
#endif
  Count=AP->Count;
  if (AP->args==NULL)
    AP->args=(Arg *)Memory_allocate((Count+1)*sizeof(Arg));
  else
    AP->args=(Arg *)Memory_reallocate((char *)AP->args,(Count+1)*sizeof(Arg));
  XtSetArg(AP->args[Count],resource,value);
  AP->Count++;
};
/*----------------*/
int ArgPack_num_args(AP)
     ArgPack AP;
{
  return(AP->Count);
}
/*-----------------*/
Arg *ArgPack_the_args(AP)
     ArgPack AP;
{
  return(AP->args);
}
/*---------------*/
void ArgPack_delete(AP)
     ArgPack AP;
{
#ifdef ARGPACK_DEBUG
  assert(Registry_remove(args,AP)==Bool_TRUE);
#endif
  if (AP->args!=NULL)
    Memory_free((char *)AP->args);
  Memory_free((char *)AP);
}
    
/*-------------------------------------------*/
ArgPack ArgPack_duplicate_args(al)
     Arg *al;
{
  ArgPack dal;
  int Size, i;

  dal=ArgPack_create();
  Size=0;
  while (al[Size].name!=NULL)  Size++;
  if (Size!=0)
    dal->args=(Arg *)Memory_allocate(Size*sizeof(Arg));
  else
    dal->args=NULL;
  dal->Count=Size;
  for (i=0;i<Size;i++)  {
    dal->args[i].name=al[i].name;
    dal->args[i].value=al[i].value;
  }
  return(dal);
} 

/*-------------------------------------------*/
ArgPack ArgPack_append_args(dal,al)
     ArgPack dal;
     Arg *al;
{
  int Size, i,Count,j;

#ifdef ARGPACK_DEBUG
  assert(Registry_get(args,dal));
#endif

  assert(dal); assert(al);
  Size=0;
  while (al[Size].name!=NULL)  Size++;
  Count=dal->Count;
  if (Size==0)  return(dal);
  if (Count==0)
    dal->args=(Arg *)Memory_allocate(Size*sizeof(Arg));
  else
    dal->args=(Arg *)Memory_reallocate(dal->args,(Count+Size)*sizeof(Arg));
  dal->Count=Count+Size;
  for (i=Count,j=0;i<(Size+Count);i++,j++)  {
    dal->args[i].name=al[j].name;
    dal->args[i].value=al[j].value;
  }
  return(dal);
} 

/*-------------------------------------------*/
ArgPack ArgPack_copy_and_append(dest,source)
     ArgPack dest,source;
{
  int S,D,i,j;
#ifdef ARGPACK_DEBUG
  assert(Registry_get(args,dest));
  assert(Registry_get(args,source));
#endif

  assert(dest);
  if (source!=NULL) {
    S=source->Count;
    D=dest->Count;
    if (S!=0) {
      if (dest->args==NULL) {
	dest->args=(Arg *)Memory_allocate(S*sizeof(Arg));
	dest->Count=S;
      }
      else {
	dest->args=(Arg *)Memory_reallocate(dest->args,(S+D)*sizeof(Arg));
	dest->Count=S+D;
      }
      for (j=0,i=D;j<S;i++,j++)  {
	dest->args[i].name=source->args[j].name;
	dest->args[i].value=source->args[j].value;
      }
    }
  }
  return(dest);
} 

/*--------------------------------------------------*/
void ArgPack_print(ap)
ArgPack ap;
{
  int i;
  for (i=0;i<ap->Count;i++)
    printf("%s, %d\n",ap->args[i].name, ap->args[i].value);
}

