
static u32 Selector_SelectIndex;
static bool Selector_FullMode;

typedef struct {
  UnicodeChar wc;
  s32 x,y,w,h;
  CglCanvas *pcan;
} TSelectorItem;

static u32 SelectorItemsCount;
static TSelectorItem *pSelectorItems;

static u32 Selector_GetIndexFromPoint(s32 mx,s32 my)
{
  for(u32 idx=0;idx<SelectorItemsCount;idx++){
    TSelectorItem *pitem=&pSelectorItems[idx];
    if((pitem->x<=mx)&&(mx<(pitem->x+pitem->w))&&(pitem->y<=my)&&(my<(pitem->y+pitem->h))) return(idx);
  }
  
  return((u32)-1);
}

static void Selector_AddItem(UnicodeChar wc)
{
  for(u32 idx=0;idx<SelectorItemsCount;idx++){
    TSelectorItem *pitem=&pSelectorItems[idx];
    if(pitem->wc==wc) return;
  }
  
  pSelectorItems=(TSelectorItem*)saferealloc(&MM_Temp,pSelectorItems,sizeof(TSelectorItem)*(SelectorItemsCount+1));
  TSelectorItem *pitem=&pSelectorItems[SelectorItemsCount];
  
  pitem->wc=wc;
  
  u32 x,y,w,h;
  u32 collev;
  
  if(Selector_FullMode==true){
    x=8; y=22; w=16; h=16;
    u32 xidx=SelectorItemsCount%13;
    u32 yidx=SelectorItemsCount/13;
    x+=xidx*(w+3);
    y+=yidx*(h+3);
    collev=28;
    }else{
    x=128; y=22; w=20; h=20;
    u32 xidx=SelectorItemsCount%5;
    u32 yidx=SelectorItemsCount/5;
    x+=xidx*(w+5);
    y+=(3-yidx)*(h+4);
    collev=SelectorItemsCount;
    if(31<collev) collev=31;
    collev=31-collev;
  }
  
  if((ScreenHeight-h)<=y) return;
  
  pitem->x=x;
  pitem->y=y;
  pitem->w=w;
  pitem->h=h;
  
  pitem->pcan=new CglCanvas(&MM_Temp,NULL,w,h,pf15bit);
  pitem->pcan->SetCglFont(pCglFontDefault);
  
  pitem->pcan->FillFull(0);
  pitem->pcan->SetColor(RGB15(collev-4,collev-4,collev-4)|BIT15);
  pitem->pcan->DrawBox(0,0,pitem->w,pitem->h);
  
  u32 tw=pitem->pcan->GetCharWidthW(wc);
  u32 th=glCanvasTextHeight;
  
  UnicodeChar str[2]={wc,0};
  pitem->pcan->SetFontTextColor(RGB15(collev,collev,collev)|BIT15);
  pitem->pcan->TextOutW((w-tw)/2,(h-th)/2,str);
  
  SelectorItemsCount++;
}

static void Selector_Draw(CglCanvas *pCanvas,TModel *pSrcModel)
{
  CglCanvas *pcan=new CglCanvas(&MM_Temp,NULL,ScreenWidth,ScreenHeight,pf15bit);
  pcan->SetCglFont(pCglFontDefault);
  pcan->FillFull(0);
  
  if(Selector_FullMode==true){
    }else{
    u32 x=16,y=192-32;
    pcan->SetFontTextColor(RGB15(24,24,24)|BIT15);
    pcan->TextOutA(x,y,"Please choose a correct character.");
  }
  
  {
    u32 x=16,y=48;
    double ratio=0.25;
    u16 col=RGB15(16,16,16)|BIT15;
    pcan->SetColor(col);
    pcan->DrawBox(x,y,256*ratio,256*ratio);
    Model_Draw(pSrcModel,pcan,x,y,ratio,col);
  }
  
  for(u32 idx=0;idx<SelectorItemsCount;idx++){
    TSelectorItem *pitem=&pSelectorItems[idx];
    if(Selector_SelectIndex!=idx){
      pcan->SetColor(0);
      }else{
      pcan->SetColor(RGB15(4,12,4)|BIT15);
    }
    pcan->FillBox(pitem->x,pitem->y,pitem->w,pitem->h);
    pitem->pcan->BitBlt(pcan,pitem->x,pitem->y,pitem->w,pitem->h,0,0,true);
  }
  
  pcan->BitBltFullBeta(pCanvas);
  if(pcan!=NULL){
    delete pcan; pcan=NULL;
  }
}

