/*
 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file picorsrc.c
 *
 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
 * All rights reserved.
 *
 * History:
 * - 2009-04-20 -- initial version
 *
 */

#include "picodefs.h"
#include "picoos.h"
#include "picodbg.h"

/* knowledge layer */
#include "picoknow.h"

#include "picokdt.h"
#include "picoklex.h"
#include "picokfst.h"
#include "picokpdf.h"
#include "picoktab.h"
#include "picokpr.h"

#include "picorsrc.h"

#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif


#if defined(PICO_DEBUG)
#include "picokdbg.h"
#endif


/**  object   : Resource
 *   shortcut : rsrc
 *
 */
typedef struct picorsrc_resource {
    picoos_uint32 magic;  /* magic number used to validate handles */
    /* next connects all active resources of a resource manager and the garbaged resources of the manager's free list */
    picorsrc_Resource next;
    picorsrc_resource_type_t type;
    picorsrc_resource_name_t name;
    picoos_int8 lockCount;  /* count of current subscribers of this resource */
    picoos_File file;
    picoos_uint8 * raw_mem; /* pointer to allocated memory. NULL if preallocated. */
    /* picoos_uint32 size; */
    picoos_uint8 * start; /* start of content (after header) */
    picoknow_KnowledgeBase kbList;
} picorsrc_resource_t;


#define MAGIC_MASK 0x7049634F  /* pIcO */

#define SET_MAGIC_NUMBER(res) \
    (res)->magic = ((picoos_uint32) (res)) ^ MAGIC_MASK

#define CHECK_MAGIC_NUMBER(res) \
    ((res)->magic == (((picoos_uint32) (res)) ^ MAGIC_MASK))



/**
 * Returns non-zero if 'this' is a valid resource handle, zero otherwise.
 */
picoos_int16 picoctrl_isValidResourceHandle(picorsrc_Resource this)
{
    return (this != NULL) && CHECK_MAGIC_NUMBER(this);
}


static picorsrc_Resource picorsrc_newResource(picoos_MemoryManager mm)
{
    picorsrc_Resource this = picoos_allocate(mm, sizeof(*this));
    if (NULL != this) {
        SET_MAGIC_NUMBER(this);
        /* initialize */
        this->name[0] = NULLC;
        /* picoos_strlcpy(this->name, name,PICORSRC_MAX_RSRC_NAME_SIZ); */
        this->next = NULL;
        this->type = PICORSRC_TYPE_NULL;
        this->lockCount = 0;
        this->file = NULL;
        this->raw_mem = NULL;
        this->start = NULL;
        this->kbList = NULL;
        /* this->size=0; */
    }
    return this;
}

static void picorsrc_disposeResource(picoos_MemoryManager mm, picorsrc_Resource * this)
{
    if (NULL != (*this)) {
        (*this)->magic ^= 0xFFFEFDFC;
        /* we have to explicitly free 'raw_mem' here because in testing
           scenarios (where memory protection functionality is enabled)
           it might be allocated aside from normal memory */
        if ((*this)->raw_mem != NULL) {
            picoos_deallocProtMem(mm, (void *) &(*this)->raw_mem);
        }
        picoos_deallocate(mm,(void * *)this);
    }
}




static void picorsrc_initializeVoice(picorsrc_Voice this)
{
    picoos_uint16 i;
    if (NULL != this) {
        /* initialize */
        for (i=0; i<PICORSRC_KB_ARRAY_SIZE; i++) {
          this->kbArray[i] = NULL;
        }
        this->numResources = 0;
        this->next = NULL;
    }
}

static picorsrc_Voice picorsrc_newVoice(picoos_MemoryManager mm)
{
    picorsrc_Voice this = (picorsrc_Voice) picoos_allocate(mm,sizeof(*this));
    picorsrc_initializeVoice(this);
    return this;
}

/*
static void picorsrc_disposeVoice(picoos_MemoryManager mm, picorsrc_Voice * this)
{
    if (NULL != (*this)) {

        picoos_deallocate(mm,(void *)this);
    }
}
*/


/**  object   : VoiceDefinition
 *   shortcut : vdef
 *
 */

typedef struct picorsrc_voice_definition * picorsrc_VoiceDefinition;

typedef struct picorsrc_voice_definition {
    picoos_char voiceName[PICO_MAX_VOICE_NAME_SIZE];
    picoos_uint8 numResources;
    picorsrc_resource_name_t resourceName[PICO_MAX_NUM_RSRC_PER_VOICE];
    picorsrc_VoiceDefinition next;
} picorsrc_voice_definition_t;


static picorsrc_VoiceDefinition picorsrc_newVoiceDefinition(picoos_MemoryManager mm)
{
    /* picoos_uint8 i; */
    picorsrc_VoiceDefinition this = (picorsrc_VoiceDefinition) picoos_allocate(mm,sizeof(*this));
    if (NULL != this) {
        /* initialize */
        this->voiceName[0] = NULLC;
        this->numResources = 0;
        /*
        for (i=0; i < PICO_MAX_NUM_RSRC_PER_VOICE; i++) {
            this->resourceName[i][0] = NULLC;
        }
        */
        this->next = NULL;
    }
    return this;
}

