/*
*******************************************************************************
*                                                                             *
* COPYRIGHT:                                                                  *
*   (C) Copyright International Business Machines Corporation, 1998, 1999     *
*   Licensed Material - Program-Property of IBM - All Rights Reserved.        *
*   US Government Users Restricted Rights - Use, duplication, or disclosure   *
*   restricted by GSA ADP Schedule Contract with IBM Corp.                    *
*                                                                             *
*******************************************************************************
*
* File list.c
*
* Modification History:
*
*   Date        Name        Description
*   06/01/99    stephen     Creation.
*******************************************************************************
*/

#include "list.h"
#include "cmemory.h"
#include "ustring.h"

/* Protos */
static void strlist_grow(struct SList *list, UErrorCode *status);
static void strlist2d_grow(struct SList *list, UErrorCode *status);
static void strlist2d_growRows(struct SList *list, UErrorCode *status);
static void taglist_grow(struct SList *list, UErrorCode *status);

/* String list */

struct SList*
strlist_open(UErrorCode *status)
{
  struct SList *list;
  
  if(FAILURE(*status)) return 0;
  
  list = (struct SList*) icu_malloc(sizeof(struct SList));
  if(list == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  list->fType = eStringList;
  
  list->u.fStringList.fData = 0;
  list->u.fStringList.fCount = 0;
  list->u.fStringList.fCapacity = 32;

  strlist_grow(list, status);

  return list;
}

void
strlist_close(struct SList *list,
	      UErrorCode *status)
{
  int32_t i;

  if(FAILURE(*status)) return;

  if(list->fType != eStringList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  /* deallocate each string */
  for(i = 0; i < list->u.fStringList.fCount; ++i) {
    icu_free(list->u.fStringList.fData[i]);
  }
  icu_free(list->u.fStringList.fData);
  
  list->fType = eEmpty;
  icu_free(list);
}

void
strlist_add(struct SList *list,
	    const UChar *s,
	    UErrorCode *status)
{
  int32_t index;
  
  if(FAILURE(*status)) return;
  
  if(list->fType != eStringList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  index = list->u.fStringList.fCount;
  
  if(list->u.fStringList.fCount == list->u.fStringList.fCapacity) 
    strlist_grow(list, status);

  list->u.fStringList.fData[index] = (UChar*) 
    icu_malloc(sizeof(UChar) * (u_strlen(s) + 1));
  if(list->u.fStringList.fData[index] == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return;
  }

  u_strcpy(list->u.fStringList.fData[index], s);
  ++(list->u.fStringList.fCount);
}

static void 
strlist_grow(struct SList *list,
	     UErrorCode *status)
{
  int32_t i, j;
  int32_t newCapacity;
  UChar **newData;
  
  if(FAILURE(*status)) return;
  
  if(list->fType != eStringList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  newCapacity = list->u.fStringList.fCapacity << 1; 
  
  /* allocate space for the array of strings */
  newData = (UChar**) icu_malloc(sizeof(UChar*) * newCapacity);
  if(newData == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return;
  }

  /* allocate and copy each string */
  for(i = 0; i < list->u.fStringList.fCount; ++i) {
    newData[i] = (UChar*) 
      icu_malloc(sizeof(UChar) * (u_strlen(list->u.fStringList.fData[i]) + 1));
    if(newData[i] == 0) {
      *status = MEMORY_ALLOCATION_ERROR;
      for(j = 0; j < i; ++j) 
	icu_free(newData[j]);
      icu_free(newData);
      return;
    }
    u_strcpy(newData[i], list->u.fStringList.fData[i]);
  }
  
  icu_free(list->u.fStringList.fData);
  list->u.fStringList.fData = newData;
  list->u.fStringList.fCapacity = newCapacity;
}

/* 2-d String list*/

struct SList*
strlist2d_open(UErrorCode *status)
{
  struct SList *list;
  
  if(FAILURE(*status)) return 0;

  list = (struct SList*) icu_malloc(sizeof(struct SList));
  if(list == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  list->fType = eStringList2d;
  
  list->u.fStringList2d.fData = 0;
  list->u.fStringList2d.fCount = 0;
  list->u.fStringList2d.fCapacity = 32;

  list->u.fStringList2d.fRows = 0;
  list->u.fStringList2d.fRowCount = 0;
  list->u.fStringList2d.fRowCapacity = 32;

  strlist2d_grow(list, status);
  strlist2d_growRows(list, status);

  if(SUCCESS(*status)) {
    list->u.fStringList2d.fRows[0] = 0;
    list->u.fStringList2d.fRowCount = 1;
  }

  return list;
}

void 
strlist2d_close(struct SList *list,
		UErrorCode *status)
{
  int32_t i;
  
  if(FAILURE(*status)) return;
  
  if(list->fType != eStringList2d) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }

  /* deallocate each string */
  for(i = 0; i < list->u.fStringList2d.fCount; ++i) {
    icu_free(list->u.fStringList2d.fData[i]);
  }
  icu_free(list->u.fStringList2d.fData);

  icu_free(list->u.fStringList2d.fRows);

  list->fType = eEmpty;
  icu_free(list);
}

void
strlist2d_newRow(struct SList *list,
		 UErrorCode *status)
{
  if(FAILURE(*status)) return;

  if(list->fType != eStringList2d) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  if(list->u.fStringList2d.fRowCount == list->u.fStringList2d.fRowCapacity)
    strlist2d_growRows(list, status);
  if(FAILURE(*status)) return;
  list->u.fStringList2d.fRows[(list->u.fStringList2d.fRowCount)++] = 
    list->u.fStringList2d.fCount;
}

void strlist2d_add(struct SList *list,
		 const UChar *s,
		 UErrorCode *status)
{
  int32_t index;
  
  if(FAILURE(*status)) return;

  if(list->fType != eStringList2d) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }

  index = list->u.fStringList2d.fCount;
  
  if(list->u.fStringList2d.fCount == list->u.fStringList2d.fCapacity) 
    strlist2d_grow(list, status);

  list->u.fStringList2d.fData[index] = (UChar*) 
    icu_malloc(sizeof(UChar) * (u_strlen(s) + 1));
  if(list->u.fStringList2d.fData[index] == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return;
  }

  u_strcpy(list->u.fStringList2d.fData[index], s);
  ++(list->u.fStringList2d.fCount);
}

static void
strlist2d_grow(struct SList *list,
	       UErrorCode *status)
{
  int32_t i, j;
  int32_t newCapacity;
  UChar **newData;
  
  if(FAILURE(*status)) return;

  if(list->fType != eStringList2d) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  newCapacity = list->u.fStringList2d.fCapacity << 1; 
  
  /* allocate space for the array of strings */
  newData = (UChar**) icu_malloc(sizeof(UChar*) * newCapacity);
  if(newData == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return;
  }

  /* allocate and copy each string */
  for(i = 0; i < list->u.fStringList2d.fCount; ++i) {
    newData[i] = (UChar*) 
      icu_malloc(sizeof(UChar) * (u_strlen(list->u.fStringList2d.fData[i]) + 1));
    if(newData[i] == 0) {
      *status = MEMORY_ALLOCATION_ERROR;
      for(j = 0; j < i; ++j) 
	icu_free(newData[j]);
      icu_free(newData);
      return;
    }
    u_strcpy(newData[i], list->u.fStringList2d.fData[i]);
  }
  
  icu_free(list->u.fStringList2d.fData);
  list->u.fStringList2d.fData = newData;
  list->u.fStringList2d.fCapacity = newCapacity;
}

static void 
strlist2d_growRows(struct SList *list,
		   UErrorCode *status)
{
  int32_t i;
  int32_t newCapacity;
  int32_t *newRows;

  if(FAILURE(*status)) return;

  if(list->fType != eStringList2d) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }

  newCapacity = list->u.fStringList2d.fRowCapacity << 1;
  
  /* allocate space for the array of ints */
  newRows = (int32_t*) icu_malloc(sizeof(int32_t) * newCapacity);
  if(newRows == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
  }
  
  /* copy each int */
  for(i = 0; i < list->u.fStringList2d.fRowCount; ++i) 
    newRows[i] = list->u.fStringList2d.fRows[i];
  
  /* clean up */
  icu_free(list->u.fStringList2d.fRows);
  list->u.fStringList2d.fRows = newRows;
  list->u.fStringList2d.fRowCapacity = newCapacity;
}

/* Tagged list */

struct SList*
taglist_open(UErrorCode *status)
{
  struct SList *list;
  
  if(FAILURE(*status)) return 0;
  
  list = (struct SList*) icu_malloc(sizeof(struct SList));
  if(list == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  list->fType = eTaggedList;
  
  list->u.fTaggedList.fData = 0;
  list->u.fTaggedList.fCount = 0;
  list->u.fTaggedList.fCapacity = 32;

  taglist_grow(list, status);
  
  return list;
}

void 
taglist_close(struct SList *list,
	      UErrorCode *status)
{
  if(FAILURE(*status)) return;

  if(list->fType != eTaggedList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  icu_free(list->u.fTaggedList.fData);
  
  list->fType = eEmpty;
  icu_free(list);
}


static void 
taglist_grow(struct SList *list,
	     UErrorCode *status)
{
  int32_t i;
  int32_t newCapacity;
  struct SStringPair *newData;
  
  if(FAILURE(*status)) return;
  
  if(list->fType != eTaggedList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }
  
  newCapacity = list->u.fTaggedList.fCapacity << 1; 
  
  /* allocate space for the array of string pairs */
  newData = (struct SStringPair*) 
    icu_malloc(sizeof(struct SStringPair) * newCapacity);
  if(newData == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return;
  }

  /* copy each string pair */
  for(i = 0; i < list->u.fTaggedList.fCount; ++i) {
    newData[i] = list->u.fTaggedList.fData[i];
  }
  
  icu_free(list->u.fTaggedList.fData);
  list->u.fTaggedList.fData = newData;
  list->u.fTaggedList.fCapacity = newCapacity;
}

void
taglist_add(struct SList *list,
	    const UChar *tag, 
	    const UChar *data,
	    UErrorCode *status)
{
  int32_t index;
  struct SStringPair pair;
  
  if(FAILURE(*status)) return;
  
  if(list->fType != eTaggedList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return;
  }

  pair.fKey = (UChar*) icu_malloc(sizeof(UChar) * (u_strlen(tag) + 1));
  if(pair.fKey == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    return;
  }

  pair.fValue = (UChar*) icu_malloc(sizeof(UChar) * (u_strlen(data) + 1));
  if(pair.fValue == 0) {
    *status = MEMORY_ALLOCATION_ERROR;
    icu_free(pair.fKey);
    return;
  }

  u_strcpy(pair.fKey, tag);
  u_strcpy(pair.fValue, data);
  
  index = list->u.fTaggedList.fCount;
  
  if(list->u.fTaggedList.fCount == list->u.fTaggedList.fCapacity)
    taglist_grow(list, status);
  
  list->u.fTaggedList.fData[index] = pair;
  ++(list->u.fTaggedList.fCount);
}

const UChar* 
taglist_get(const struct SList *list,
	    const UChar *tag,
	    UErrorCode *status)
{
  int32_t i;

  if(FAILURE(*status)) return 0;
  
  if(list->fType != eTaggedList) {
    *status = ILLEGAL_ARGUMENT_ERROR;
    return 0;
  }

  for(i = 0; i < list->u.fTaggedList.fCount; ++i) {
    if(u_strcmp(list->u.fTaggedList.fData[i].fKey, tag) == 0)
      return list->u.fTaggedList.fData[i].fValue;
  }

  return 0;
}
