
typedef struct {
  u32 DicIndex;
  s32 Rate;
  u8 *pOkuriStr;
} TDicUser_Item;

static u32 DicUser_ItemsCount;
static TDicUser_Item *DicUser_pItems;

#define UserDicID (0x31554b53)

static void DicUser_Init(void)
{
  DicUser_ItemsCount=0;
  DicUser_pItems=NULL;
  
  _consolePrintf("DicUser: Load user dic file.\n");
  
  FAT_FILE *pf=Shell_FAT_fopen_Root(UserDicFilename);
  
  u32 ID;
  FAT2_fread(&ID,4,1,pf);
  
  if(ID!=UserDicID){
    _consolePrintf("DicUser: Illigal ID. ignored.\n");
    }else{
    FAT2_fread(&DicUser_ItemsCount,4,1,pf);
    if(DicUser_ItemsCount==0){
      _consolePrintf("DicUser: User dic is blank. ignored.\n");
      }else{
      _consolePrintf("DicUser: Load items. (%d)\n",DicUser_ItemsCount);
      DicUser_pItems=(TDicUser_Item*)safemalloc(&MM_SKKDic,DicUser_ItemsCount*sizeof(TDicUser_Item));
      for(u32 idx=0;idx<DicUser_ItemsCount;idx++){
        TDicUser_Item *pui=&DicUser_pItems[idx];
        FAT2_fread(&pui->DicIndex,4,1,pf);
        FAT2_fread(&pui->Rate,4,1,pf);
        u8 len;
        FAT2_fread(&len,1,1,pf);
        if(len==0){
          pui->pOkuriStr=NULL;
          }else{
          pui->pOkuriStr=(u8*)safemalloc(&MM_SKKDic,len+1);
          FAT2_fread(pui->pOkuriStr,1,len,pf);
          pui->pOkuriStr[len]=0;
        }
      }
    }
  }
  
  FAT2_fclose(pf); pf=NULL;
  
  _consolePrintf("DicUser: Loaded.\n");
}

static void DicUser_Free(void)
{
  _consolePrintf("DicUser: Save user dic file.\n");
  
  if(DicUser_ItemsCount==0){
    _consolePrintf("DicUser: User dic is blank. ignored.\n");
    }else{
    FAT_FILE *pf=Shell_FAT_fopenwrite_Root(UserDicFilename);
    u32 ID=UserDicID;
    FAT2_fwrite(&ID,4,1,pf);
    FAT2_fwrite(&DicUser_ItemsCount,4,1,pf);
    
    _consolePrintf("DicUser: Save items. (%d)\n",DicUser_ItemsCount);
    for(u32 idx=0;idx<DicUser_ItemsCount;idx++){
      TDicUser_Item *pui=&DicUser_pItems[idx];
      FAT2_fwrite(&pui->DicIndex,4,1,pf);
      FAT2_fwrite(&pui->Rate,4,1,pf);
      u32 len=0;
      if(pui->pOkuriStr!=NULL){
        while(pui->pOkuriStr[len]!=0){
          len++;
        }
      }
      FAT2_fwrite(&len,1,1,pf);
      if(len!=0){
        FAT2_fwrite(pui->pOkuriStr,1,len,pf);
      }
    }
    FAT2_fclose(pf); pf=NULL;
    
    _consolePrintf("DicUser: Saved.\n");
  }
  
  for(u32 idx=0;idx<DicUser_ItemsCount;idx++){
    TDicUser_Item *pui=&DicUser_pItems[idx];
    if(pui->pOkuriStr!=NULL){
      safefree(&MM_SKKDic,pui->pOkuriStr); pui->pOkuriStr=NULL;
    }
  }
  DicUser_ItemsCount=0;
  
  if(DicUser_pItems!=NULL){
    safefree(&MM_SKKDic,DicUser_pItems); DicUser_pItems=NULL;
  }
}

static void DicUser_RegistSelectedItem(const u32 DicIndex,const u8 *pOkuriStr)
{
  u32 TagDicUserIndex=(u32)-1;
  
  for(u32 idx=0;idx<DicUser_ItemsCount;idx++){
    TDicUser_Item *pui=&DicUser_pItems[idx];
    if(pui->DicIndex==DicIndex){
      TagDicUserIndex=idx;
      break;
    }
  }
  
  if(TagDicUserIndex==(u32)-1){
    DicUser_ItemsCount++;
    DicUser_pItems=(TDicUser_Item*)saferealloc(&MM_SKKDic,DicUser_pItems,DicUser_ItemsCount*sizeof(TDicUser_Item));
    _consolePrintf("DicUser: Add new item. (%d)\n",DicUser_ItemsCount);
    TagDicUserIndex=DicUser_ItemsCount-1;
    TDicUser_Item *pui=&DicUser_pItems[TagDicUserIndex];
    pui->DicIndex=DicIndex;
    pui->Rate=0;
    pui->pOkuriStr=NULL;
  }
  
  {
    TDicUser_Item *pui=&DicUser_pItems[TagDicUserIndex];
    pui->Rate++;
    u32 len=0;
    if(pOkuriStr!=NULL){
      while(pOkuriStr[len]!=0){
        len++;
      }
    }
    if(len==0){
      if(pui->pOkuriStr!=NULL){
        safefree(&MM_SKKDic,pui->pOkuriStr); pui->pOkuriStr=NULL;
      }
      }else{
      pui->pOkuriStr=(u8*)saferealloc(&MM_SKKDic,pui->pOkuriStr,len+1);
      for(u32 idx=0;idx<len;idx++){
        pui->pOkuriStr[idx]=pOkuriStr[idx];
      }
      pui->pOkuriStr[len]=0;
    }
    _consolePrintf("DicUser: Registed. %d, %d, %d, %d.\n",TagDicUserIndex,pui->DicIndex,pui->Rate,len);
  }
}

static s32 DicUser_GetRate(const u32 DicIndex)
{
  for(u32 idx=0;idx<DicUser_ItemsCount;idx++){
    TDicUser_Item *pui=&DicUser_pItems[idx];
    if(pui->DicIndex==DicIndex) return(pui->Rate*4);
  }
  
  return(0);
}

static const u8* DicUser_GetOkuriBinStr(const u32 DicIndex)
{
  for(u32 idx=0;idx<DicUser_ItemsCount;idx++){
    TDicUser_Item *pui=&DicUser_pItems[idx];
    if(pui->DicIndex==DicIndex) return(pui->pOkuriStr);
  }
  
  return(NULL);
}