/*
static void picorsrc_disposeVoiceDefinition(picoos_MemoryManager mm, picorsrc_VoiceDefinition * this)
{
    if (NULL != (*this)) {

        picoos_deallocate(mm,(void *)this);
    }
}
*/



/**  object   : ResourceManager
 *   shortcut : rm
 *
 */
typedef struct picorsrc_resource_manager {
    picoos_Common common;
    picoos_uint16 numResources;
    picorsrc_Resource resources, freeResources;
    picoos_uint16 numVoices;
    picorsrc_Voice voices, freeVoices;
    picoos_uint16 numVdefs;
    picorsrc_VoiceDefinition vdefs, freeVdefs;
    picoos_uint16 numKbs;
    picoknow_KnowledgeBase freeKbs;
    picoos_header_string_t tmpHeader;
} picorsrc_resource_manager_t;

pico_status_t picorsrc_createDefaultResource(picorsrc_ResourceManager this /*,
        picorsrc_Resource * resource */);


picorsrc_ResourceManager picorsrc_newResourceManager(picoos_MemoryManager mm, picoos_Common common /* , picoos_char * configFile */)
{
    picorsrc_ResourceManager this = picoos_allocate(mm,sizeof(*this));
    if (NULL != this) {
        /* initialize */
        this->common = common;
        this->numResources = 0;
        this->resources = NULL;
        this->freeResources = NULL;
        this->numVoices = 0;
        this->voices = NULL;
        this->freeVoices = NULL;
        this->numVdefs = 0;
        this->vdefs = NULL;
        this->freeVdefs = NULL;
    }
    return this;
}

void picorsrc_disposeResourceManager(picoos_MemoryManager mm, picorsrc_ResourceManager * this)
{
    if (NULL != (*this)) {
        /* terminate */
        picoos_deallocate(mm,(void *)this);
    }
}


/* ******* accessing resources **************************************/


static pico_status_t findResource(picorsrc_ResourceManager this, picoos_char * resourceName, picorsrc_Resource * rsrc) {
    picorsrc_Resource r;
    if (NULL == this) {
        return PICO_ERR_NULLPTR_ACCESS;
    }
    r = this->resources;
    while (NULL != r && (0 != picoos_strcmp(r->name,resourceName))) {
        r = r->next;
    }
    *rsrc = r;
    return PICO_OK;
}

static picoos_uint8 isResourceLoaded(picorsrc_ResourceManager this, picoos_char * resourceName) {
    picorsrc_Resource res;

    if (PICO_OK == findResource(this, resourceName,&res)){
        return (NULL != res);
    } else {
        return FALSE;
    }
 }

static pico_status_t parse_resource_name(picoos_char * fileName)
{
    PICODBG_DEBUG(("analysing file name %s",fileName));
    if (picoos_has_extension(fileName,
            (picoos_char *)PICO_BIN_EXTENSION)) {
        return PICO_OK;
    } else {
        return PICO_EXC_UNEXPECTED_FILE_TYPE;
    }
}



static pico_status_t readHeader(picorsrc_ResourceManager this,
        picoos_FileHeader header, picoos_uint32 * headerlen, picoos_File file)
{

    picoos_uint16 hdrlen1;
    picoos_uint32 n;
    pico_status_t status;


    /* read PICO header */
    status = picoos_readPicoHeader(file, headerlen);
    if (PICO_OK == status) {

    } else {
        return picoos_emRaiseException(this->common->em,status,NULL,(picoos_char *)"problem reading file header");
    }
    /* read header length (excluding length itself) */
    status = picoos_read_pi_uint16(file,&hdrlen1);
    PICODBG_DEBUG(("got header size %d",hdrlen1));

    if (PICO_OK == status) {
        *headerlen += 2;
        status = (hdrlen1 <= PICOOS_MAX_HEADER_STRING_LEN-1) ? PICO_OK : PICO_ERR_OTHER;
        if (PICO_OK == status) {
            n = hdrlen1;
            if (picoos_ReadBytes(file, (picoos_uint8 *) this->tmpHeader, &n) && hdrlen1 == n) {
                this->tmpHeader[hdrlen1] = NULLC;
                *headerlen += hdrlen1;
                PICODBG_DEBUG(("got header <%s>",this->tmpHeader));

                status = PICO_OK;
            } else {
                status = PICO_ERR_OTHER;
            }
        }
        if (PICO_OK == status) {
            status = picoos_hdrParseHeader(header, this->tmpHeader);
        }
    }
    return status;
}