static void Selector_Free(void)
{
  for(u32 idx=0;idx<SelectorItemsCount;idx++){
    if(pSelectorItems[idx].pcan!=NULL){
      delete pSelectorItems[idx].pcan; pSelectorItems[idx].pcan=NULL;
    }
  }
  SelectorItemsCount=0;
  if(pSelectorItems!=NULL){
    safefree(&MM_Temp,pSelectorItems); pSelectorItems=NULL;
  }
}

static void Selector_SetupFullMode(void)
{
  Selector_SelectIndex=(u32)-1;
  Selector_FullMode=true;
  
  Selector_Free();
  
  for(u32 idx=0;idx<ModelsCount;idx++){
    UnicodeChar wc=pModels[idx].wc;
    if(Model_isEnableChar(wc)==true) Selector_AddItem(wc);
  }
}

static void Selector_SetupNonFullMode(void)
{
  Selector_SelectIndex=(u32)-1;
  Selector_FullMode=false;
  
  Selector_Free();
  
  for(u32 idx=0;idx<ModelResultsCount;idx++){
    u32 midx=pModelResults[idx].ModelIndex;
    UnicodeChar wc=pModels[midx].wc;
    if(Model_isEnableChar(wc)==true) Selector_AddItem(wc);
  }
}

static void Selector_Execute_Dialog_Add(u32 x,u32 y,u32 w,u32 h,const char *pstr)
{
  pSelectorItems=(TSelectorItem*)saferealloc(&MM_Temp,pSelectorItems,sizeof(TSelectorItem)*(SelectorItemsCount+1));
  TSelectorItem *pitem=&pSelectorItems[SelectorItemsCount];
  
  pitem->x=x;
  pitem->y=y;
  pitem->w=w;
  pitem->h=h;
  
  pitem->pcan=new CglCanvas(&MM_Temp,NULL,w,h,pf15bit);
  pitem->pcan->SetCglFont(pCglFontDefault);
  
  pitem->pcan->FillFull(0);
  pitem->pcan->SetColor(RGB15(28,28,28)|BIT15);
  pitem->pcan->DrawBox(0,0,pitem->w,pitem->h);
  
  u32 tw=pitem->pcan->GetTextWidthA(pstr);
  u32 th=glCanvasTextHeight;
  
  pitem->pcan->SetFontTextColor(RGB15(31,31,31)|BIT15);
  pitem->pcan->TextOutA((w-tw)/2,(h-th)/2,pstr);
  
  SelectorItemsCount++;
}

