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

#include "core.h"

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

void AI_Memory_DataTag_E_Free(AI_Memory_DataTag_E *tag)
{
    if(tag->pattern != NULL){
        AI_Array_FreePointer(tag->pattern);
        AI_Array_Free(&tag->pattern);
    }
    free(tag);
    return;
}

void AI_Memory_DataTag_E_ReadSaveData(const char line[])
{
    AI_Array *separated;
    AI_Memory_DataTag_E *tagE;
    
    separated = AI_Array_Initialize();
    AI_Array_GetSeparatedStringByArray(&separated, &AI_SystemStringList, line);
    
    tagE = AI_Memory_DataTag_E_Allocate();
    tagE->dataID = AI_Memory_AddRootData(AI_strtol(line, NULL, 0), tagE);
    if(tagE->dataID == AI_DATAID_NULL){
        //add failed.
        AI_Memory_DataTag_E_Free(tagE);
    } else{
        tagE->meanID = AI_strtol((const char *)AI_Array_GetPointerByIndex(separated, 4), NULL, 0);
        AI_Array_GetSeparatedStringByArrayWithoutListWord(&tagE->pattern, &AI_SystemStringList_ReadExpressionData, (const char *)AI_Array_GetPointerByIndex(separated, 2));
        AI_Array_AppendLast(&AI_MainMemory.list_expresson, tagE->dataID, tagE);
    }
    
    AI_Array_FreePointer(separated);
    AI_Array_Free(&separated);
    
    return;
}

void AI_Memory_DataTag_E_WriteSaveData(FILE *fp, AI_Memory_DataTag_E *tag)
{
    int i, i_max;
    
    fprintf(fp, "E0x%08X:", tag->dataID);
    i_max = AI_Array_GetNumberOfTags(tag->pattern);
    for(i = 0; i < i_max; i++){
        fprintf(fp, "%s,", AI_Array_GetPointerByIndex(tag->pattern, i));
    }
    fprintf(fp, ":0x%08X\n", tag->meanID);
    return;
}

AI_Array *AI_Memory_Expression_GetMeanFromSeparatedString(const AI_Array *separated)
{
    AI_Array *retlist;  //MeanDataID:*AI_Memory_DataTag_E(ref)
    AI_Array *pattern;
    AI_Memory_DataTag_E *tagE;
    int i, i_max;
    
    retlist = AI_Array_Initialize();
    
    i_max = AI_Array_GetNumberOfTags(AI_MainMemory.list_expresson);
    for(i = 0; i < i_max; i++){
        tagE = (AI_Memory_DataTag_E *)AI_Array_GetPointerByIndex(AI_MainMemory.list_expresson, i);
        pattern = tagE->pattern;
        if(AI_Memory_Expression_CheckString(pattern, separated, 0, 0)){
            AI_Array_AppendLast(&retlist, tagE->meanID, tagE);
        }
    }
        
    return  retlist;
}

int AI_Memory_Expression_CheckString(const AI_Array *pattern, const AI_Array *separated, int patternstart, int separatedstart)
{
    //True:Equal False:Not equal
    
    int pattern_max, separated_max;
    int i, separated_i;
    const char *patternstr;
    const char *separatedstr;
    
    pattern_max = AI_Array_GetNumberOfTags(pattern);
    separated_max = AI_Array_GetNumberOfTags(separated);
    separated_i = separatedstart;
    for(i = patternstart; i < pattern_max; i++){
        patternstr = (const char *)AI_Array_GetPointerByIndex(pattern, i);
        separatedstr = (const char *)AI_Array_GetPointerByIndex(separated, separated_i);
        if(patternstr[0] == '?'){
            separated_i++;
        } else if(patternstr[0] == '*'){
            for(i++; i < pattern_max; i++){
                patternstr = (const char *)AI_Array_GetPointerByIndex(pattern, i);
                if(patternstr[0] == '?'){
                    separated_i++;
                } else if(patternstr[0] == '*'){
                    
                } else{
                    break;
                }
            }
            for(; separated_i < separated_max; separated_i++){
                if(AI_Memory_Expression_CheckString(pattern, separated, i, separated_i)){
                    i = pattern_max;
                    separated_i = separated_max;
                    break;
                }
            }
            break;
        } else{
            if(AI_strtol(patternstr, NULL, 0) == AI_Array_GetDataIDByIndex(separated, separated_i)){
                separated_i++;
            } else{
                break;
            }
        }
    }
    if(i == pattern_max && (separated_i == separated_max || ((const char *)AI_Array_GetPointerByIndex(pattern, pattern_max - 1))[0] == '*')){
        return True;
    }
    return False;
}