static pico_status_t picorsrc_createKnowledgeBase(
        picorsrc_ResourceManager this,
        picoos_uint8 * data,
        picoos_uint32 size,
        picoknow_kb_id_t kbid,
        picoknow_KnowledgeBase * kb)
{
    (*kb) = picoknow_newKnowledgeBase(this->common->mm);
    if (NULL == (*kb)) {
        return PICO_EXC_OUT_OF_MEM;
    }
    (*kb)->base = data;
    (*kb)->size = size;
    (*kb)->id = kbid;
    switch (kbid) {
        case PICOKNOW_KBID_TPP_MAIN:
        case PICOKNOW_KBID_TPP_USER_1:
        case PICOKNOW_KBID_TPP_USER_2:
            return picokpr_specializePreprocKnowledgeBase(*kb, this->common);
            break;
        case PICOKNOW_KBID_TAB_GRAPHS:
            return picoktab_specializeGraphsKnowledgeBase(*kb, this->common);
            break;
        case PICOKNOW_KBID_TAB_PHONES:
            return picoktab_specializePhonesKnowledgeBase(*kb, this->common);
            break;
        case PICOKNOW_KBID_TAB_POS:
            return picoktab_specializePosKnowledgeBase(*kb, this->common);
            break;
        case PICOKNOW_KBID_FIXED_IDS:
            return picoktab_specializeIdsKnowledgeBase(*kb, this->common);
            break;
        case PICOKNOW_KBID_LEX_MAIN:
        case PICOKNOW_KBID_LEX_USER_1:
        case PICOKNOW_KBID_LEX_USER_2:
            return picoklex_specializeLexKnowledgeBase(*kb, this->common);
            break;
        case PICOKNOW_KBID_DT_POSP:
            return picokdt_specializeDtKnowledgeBase(*kb, this->common,
                                                     PICOKDT_KDTTYPE_POSP);
            break;
        case PICOKNOW_KBID_DT_POSD:
            return picokdt_specializeDtKnowledgeBase(*kb, this->common,
                                                     PICOKDT_KDTTYPE_POSD);
            break;
        case PICOKNOW_KBID_DT_G2P:
            return picokdt_specializeDtKnowledgeBase(*kb, this->common,
                                                     PICOKDT_KDTTYPE_G2P);
            break;
        case PICOKNOW_KBID_DT_PHR:
            return picokdt_specializeDtKnowledgeBase(*kb, this->common,
                                                     PICOKDT_KDTTYPE_PHR);
            break;
        case PICOKNOW_KBID_DT_ACC:
             return picokdt_specializeDtKnowledgeBase(*kb, this->common,
                                                      PICOKDT_KDTTYPE_ACC);
             break;
        case PICOKNOW_KBID_FST_SPHO_1:
        case PICOKNOW_KBID_FST_SPHO_2:
        case PICOKNOW_KBID_FST_SPHO_3:
        case PICOKNOW_KBID_FST_SPHO_4:
        case PICOKNOW_KBID_FST_SPHO_5:
        case PICOKNOW_KBID_FST_SPHO_6:
        case PICOKNOW_KBID_FST_SPHO_7:
        case PICOKNOW_KBID_FST_SPHO_8:
        case PICOKNOW_KBID_FST_SPHO_9:
        case PICOKNOW_KBID_FST_SPHO_10:
        case PICOKNOW_KBID_FST_WPHO_1:
        case PICOKNOW_KBID_FST_WPHO_2:
        case PICOKNOW_KBID_FST_WPHO_3:
        case PICOKNOW_KBID_FST_WPHO_4:
        case PICOKNOW_KBID_FST_WPHO_5:
        case PICOKNOW_KBID_FST_SVOXPA_PARSE:
        case PICOKNOW_KBID_FST_XSAMPA_PARSE:
        case PICOKNOW_KBID_FST_XSAMPA2SVOXPA:

             return picokfst_specializeFSTKnowledgeBase(*kb, this->common);
             break;

        case PICOKNOW_KBID_DT_DUR:
        case PICOKNOW_KBID_DT_LFZ1:
        case PICOKNOW_KBID_DT_LFZ2:
        case PICOKNOW_KBID_DT_LFZ3:
        case PICOKNOW_KBID_DT_LFZ4:
        case PICOKNOW_KBID_DT_LFZ5:
        case PICOKNOW_KBID_DT_MGC1:
        case PICOKNOW_KBID_DT_MGC2:
        case PICOKNOW_KBID_DT_MGC3:
        case PICOKNOW_KBID_DT_MGC4:
        case PICOKNOW_KBID_DT_MGC5:
            return picokdt_specializeDtKnowledgeBase(*kb, this->common,
                                                     PICOKDT_KDTTYPE_PAM);
            break;
        case PICOKNOW_KBID_PDF_DUR:
            return picokpdf_specializePdfKnowledgeBase(*kb, this->common,
                                                       PICOKPDF_KPDFTYPE_DUR);

            break;
        case PICOKNOW_KBID_PDF_LFZ:
            return picokpdf_specializePdfKnowledgeBase(*kb, this->common,
                                                       PICOKPDF_KPDFTYPE_MUL);
            break;
        case PICOKNOW_KBID_PDF_MGC:
            return picokpdf_specializePdfKnowledgeBase(*kb, this->common,
                                                       PICOKPDF_KPDFTYPE_MUL);
            break;
        case PICOKNOW_KBID_PDF_PHS:
            return picokpdf_specializePdfKnowledgeBase(*kb, this->common,
                                                       PICOKPDF_KPDFTYPE_PHS);
            break;



#if defined(PICO_DEBUG)
        case PICOKNOW_KBID_DBG:
            return picokdbg_specializeDbgKnowledgeBase(*kb, this->common);
            break;
#endif

        default:
            break;
    }
    return PICO_OK;
}


