//
//  mem_w.c
//  AI002
//
//  Created by 西田　耀 on 13/01/03.
//  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.
//

#include "core.h"

AI_Memory_DataTag_W *AI_Memory_DataTag_W_Allocate(void)
{
    AI_Memory_DataTag_W *tag;
    
    tag = (AI_Memory_DataTag_W *)malloc(sizeof(AI_Memory_DataTag_W));
    
    if(tag == NULL){
        AI_SpeakError("Allocation error.\n", NULL);
        exit(EXIT_FAILURE);
    }
    
    memset(tag, 0, sizeof(AI_Memory_DataTag_W));
    tag->type = 'W';
    
    return tag;
}

void AI_Memory_DataTag_W_Free(AI_Memory_DataTag_W *tag)
{
    if(tag->string != NULL){
        free(tag->string);
    }
    free(tag);
    return;
}

void AI_Memory_DataTag_W_ReadSaveData(const char line[])
{
    AI_Array *separated;
    AI_Memory_DataTag_W *tagW;
    
    separated = AI_Array_Initialize();
    AI_Array_GetSeparatedStringByArray(&separated, &AI_SystemStringList, line);
    
    tagW = AI_Memory_DataTag_W_Allocate();
    tagW->dataID = AI_Memory_AddRootData(AI_strtol(line, NULL, 0), tagW);
    if(tagW->dataID == AI_DATAID_NULL){
        //add failed.
        AI_Memory_DataTag_W_Free(tagW);
    } else{
        tagW->string = AI_String_ExtractByLength(AI_Array_GetPointerByIndex(separated, 2), 0, AI_MAX_STRINGLENGTH);
        tagW->length = AI_String_GetLength(tagW->string);
        if(AI_Memory_Word_GetDataIDByString(tagW->string) != AI_DATAID_NULL){
            AI_SpeakError("word[%s] has already existed.\n", tagW->string);
        } else{
            AI_Array_AppendLast(&AI_MainMemory.list_word, tagW->dataID, tagW->string);
        }
    }

    AI_Array_FreePointer(separated);
    AI_Array_Free(&separated);
    
    return;
}

void AI_Memory_DataTag_W_WriteSaveData(FILE *fp, AI_Memory_DataTag_W *tag)
{
    fprintf(fp, "W0x%08X:%s\n", tag->dataID, tag->string);
    return;
}

int AI_Memory_Word_SortListByLength(AI_Array *start)
{
    //AI_Array(uint dataID, string[])をAI_の大きい順に並べる。
    //バブルソートなので遅いけれどとりあえず実装
    //Nullポインタを考慮していない。
    int i, i_max, exchanged;
    AI_ArrayTag *tag0, *tag1;
    AI_ArrayTag temptag;
    
    i_max = AI_Array_GetNumberOfTags(start) - 1;
    for(exchanged = 1; exchanged != 0; ){
        exchanged = 0;
        tag1 = AI_Array_GetTagPointerByIndex(start, 0);
        for(i = 0; i < i_max; i++){
            tag0 = tag1;
            tag1 = AI_Array_GetTagPointerByIndex(start, i + 1);
            if(((AI_Memory_DataTag_W *)AI_Array_GetPointerByDataID(AI_MainMemory.rootdata, tag0->dataID))->length < ((AI_Memory_DataTag_W *)AI_Array_GetPointerByDataID(AI_MainMemory.rootdata, tag1->dataID))->length){
                //temp <- tag0
                temptag.dataID = tag0->dataID;
                temptag.pointer = tag0->pointer;
                //tag0 <- tag1
                tag0->dataID = tag1->dataID;
                tag0->pointer = tag1->pointer;
                //tag1 <- temp
                tag1->dataID = temptag.dataID;
                tag1->pointer = temptag.pointer;
                
                tag1 = tag0;
                exchanged++;
            }
        }
    }
    return 0;
};

uint AI_Memory_Word_GetDataIDByString(const char s[])
{
    int s_len;
    int i, i_max;
    
    s_len = AI_String_GetLength(s);
    
    i_max = AI_Array_GetNumberOfTags(AI_MainMemory.list_word);
    for(i = 0; i < i_max; i++){
        if(AI_String_CompareString_Strict((const char *)AI_Array_GetPointerByIndex(AI_MainMemory.list_word, i), s)){
            return AI_Array_GetDataIDByIndex(AI_MainMemory.list_word, i);
        }
    }
    return AI_DATAID_NULL;
}