static bool Selector_Execute_Dialog(TModel *pSrcModel,UnicodeChar wc)
{
  CglCanvas *pcan=pScreenMainOverlay->pCanvas;
  pcan->FillFull(0);
  
  {
    u32 x=16,y=48;
    double ratio=0.25;
    u16 col=RGB15(16,16,16)|BIT15;
    pcan->SetColor(col);
    pcan->DrawBox(x,y,256*ratio,256*ratio);
    Model_Draw(pSrcModel,pcan,x,y,ratio,col);
  }
  
  {
    pcan->SetFontTextColor(RGB15(31,31,31)|BIT15);
    u32 x=96,y=64-8;
    UnicodeChar strw[6]={UnicodeChar('\"'),UnicodeChar(' '),wc,UnicodeChar(' '),UnicodeChar('\"'),0};
    pcan->TextOutW(x,y,strw);
    pcan->TextOutA(x+48,y,"May I register ");
    y+=16;
    pcan->TextOutA(x,y,"this handwriting data to ");
    y+=16;
    pcan->TextOutA(x,y,"the models dictionary?");
  }
  
  {
    u32 x,y=ScreenHeight-64,w=72,h=32;
    x=(ScreenWidth/2)-(w+16);
    Selector_Execute_Dialog_Add(x,y,w,h,"REGIST");
    x=(ScreenWidth/2)+16;
    Selector_Execute_Dialog_Add(x,y,w,h,"CANCEL");
  }
  
  for(u32 idx=0;idx<SelectorItemsCount;idx++){
    TSelectorItem *pitem=&pSelectorItems[idx];
    if(idx!=0){
      pcan->SetColor(0);
      }else{
      pcan->SetColor(RGB15(2,6,2)|BIT15);
    }
    pcan->FillBox(pitem->x,pitem->y,pitem->w,pitem->h);
    pitem->pcan->BitBlt(pcan,pitem->x,pitem->y,pitem->w,pitem->h,0,0,true);
  }
  
  u32 selidx=(u32)-1;
  while(selidx==(u32)-1){
    while(1){
      const TDirectPenInfo pen=DirectPenRead_FromNowPosition();
      if(pen.CanRead==true){
        if(pen.PenDown==true){
          u32 idx=Selector_GetIndexFromPoint(pen.x,pen.y);
          if(idx!=(u32)-1) selidx=idx;
          break;
        }
      }
    }
    while(1){
      const TDirectPenInfo pen=DirectPenRead_FromNowPosition();
      if(pen.CanRead==true){
        if(pen.PenDown==false) break;
      }
    }
  }
  
  Selector_Free();
  
  if(selidx==0){
    return(true);
    }else{
    return(false);
  }
}

static UnicodeChar Selector_Execute(TModel *pSrcModel)
{
  if(ModelResultsCount==0) return(0);
  
  PlaySE_Long();
  
  pScreenMainOverlay->pCanvas->BitBlt(pScreenMain->pViewCanvas,0,0,ScreenWidth,ScreenHeight,0,0,true);
  pScreenMainOverlay->pCanvas->FillFull(0);
  
  {
    u32 *pbuf=(u32*)pScreenMain->pViewCanvas->GetVRAMBuf();
    for(u32 idx=0;idx<ScreenWidth*ScreenHeight/2;idx++){
      u32 col=*pbuf;
      col=(col&0x63186318)>>3;
      *pbuf++=col|BIT15|BIT31;
    }
  }
  
  SelectorItemsCount=0;
  pSelectorItems=NULL;
  
  Selector_SetupNonFullMode();
  
  Selector_Draw(pScreenMainOverlay->pCanvas,pSrcModel);
  
  while(1){
    const TDirectPenInfo pen=DirectPenRead_FromNowPosition();
    if(pen.CanRead==true){
      if(pen.PenDown==false) break;
      u32 nowidx=Selector_GetIndexFromPoint(pen.x,pen.y);
      if(Selector_FullMode==false){
        if(nowidx==(u32)-1){
          if(pen.x<72){
            Selector_SetupFullMode();
            Selector_Draw(pScreenMainOverlay->pCanvas,pSrcModel);
          }
        }
      }
      if(Selector_SelectIndex!=nowidx){
        Selector_SelectIndex=nowidx;
        if(Selector_SelectIndex!=(u32)-1) PlaySE_Short();
        Selector_Draw(pScreenMainOverlay->pCanvas,pSrcModel);
      }
    }
  }
  
  UnicodeChar reswc=0;
  bool dialog=false;
  if(Selector_SelectIndex!=(u32)-1){
    reswc=pSelectorItems[Selector_SelectIndex].wc;
    if(Selector_SelectIndex!=0) dialog=true;
  }
  
  Selector_Free();
  
  if(dialog==true){
    if(Selector_Execute_Dialog(pSrcModel,reswc)==false) reswc=0;
  }
  
//  if(Selector_SelectIndex!=(u32)-1) PlaySE_Long();
  
  if(reswc!=0) Models_AddRefer(pSrcModel,reswc);
  
  return(reswc);  
}