static pico_status_t picorsrc_releaseKnowledgeBase(
        picorsrc_ResourceManager this,
        picoknow_KnowledgeBase * kb)
{
    (*kb) = NULL;
    return PICO_OK;
}

static pico_status_t picorsrc_getKbList(picorsrc_ResourceManager this,
        picoos_uint8 * data,
        picoos_uint32 datalen,
        picoknow_KnowledgeBase * kbList)
{

    pico_status_t status = PICO_OK;
    picoos_uint32 curpos = 0, offset, size;
    picoos_uint8 i, numKbs, kbid;
    picoos_char str[PICOKNOW_MAX_KB_NAME_SIZ];
    picoknow_KnowledgeBase kb;

    *kbList = NULL;
    datalen = datalen;
    /* read number of fields */
    numKbs = data[curpos++];
    PICODBG_DEBUG(("number of kbs (unrestricted) = %i",numKbs));
    status = (numKbs <= PICOKNOW_MAX_NUM_RESOURCE_KBS) ? PICO_OK : PICO_EXC_FILE_CORRUPT;
    /* read in all kb names */
    PICODBG_DEBUG(("number of kbs = %i",numKbs));
    i = 0;
    while ((PICO_OK == status) && (i++ < numKbs)) {
        status = (picoos_get_str((picoos_char *)data,&curpos,str,PICOOS_MAX_FIELD_STRING_LEN)) ? PICO_OK :  PICO_EXC_FILE_CORRUPT;
        PICODBG_DEBUG(("contains knowledge base %s (status: %i)",str, status));
    }
    /* consume termination of last str */
    curpos++;
    i = 0;
    while ((PICO_OK == status) && (i++ < numKbs)) {
        kbid = data[curpos++];
        PICODBG_DEBUG(("got kb id %i, curpos now %i",kbid, curpos));
        status = picoos_read_mem_pi_uint32(data,&curpos,&offset);
        PICODBG_DEBUG(("got kb offset %i, curpos now %i",offset, curpos));
        status = picoos_read_mem_pi_uint32(data,&curpos,&size);
        PICODBG_DEBUG(("got kb size %i, curpos now %i",size, curpos));
        if (PICO_OK == status) {
            if (0 == offset) {
                /* currently we consider a kb mentioned in resource but with offset 0 (no knowledge) as
                 * different form a kb not mentioned at all. We might reconsider that later. */
                PICODBG_DEBUG((" kb (id %i) is mentioned but empty (base:%i, size:%i)",kb->id, kb->base, kb->size));
                status = picorsrc_createKnowledgeBase(this, NULL, size, (picoknow_kb_id_t)kbid, &kb);
            } else {
                status = picorsrc_createKnowledgeBase(this, data+offset, size, (picoknow_kb_id_t)kbid, &kb);
            }
            PICODBG_DEBUG(("found kb (id %i) starting at %i with size %i",kb->id, kb->base, kb->size));
            if (PICO_OK == status) {
              kb->next = *kbList;
              *kbList = kb;
            }
        }
    }
    if (PICO_OK != status) {
        kb = *kbList;
        while (NULL != kb) {
            picorsrc_releaseKnowledgeBase(this,&kb);
        }
    }

    return status;

}

/* load resource file. the type of resource file etc. are in the header,
 * then follows the directory, then the knowledge bases themselves (as byte streams) */

