/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2002-2004, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

/* Created by weiv 05/09/2002 */

#include "unicode/datamap.h"
#include "unicode/resbund.h"
#include "hash.h"
#include <stdlib.h>

int32_t 
DataMap::utoi(const UnicodeString &s) const
{
  char ch[256];
  const UChar *u = s.getBuffer();
  int32_t len = s.length();
  u_UCharsToChars(u, ch, len);
  ch[len] = 0; /* include terminating \0 */
  return atoi(ch);
}

U_CDECL_BEGIN
void U_CALLCONV
deleteResBund(void *obj) {
  delete (ResourceBundle *)obj;
}
U_CDECL_END


RBDataMap::~RBDataMap()
{
  delete fData;
}

RBDataMap::RBDataMap()
{
  UErrorCode status = U_ZERO_ERROR;
  fData = new Hashtable(TRUE, status);
  fData->setValueDeleter(deleteResBund);
}

// init from table resource
// will put stuff in hashtable according to 
// keys.
RBDataMap::RBDataMap(UResourceBundle *data, UErrorCode &status)
{
  fData = new Hashtable(TRUE, status);
  fData->setValueDeleter(deleteResBund);
  init(data, status);
}

// init from headers and resource
// with checking the whether the size of resource matches 
// header size
RBDataMap::RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) 
{
  fData = new Hashtable(TRUE, status);
  fData->setValueDeleter(deleteResBund);
  init(headers, data, status);
}


void RBDataMap::init(UResourceBundle *data, UErrorCode &status) {
  int32_t i = 0;
  fData->removeAll();
  UResourceBundle *t = NULL;
  for(i = 0; i < ures_getSize(data); i++) {
    t = ures_getByIndex(data, i, t, &status);
    fData->put(UnicodeString(ures_getKey(t), ""), new ResourceBundle(t, status), status);
  }
  ures_close(t);
}

void RBDataMap::init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status)
{
  int32_t i = 0;
  fData->removeAll();
  UResourceBundle *t = NULL;
  const UChar *key = NULL;
  int32_t keyLen = 0;
  if(ures_getSize(headers) == ures_getSize(data)) {
    for(i = 0; i < ures_getSize(data); i++) {
      t = ures_getByIndex(data, i, t, &status);
      key = ures_getStringByIndex(headers, i, &keyLen, &status);
      fData->put(UnicodeString(key, keyLen), new ResourceBundle(t, status), status);
    }
  } else {
    // error
    status = U_INVALID_FORMAT_ERROR;
  }
  ures_close(t);
}

const ResourceBundle *RBDataMap::getItem(const char* key, UErrorCode &status) const
{
  if(U_FAILURE(status)) {
    return NULL;
  }

  UnicodeString hashKey(key, "");
  const ResourceBundle *r = (ResourceBundle *)fData->get(hashKey);
  if(r != NULL) {
    return r;
  } else {
    status = U_MISSING_RESOURCE_ERROR;
    return NULL;
  }
}

const UnicodeString RBDataMap::getString(const char* key, UErrorCode &status) const
{
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    return r->getString(status);
  } else {
    status = U_MISSING_RESOURCE_ERROR;
    return UnicodeString();
  }
}

int32_t
RBDataMap::getInt28(const char* key, UErrorCode &status) const
{
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    return r->getInt(status);
  } else {
    return 0;
  }
}

uint32_t
RBDataMap::getUInt28(const char* key, UErrorCode &status) const
{
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    return r->getUInt(status);
  } else {
    return 0;
  }
}

const int32_t *
RBDataMap::getIntVector(int32_t &length, const char *key, UErrorCode &status) const {
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    return r->getIntVector(length, status);
  } else {
    return NULL;
  }
}

const uint8_t *
RBDataMap::getBinary(int32_t &length, const char *key, UErrorCode &status) const {
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    return r->getBinary(length, status);
  } else {
    return NULL;
  }
}

int32_t RBDataMap::getInt(const char* key, UErrorCode &status) const
{
  UnicodeString r = this->getString(key, status);
  if(U_SUCCESS(status)) {
    return utoi(r);
  } else {
    return 0;
  }
}

const UnicodeString* RBDataMap::getStringArray(int32_t& count, const char* key, UErrorCode &status) const 
{
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    int32_t i = 0;

    count = r->getSize();
    if(count <= 0) {
      return NULL;
    }

    UnicodeString *result = new UnicodeString[count];
    for(i = 0; i<count; i++) {
      result[i] = r->getStringEx(i, status);
    }
    return result;
  } else {
    status = U_MISSING_RESOURCE_ERROR;
    return NULL;
  }
}

const int32_t* RBDataMap::getIntArray(int32_t& count, const char* key, UErrorCode &status) const
{
  const ResourceBundle *r = getItem(key, status);
  if(U_SUCCESS(status)) {
    int32_t i = 0;

    count = r->getSize();
    if(count <= 0) {
      return NULL;
    }

    int32_t *result = new int32_t[count];
    UnicodeString stringRes;
    for(i = 0; i<count; i++) {
      stringRes = r->getStringEx(i, status);
      result[i] = utoi(stringRes);
    }
    return result;
  } else {
    status = U_MISSING_RESOURCE_ERROR;
    return NULL;
  }
}
