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

#ifndef AI002_core_h
#define AI002_core_h

//includes
//+---C99 standard headers
#include <stdio.h>
//+-------FILENAME_MAX
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#include <time.h>

//+---Project headers
#include "sysdata.h"

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;

#define True    1
#define False   0

//preprocessor functions
#ifdef DEBUG
#define debug(s, ...)   printf("AI:Debug:%s:%s:%d:" s "\n", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__);
#else
#define debug(s, ...)
#endif

#define AI_SpeakSystem(s, ...)  printf("AI:System:%s:" s, __FUNCTION__, __VA_ARGS__);
#define AI_SpeakError(s, ...)   printf("AI:Error:%s:%d:" s, __FUNCTION__, __LINE__, __VA_ARGS__);

//define values
#define AI_ARRAY_PACKDATAS  7
#define AI_DATAID_NULL  0
#define AI_MAX_STRINGLENGTH 1024
#define AI_ARRAY_INDEX_NOTFOUND -1
#define AI_MEMORY_FILENAME  "memory.txt"

//typedef
typedef struct AI_ARRAY_TAG {
    uint dataID;
    void *pointer;
} AI_ArrayTag;

typedef struct AI_ARRAY {
    int using_tags;    //Number of using tags in this pack.
    AI_ArrayTag tag[AI_ARRAY_PACKDATAS];
    struct AI_ARRAY *next;
} AI_Array;

typedef struct AI_MEMORY_WORKING_SET {
    char *filename;
    AI_Array *rootdata; //pointer = AI_Memory_DataTag_X(instace)
    int mode;
    struct AI_MEMORY_WORKING_SET_FLAGS {
        unsigned no_asking_user : 1;
    } flags;
    
    AI_Array *list_word;    //pointer = char[](ref)
    AI_Array *list_mean;    //pointer = char[](ref)
    AI_Array *list_expresson;   //pointer = *AI_Memory_DataTag_E(ref)
} AI_Memory_WorkingSet;

typedef struct AI_MEMORY_DATA_TAG_W {
    char type;
    uint dataID;
    char *string;
    int length;
    AI_Array *part_of_speech;
} AI_Memory_DataTag_W;

typedef struct AI_MEMORY_DATA_TAG_M {
    char type;
    uint dataID;
    char *description;
} AI_Memory_DataTag_M;

typedef struct AI_MEMORY_DATA_TAG_E {
    char type;
    uint dataID;
    AI_Array *pattern;
    uint meanID;
} AI_Memory_DataTag_E;

//functions
//@array.c
AI_Array *AI_Array_Initialize(void);
AI_Array *AI_Array_Allocate(void);
void AI_Array_Free(AI_Array **start);
void AI_Array_FreePointer(AI_Array *start);
uint AI_Array_GetDataIDByIndex(const AI_Array *start, int index);
void *AI_Array_GetPointerByIndex(const AI_Array *start, int index);
int AI_Array_GetIndexByDataID(const AI_Array *start, int dataID);
void *AI_Array_GetPointerByDataID(const AI_Array *start, int dataID);
int AI_Array_GetNumberOfTags(const AI_Array *start);
int AI_Array_AppendLast(AI_Array **start, uint dataID, void *pointer);
AI_ArrayTag *AI_Array_GetTagPointerByIndex(AI_Array *start, int index);
//@command.c
void AI_Command_System_info(AI_Array *separated);
void AI_Command_System_setmode(AI_Array *separated);
//@constant.c
extern AI_Array AI_SystemStringList;
extern AI_Array AI_SystemStringList_ReadExpressionData;
//@dpndenv.c
void AI_Environment_SetCurrentWorkingDirectory(const char apppath[]);
//@main.c
int AI_Speak(char *format, ...);
char *AI_ReadInput(char line[], int linesize, FILE *fp);
int AI_strtol(const char s[], char **invalidchar, int base);
//@mem_e.c
AI_Memory_DataTag_E *AI_Memory_DataTag_E_Allocate(void);
void AI_Memory_DataTag_E_Free(AI_Memory_DataTag_E *tag);
void AI_Memory_DataTag_E_ReadSaveData(const char line[]);
void AI_Memory_DataTag_E_WriteSaveData(FILE *fp, AI_Memory_DataTag_E *tag);
AI_Array *AI_Memory_Expression_GetMeanFromSeparatedString(const AI_Array *separated);
int AI_Memory_Expression_CheckString(const AI_Array *pattern, const AI_Array *separated, int patternstart, int separatedstart);
//@mem_m.c
AI_Memory_DataTag_M *AI_Memory_DataTag_M_Allocate(void);
void AI_Memory_DataTag_M_Free(AI_Memory_DataTag_M *tag);
void AI_Memory_DataTag_M_ReadSaveData(const char line[]);
void AI_Memory_DataTag_M_WriteSaveData(FILE *fp, AI_Memory_DataTag_M *tag);
//@mem_w.c
AI_Memory_DataTag_W *AI_Memory_DataTag_W_Allocate(void);
void AI_Memory_DataTag_W_Free(AI_Memory_DataTag_W *tag);
void AI_Memory_DataTag_W_ReadSaveData(const char line[]);
void AI_Memory_DataTag_W_WriteSaveData(FILE *fp, AI_Memory_DataTag_W *tag);
int AI_Memory_Word_SortListByLength(AI_Array *start);
uint AI_Memory_Word_GetDataIDByString(const char s[]);
//@memory.c
extern AI_Memory_WorkingSet AI_MainMemory;
void AI_Memory_InitializeWorkingSet(void);
char AI_Memory_DataTag_GetType(void *pointer);
int AI_Memory_ReadMemory(const char filename[]);
int AI_Memory_SaveMemory(const char filename[]);
int AI_Memory_AddRootData(uint dataID, void *tag);
//@separate.c
int AI_Array_GetSeparatedStringByArray(AI_Array **separated, AI_Array *list, const char s[]);
int AI_Array_GetSeparatedStringByArrayWithoutListWord(AI_Array **separated, AI_Array *list, const char s[]);
//@string.c
void AI_String_DeleteCRLF(char s[]);
char *AI_String_ExtractByLength(const char s[], int start, int len);
int AI_String_GetLength(const char s[]);
int AI_String_CompareString(const char s[], const char search[]);
int AI_String_CompareString_Strict(const char s[], const char search[]);
int AI_String_SearchLocationFromArray(const char s[], AI_Array *start, int *location);
//@think.c
void AI_ThinkMain(void);
int AI_Think_GetSeparatedStringByMemory(AI_Array **separated, const char s[]);




#endif