pico_status_t picorsrc_loadResource(picorsrc_ResourceManager this,
        picoos_char * fileName, picorsrc_Resource * resource)
{
    picorsrc_Resource res;
    picoos_uint32 headerlen, len,maxlen;
    picoos_file_header_t header;
    picoos_uint8 rem;
    pico_status_t status = PICO_OK;

    if (resource == NULL) {
        return PICO_ERR_NULLPTR_ACCESS;
    } else {
        *resource = NULL;
    }

    res = picorsrc_newResource(this->common->mm);

    if (NULL == res) {
        return picoos_emRaiseException(this->common->em,PICO_EXC_OUT_OF_MEM,NULL,NULL);
    }

    if (PICO_MAX_NUM_RESOURCES <= this->numResources) {
        picoos_deallocate(this->common->mm, (void *) &res);
        return picoos_emRaiseException(this->common->em,PICO_EXC_MAX_NUM_EXCEED,NULL,(picoos_char *)"no more than %i resources",PICO_MAX_NUM_RESOURCES);
    }

    /* ***************** parse file name for file type and parameters */

    if (PICO_OK != parse_resource_name(fileName)) {
        picoos_deallocate(this->common->mm, (void *) &res);
        return PICO_EXC_UNEXPECTED_FILE_TYPE;
    }

    /* ***************** get header info */

    /* open binary file for reading (no key, nrOfBufs, bufSize) */
    PICODBG_DEBUG(("trying to open file %s",fileName));
    if (!picoos_OpenBinary(this->common, &res->file, fileName)) {
        /* open didn't succeed */
        status = PICO_EXC_CANT_OPEN_FILE;
        PICODBG_ERROR(("can't open file %s",fileName));
        picoos_emRaiseException(this->common->em, PICO_EXC_CANT_OPEN_FILE,
                NULL, (picoos_char *) "%s", fileName);
    }
    if (PICO_OK == status) {
        status = readHeader(this, &header, &headerlen, res->file);
        /* res->file now positioned at first pos after header */
    }

    /* ***************** check header values */
    if (PICO_OK == status && isResourceLoaded(this, header.field[PICOOS_HEADER_NAME].value)) {
        /* lingware is allready loaded, do nothing */
        PICODBG_WARN((">>> lingware '%s' allready loaded",header.field[PICOOS_HEADER_NAME].value));
        picoos_emRaiseWarning(this->common->em,PICO_WARN_RESOURCE_DOUBLE_LOAD,NULL,(picoos_char *)"%s",header.field[PICOOS_HEADER_NAME].value);
        status = PICO_WARN_RESOURCE_DOUBLE_LOAD;
    }

    if (PICO_OK == status) {
            /* get data length */
        status = picoos_read_pi_uint32(res->file, &len);
        PICODBG_DEBUG(("found net resource len of %i",len));
        /* allocate memory */
        if (PICO_OK == status) {
            PICODBG_TRACE((">>> 2"));
            maxlen = len + PICOOS_ALIGN_SIZE; /* once would be sufficient? */
            res->raw_mem = picoos_allocProtMem(this->common->mm, maxlen);
            /* res->size = maxlen; */
            status = (NULL == res->raw_mem) ? PICO_EXC_OUT_OF_MEM : PICO_OK;
        }
        if (PICO_OK == status) {
            rem = (picoos_uint32) res->raw_mem % PICOOS_ALIGN_SIZE;
            if (rem > 0) {
                res->start = res->raw_mem + (PICOOS_ALIGN_SIZE - rem);
            } else {
                res->start = res->raw_mem;
            }

            /* read file contents into memory */
            status = (picoos_ReadBytes(res->file, res->start, &len)) ? PICO_OK
                    : PICO_ERR_OTHER;
            /* resources are read-only; the following write protection
             has an effect in test configurations only */
            picoos_protectMem(this->common->mm, res->start, len, /*enable*/TRUE);
        }
        /* note resource unique name */
        if (PICO_OK == status) {
            if (picoos_strlcpy(res->name,header.field[PICOOS_HEADER_NAME].value,PICORSRC_MAX_RSRC_NAME_SIZ) < PICORSRC_MAX_RSRC_NAME_SIZ) {
                PICODBG_DEBUG(("assigned name %s to resource",res->name));
                status = PICO_OK;
            } else {
                status = PICO_ERR_INDEX_OUT_OF_RANGE;
                PICODBG_ERROR(("failed assigning name %s to resource",
                               res->name));
                picoos_emRaiseException(this->common->em,
                                        PICO_ERR_INDEX_OUT_OF_RANGE, NULL,
                                        (picoos_char *)"resource %s",res->name);
            }
        }

        /* get resource type */
        if (PICO_OK == status) {
            if (!picoos_strcmp(header.field[PICOOS_HEADER_CONTENT_TYPE].value, PICORSRC_FIELD_VALUE_TEXTANA)) {
                res->type = PICORSRC_TYPE_TEXTANA;
            } else if (!picoos_strcmp(header.field[PICOOS_HEADER_CONTENT_TYPE].value, PICORSRC_FIELD_VALUE_SIGGEN)) {
                res->type = PICORSRC_TYPE_SIGGEN;
            } else if (!picoos_strcmp(header.field[PICOOS_HEADER_CONTENT_TYPE].value, PICORSRC_FIELD_VALUE_SIGGEN)) {
                res->type = PICORSRC_TYPE_USER_LEX;
            } else if (!picoos_strcmp(header.field[PICOOS_HEADER_CONTENT_TYPE].value, PICORSRC_FIELD_VALUE_SIGGEN)) {
                res->type = PICORSRC_TYPE_USER_PREPROC;
            } else {
                res->type = PICORSRC_TYPE_OTHER;
            }
        }

        if (PICO_OK == status) {
            /* create kb list from resource */
            status = picorsrc_getKbList(this, res->start, len, &res->kbList);
        }
    }

    if (status == PICO_OK) {
        /* add resource to rm */
        res->next = this->resources;
        this->resources = res;
        this->numResources++;
        *resource = res;
        PICODBG_DEBUG(("done loading resource %s from %s", res->name, fileName));
    } else {
        picorsrc_disposeResource(this->common->mm, &res);
        PICODBG_ERROR(("failed to load resource"));
    }

    if (status < 0) {
        return status;
    } else {
        return PICO_OK;
    }
}

