/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2002-2006, 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), -1, US_INV), 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, -1, US_INV);
  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 {
    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 {
    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 {
    return NULL;
  }
}

