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

#include "core.h"

AI_Memory_WorkingSet AI_MainMemory;

void AI_Memory_InitializeWorkingSet(void)
{
    memset(&AI_MainMemory, 0, sizeof(AI_Memory_WorkingSet));
    
    return;
}

char AI_Memory_DataTag_GetType(void *pointer)
{
    return *((char *)pointer);
}

int AI_Memory_ReadMemory(const char filename[])
{
    FILE *fp;
    char line[AI_MAX_STRINGLENGTH];

    if(filename == NULL){
        filename = AI_MainMemory.filename;
    }
    
    fp = fopen(filename, "r");
    if(fp == NULL){
        AI_SpeakError("Can't open [%s]\n", AI_MainMemory.filename);
        return 1;
    }
    
    if(filename != AI_MainMemory.filename){
        free(AI_MainMemory.filename);
        AI_MainMemory.filename = AI_String_ExtractByLength(filename, 0, PATH_MAX);
    }
    
    for(;;){
        if(AI_ReadInput(line, sizeof(line), fp) == NULL){
            break;
        }

        if(line[0] != '\0'){
            if(line[0] == 'W'){
                AI_Memory_DataTag_W_ReadSaveData(&line[1]);
            } else if(line[0] == 'M'){
                AI_Memory_DataTag_M_ReadSaveData(&line[1]);
            } else if(line[0] == 'E'){
                AI_Memory_DataTag_E_ReadSaveData(&line[1]);
            } else{
                AI_SpeakError("Unknown datatype [%c].\n", line[0]);
            }
        }
    }
    
    fclose(fp);
    AI_SpeakSystem("Read %d datas.\n", AI_Array_GetNumberOfTags(AI_MainMemory.rootdata));
    
    AI_Memory_Word_SortListByLength(AI_MainMemory.list_word);
    AI_SpeakSystem("Sorted %d word datas.\n", AI_Array_GetNumberOfTags(AI_MainMemory.list_word));

    return 0;
}

int AI_Memory_SaveMemory(const char filename[])
{
    
    FILE *fp;
    int i, i_max;
    void *tag;

    if(filename == NULL){
        filename = AI_MainMemory.filename;
    }
    
    fp = fopen(filename, "w");
    if(fp == NULL){
        AI_SpeakError("Can't open [%s]\n", AI_MainMemory.filename);
        return 1;
    }
    
    if(filename != AI_MainMemory.filename){
        free(AI_MainMemory.filename);
        AI_MainMemory.filename = AI_String_ExtractByLength(filename, 0, PATH_MAX);
    }
    
    i_max = AI_Array_GetNumberOfTags(AI_MainMemory.rootdata);
    for(i = 0; i < i_max; i++){
        tag = AI_Array_GetPointerByIndex(AI_MainMemory.rootdata, i);
        switch(AI_Memory_DataTag_GetType(tag)){
            case 'W':
                AI_Memory_DataTag_W_WriteSaveData(fp, (AI_Memory_DataTag_W *)tag);
                break;
            case 'M':
                AI_Memory_DataTag_M_WriteSaveData(fp, (AI_Memory_DataTag_M *)tag);
                break;
            case 'E':
                AI_Memory_DataTag_E_WriteSaveData(fp, (AI_Memory_DataTag_E *)tag);
                break;
        }
    }
    
    fclose(fp);
    
    AI_SpeakSystem("Saved %d datas to [%s].\n", AI_Array_GetNumberOfTags(AI_MainMemory.rootdata), AI_MainMemory.filename);
    
    return 0;

}

int AI_Memory_AddRootData(uint dataID, void *tag)
{
    //retv == datanumber(AI_DATANUMBER_NULL:error)
    int i, i_max, j;
    
    //重複チェック
    if(AI_Array_GetIndexByDataID(AI_MainMemory.rootdata, dataID) != AI_ARRAY_INDEX_NOTFOUND){
        AI_SpeakError("datanumber %d is conflicted. Not added.\n", dataID);
        return AI_DATAID_NULL;
    }
    if(dataID == 0){
        //自動割当
        i_max = AI_Array_GetNumberOfTags(AI_MainMemory.rootdata);
        dataID = 1;
        for(i = 0; i < i_max; i++){
            j = AI_Array_GetDataIDByIndex(AI_MainMemory.rootdata, i);
            if(j > dataID){
                dataID = j + 1;
            }
        }
        AI_SpeakSystem("datanumber 0 is reserved. This data added as datanumber %d.\n", dataID);
    }
    AI_Array_AppendLast(&AI_MainMemory.rootdata, dataID, tag);
    return dataID;
}