static pico_status_t picorsrc_releaseKbList(picorsrc_ResourceManager this, picoknow_KnowledgeBase * kbList)
{
    picoknow_KnowledgeBase kbprev, kb;
    kb = *kbList;
    while (NULL != kb) {
        kbprev = kb;
        kb = kb->next;
        picoknow_disposeKnowledgeBase(this->common->mm,&kbprev);
    }
    *kbList = NULL;
    return PICO_OK;
}

/* unload resource file. (if resource file is busy, warn and don't unload) */
pico_status_t picorsrc_unloadResource(picorsrc_ResourceManager this, picorsrc_Resource * resource) {

    picorsrc_Resource r1, r2, rsrc;

    if (resource == NULL) {
        return PICO_ERR_NULLPTR_ACCESS;
    } else {
        rsrc = *resource;
    }

    if (rsrc->lockCount > 0) {
        return PICO_EXC_RESOURCE_BUSY;
    }
    /* terminate */
    if (rsrc->file != NULL) {
        picoos_CloseBinary(this->common, &rsrc->file);
    }
    if (NULL != rsrc->raw_mem) {
        picoos_deallocProtMem(this->common->mm, (void *) &rsrc->raw_mem);
        PICODBG_DEBUG(("deallocated raw mem"));
    }

    r1 = NULL;
    r2 = this->resources;
    while (r2 != NULL && r2 != rsrc) {
        r1 = r2;
        r2 = r2->next;
    }
    if (NULL == r1) {
        this->resources = rsrc->next;
    } else if (NULL == r2) {
        /* didn't find resource in rm! */
        return PICO_ERR_OTHER;
    } else {
        r1->next = rsrc->next;
    }

    if (NULL != rsrc->kbList) {
        picorsrc_releaseKbList(this, &rsrc->kbList);
    }

    picoos_deallocate(this->common->mm,(void **)resource);
    this->numResources--;

    return PICO_OK;
}


pico_status_t picorsrc_createDefaultResource(picorsrc_ResourceManager this
        /*, picorsrc_Resource * resource */)
{
    picorsrc_Resource res;
    pico_status_t status = PICO_OK;


    /* *resource = NULL; */

    if (PICO_MAX_NUM_RESOURCES <= this->numResources) {
        return picoos_emRaiseException(this->common->em,PICO_EXC_MAX_NUM_EXCEED,NULL,(picoos_char *)"no more than %i resources",PICO_MAX_NUM_RESOURCES);
    }

    res = picorsrc_newResource(this->common->mm);

    if (NULL == res) {
        return picoos_emRaiseException(this->common->em,PICO_EXC_OUT_OF_MEM,NULL,NULL);
    }

    if (picoos_strlcpy(res->name,PICOKNOW_DEFAULT_RESOURCE_NAME,PICORSRC_MAX_RSRC_NAME_SIZ) < PICORSRC_MAX_RSRC_NAME_SIZ) {
        PICODBG_DEBUG(("assigned name %s to default resource",res->name));
        status = PICO_OK;
    } else {
        PICODBG_ERROR(("failed assigning name %s to default resource",res->name));
        status = PICO_ERR_INDEX_OUT_OF_RANGE;
    }
    status = picorsrc_createKnowledgeBase(this, NULL, 0, (picoknow_kb_id_t)PICOKNOW_KBID_FIXED_IDS, &res->kbList);

    if (PICO_OK == status) {
        res->next = this->resources;
        this->resources = res;
        this->numResources++;
        /* *resource = res; */

    }


    return status;

}

pico_status_t picorsrc_rsrcGetName(picorsrc_Resource this,
        picoos_char * name, picoos_uint32 maxlen) {
    if (!picoctrl_isValidResourceHandle(this)) {
        return PICO_ERR_INVALID_ARGUMENT;
    }
    picoos_strlcpy(name, this->name,maxlen);
    return PICO_OK;
}


/* ******* accessing voice definitions **************************************/


static pico_status_t findVoiceDefinition(picorsrc_ResourceManager this,
        const picoos_char * voiceName, picorsrc_VoiceDefinition * vdef)
{
    picorsrc_VoiceDefinition v;
    PICODBG_DEBUG(("finding voice name %s",voiceName));
    if (NULL == this) {
        return PICO_ERR_NULLPTR_ACCESS;
    }
    v = this->vdefs;
    while (NULL != v && (0 != picoos_strcmp(v->voiceName,voiceName))) {
        PICODBG_DEBUG(("%s doesnt match",v->voiceName));
        v = v->next;
    }
    *vdef = v;
    if (v == NULL) {
        PICODBG_DEBUG(("didnt find voice name %s",voiceName));
    } else {
        PICODBG_DEBUG(("found voice name %s",voiceName));
   }
    return PICO_OK;
}


pico_status_t picorsrc_addResourceToVoiceDefinition(picorsrc_ResourceManager this,
        picoos_char * voiceName, picoos_char * resourceName)
{
    picorsrc_VoiceDefinition vdef;

    if (NULL == this) {
        PICODBG_ERROR(("this is NULL"));
        return PICO_ERR_NULLPTR_ACCESS;
    }
    if ((PICO_OK == findVoiceDefinition(this,voiceName,&vdef)) && (NULL != vdef)) {
        if (PICO_MAX_NUM_RSRC_PER_VOICE <= vdef->numResources) {
            return picoos_emRaiseException(this->common->em,PICO_EXC_MAX_NUM_EXCEED,NULL,(picoos_char *)"no more than %i resources per voice",PICO_MAX_NUM_RSRC_PER_VOICE);
        }
        if (picoos_strlcpy(vdef->resourceName[vdef->numResources++], resourceName,
                            PICORSRC_MAX_RSRC_NAME_SIZ) < PICORSRC_MAX_RSRC_NAME_SIZ) {
            PICODBG_DEBUG(("vdef added resource '%s' to voice '%s'",resourceName,voiceName));
            return PICO_OK;
        } else {
            PICODBG_ERROR(("illegal name (%s)",resourceName));
            return picoos_emRaiseException(this->common->em,PICO_EXC_NAME_ILLEGAL,NULL,(picoos_char *)"%s",resourceName);
        }

    } else {
        return picoos_emRaiseException(this->common->em,PICO_EXC_NAME_UNDEFINED,NULL,(picoos_char *)"%s",voiceName);
    }
}


pico_status_t picorsrc_createVoiceDefinition(picorsrc_ResourceManager this,
        picoos_char * voiceName)
{
    picorsrc_VoiceDefinition vdef;

    if (NULL == this) {
        PICODBG_ERROR(("this is NULL"));
        return PICO_ERR_NULLPTR_ACCESS;
    }
    if ((PICO_OK == findVoiceDefinition(this,voiceName,&vdef)) && (NULL != vdef)) {
        PICODBG_ERROR(("voice %s allready defined",voiceName));
        return picoos_emRaiseException(this->common->em,PICO_EXC_NAME_CONFLICT,NULL,NULL);
    }
    if (PICO_MAX_NUM_VOICE_DEFINITIONS <= this->numVdefs) {
        PICODBG_ERROR(("max number of vdefs exceeded (%i)",this->numVdefs));
        return picoos_emRaiseException(this->common->em,PICO_EXC_MAX_NUM_EXCEED,NULL,(picoos_char *)"no more than %i voice definitions",PICO_MAX_NUM_VOICE_DEFINITIONS);
    }
    if (NULL == this->freeVdefs) {
        vdef = picorsrc_newVoiceDefinition(this->common->mm);
    } else {
        vdef = this->freeVdefs;
        this->freeVdefs = vdef->next;
        vdef->voiceName[0] = NULLC;
        vdef->numResources = 0;
        vdef->next = NULL;
    }
    if (NULL == vdef) {
        return picoos_emRaiseException(this->common->em,PICO_EXC_OUT_OF_MEM,NULL,NULL);
    }
    if (picoos_strlcpy(vdef->voiceName, voiceName,
            PICO_MAX_VOICE_NAME_SIZE) < PICO_MAX_VOICE_NAME_SIZE) {
        vdef->next = this->vdefs;
        this->vdefs = vdef;
        this->numVdefs++;
        if (PICO_OK != picorsrc_addResourceToVoiceDefinition(this,voiceName,PICOKNOW_DEFAULT_RESOURCE_NAME)) {
            return picoos_emRaiseException(this->common->em,PICO_ERR_OTHER,NULL,(picoos_char *)"problem loading default resource %s",voiceName);
        }
        PICODBG_DEBUG(("vdef created (%s)",voiceName));
        return PICO_OK;
    } else {
        PICODBG_ERROR(("illegal name (%s)",voiceName));
        return picoos_emRaiseException(this->common->em,PICO_EXC_NAME_ILLEGAL,NULL,(picoos_char *)"%s",voiceName);
    }
}


pico_status_t picorsrc_releaseVoiceDefinition(picorsrc_ResourceManager this,
        picoos_char *voiceName)
{
    picorsrc_VoiceDefinition v, l;

    if (this == NULL) {
        return PICO_ERR_NULLPTR_ACCESS;
    }

    l = NULL;
    v = this->vdefs;
    while ((v != NULL) && (picoos_strcmp(v->voiceName, voiceName) != 0)) {
        l = v;
        v = v->next;
    }
    if (v != NULL) {
        /* remove v from vdefs list */
        if (l != NULL) {
            l->next = v->next;
        } else {
            this->vdefs = v->next;
        }
        /* insert v at head of freeVdefs list */
        v->next = this->freeVdefs;
        this->freeVdefs = v;
        this->numVdefs--;
        return PICO_OK;
    } else {
        /* we should rather return a warning, here */
        /* return picoos_emRaiseException(this->common->em,PICO_EXC_NAME_UNDEFINED,"%s", NULL); */
        return PICO_OK;
    }
}



/* ******* accessing voices **************************************/


/* create voice, given a voice name. the corresponding lock counts are incremented */

pico_status_t picorsrc_createVoice(picorsrc_ResourceManager this, const picoos_char * voiceName, picorsrc_Voice * voice) {

    picorsrc_VoiceDefinition vdef;
    picorsrc_Resource rsrc;
    picoos_uint8 i, required;
    picoknow_KnowledgeBase kb;
    /* pico_status_t status = PICO_OK; */

    PICODBG_DEBUG(("creating voice %s",voiceName));

    if (NULL == this) {
        PICODBG_ERROR(("this is NULL"));
        return PICO_ERR_NULLPTR_ACCESS;

    }
    /* check number of voices */
    if (PICORSRC_MAX_NUM_VOICES <= this->numVoices) {
        PICODBG_ERROR(("PICORSRC_MAX_NUM_VOICES exceeded"));
        return picoos_emRaiseException(this->common->em,PICO_EXC_MAX_NUM_EXCEED,NULL,(picoos_char *)"no more than %i voices",PICORSRC_MAX_NUM_VOICES);
    }

    /* find voice definition for that name */
    if (!(PICO_OK == findVoiceDefinition(this,voiceName,&vdef)) || (NULL == vdef)) {
        PICODBG_ERROR(("no voice definition for %s",voiceName));
        return picoos_emRaiseException(this->common->em,PICO_EXC_NAME_UNDEFINED,NULL,(picoos_char *)"voice definition %s",voiceName);

    }
    PICODBG_DEBUG(("found voice definition for %s",voiceName));

    /* check that resources are loaded */
    for (i = 0; i < vdef->numResources; i++) {
        required = (NULLC != vdef->resourceName[i][0]);
        if (required && !isResourceLoaded(this,vdef->resourceName[i])) {
            PICODBG_ERROR(("resource missing"));
            return picoos_emRaiseException(this->common->em,PICO_EXC_RESOURCE_MISSING,NULL,(picoos_char *)"resource %s for voice %s",vdef->resourceName[i],voiceName);
        }
    }

    /* allocate new voice */
    if (NULL == this->freeVoices) {
        *voice = picorsrc_newVoice(this->common->mm);
    } else {
        *voice = this->freeVoices;
        this->freeVoices = (*voice)->next;
        picorsrc_initializeVoice(*voice);
    }
    if (*voice == NULL) {
        return picoos_emRaiseException(this->common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
    }
    this->numVoices++;

    /* copy resource kb pointers into kb array of voice */
    for (i = 0; i < vdef->numResources; i++) {
        required = (NULLC != vdef->resourceName[i][0]);
        if (required) {
            findResource(this,vdef->resourceName[i],&rsrc);
           (*voice)->resourceArray[(*voice)->numResources++] = rsrc;
            rsrc->lockCount++;
            kb = rsrc->kbList;
            while (NULL != kb) {
                if (NULL != (*voice)->kbArray[kb->id]) {
                    picoos_emRaiseWarning(this->common->em,PICO_WARN_KB_OVERWRITE,NULL, (picoos_char *)"%i", kb->id);
                    PICODBG_WARN(("overwriting knowledge base of id %i", kb->id));

                }
                PICODBG_DEBUG(("setting knowledge base of id %i", kb->id));

                (*voice)->kbArray[kb->id] = kb;
                kb = kb->next;
            }
        }
    } /* for */

    return PICO_OK;
}

/* dispose voice. the corresponding lock counts are decremented. */

pico_status_t picorsrc_releaseVoice(picorsrc_ResourceManager this, picorsrc_Voice * voice)
{
    picoos_uint16 i;
    picorsrc_Voice v = *voice;
    if (NULL == this || NULL == v) {
        return PICO_ERR_NULLPTR_ACCESS;
    }
    for (i = 0; i < v->numResources; i++) {
        v->resourceArray[i]->lockCount--;
    }
    v->next = this->freeVoices;
    this->freeVoices = v;
    this->numVoices--;

    return PICO_OK;
}

#ifdef __cplusplus
}
#endif

/* end picorsrc.c */
