#include "geki4.h"
#include "extern.h"

/**********************
  当たり範囲設定
 **********************/
void SetPer(PixData *my, float per)
{
  Sint16 w, h, sw, wper, hper, i, ws, hs;

  w = my->Image->Width;
  h = my->Image->Height;
  /* 当り判定領域設定 */
  ws = (Sint16)((float)w * per + 0.5);
  wper = w - ws * 2;
  hs = (Sint16)((float)h * per + 0.5);
  hper = h - hs * 2;
  wper = wper > CHECK_MAX ? ws : 0;
  hper = hper > CHECK_MAX ? hs : 0;;
  my->x[0] = my->x[2] =     wper;
  my->x[1] = my->x[3] = w - wper - 1;
  my->y[0] = my->y[1] =     hper;
  my->y[2] = my->y[3] = h - hper - 1;
  my->AddX = -w / 2;
  my->AddY = -h / 2;
}

/**********************
  ピックスマップ作成
 **********************/
PixData **LoadImage(Uint8 *name, Uint8 blend, Uint8 w, Uint8 h, float per)
{
  Uint8 x,y;
  KXL_Image *tmp;
  KXL_Rect r;
  Uint8 path[128];
  PixData **new;
  
  sprintf(path, BMP_PATH "/%s.bmp", name);
  tmp = KXL_LoadBitmap(path, blend);
  new = (PixData **)KXL_Malloc(sizeof(PixData *) * (w * h));
  r.Width  = tmp->Width / w;
  r.Height = tmp->Height / h;
  for (y = 0; y < h; y++) {
    for (x = 0; x < w; x++) {
      r.Left = x * r.Width;
      r.Top  = y * r.Height;
      new[y * w + x] = (PixData *)KXL_Malloc(sizeof(PixData));
      new[y * w + x]->Image = KXL_CopyImage(tmp, r);
      SetPer(new[y * w + x], per);
    }
  }
  KXL_DeleteImage(tmp);
  return new;
}

/**********************
  縮小イメージ作成
 **********************/
PixData **LoadImage2Strech(Uint8 *name, Uint8 blend, float per)
{
  Uint8 no;
  KXL_Image *tmp;
  Uint8 path[128];
  PixData **new;
  Uint16 w,h;
  
  sprintf(path, BMP_PATH "/%s.bmp", name);
  tmp = KXL_LoadBitmap(path, blend);
  new = (PixData **)KXL_Malloc(sizeof(PixData *) * MAX_Z);
  for (no = 0; no < MAX_Z; no ++) {
    new[no] = (PixData *)KXL_Malloc(sizeof(PixData));
    w = tmp->Width  * BASE_Z / (BASE_Z + no);
    h = tmp->Height * BASE_Z / (BASE_Z + no);
    new[no]->Image = KXL_StrechImage(tmp, w, h);
    SetPer(new[no], per);
  }
  KXL_DeleteImage(tmp);
  return new;
}

/**********************
  ピックスマップ作成
 **********************/
void CreatePixmap(void)
{
  fprintf(stderr, "creating image...");
  PixMy     = LoadImage("my",   0, 5, 3, 0.4);
  PixEnemy1 = LoadImage2Strech("enemy1", 0, CHECK_PER);
  PixEnemy2 = LoadImage2Strech("enemy2", 0, CHECK_PER);
  PixShot   = LoadImage2Strech("shot", 0, CHECK_PER);
  PixBomb   = LoadImage2Strech("bomb", 0, CHECK_PER);
  PixKage   = LoadImage2Strech("kage", 0, CHECK_PER);
  PixEShot  = LoadImage2Strech("eshot", 0, CHECK_PER);
  fprintf(stderr, "  end\n");
}

/**********************
  ピックスマップ解放
 **********************/
void UnLoadPixmaps(PixData **my, Uint16 max)
{
  while (max)
    KXL_DeleteImage(my[-- max]->Image);
  KXL_Free(my);
}

/**********************
  ピックスマップ削除
 **********************/
void DeletePixmap(void)
{
  UnLoadPixmaps(PixMy,     5 * 3);
  UnLoadPixmaps(PixEnemy1, MAX_Z);
  UnLoadPixmaps(PixEnemy2, MAX_Z);
  UnLoadPixmaps(PixShot, MAX_Z);
  UnLoadPixmaps(PixBomb, MAX_Z);
  UnLoadPixmaps(PixKage, MAX_Z);
  UnLoadPixmaps(PixEShot, MAX_Z);
}

/**********************
  ステージ別キャラクタ作成
 **********************/
void LoadStage(void)
{
  FILE *fp;
  Uint8 buff[256];
  Uint16 dat, i;

  /* 敵出現データファイルを読み込む */
  sprintf(buff, DATA_PATH "/stage%d.dat", Root->Stage + 1);
  if ((fp = fopen(buff, "r")) == NULL) {
    KXL_PlaySound(0, KXL_SOUND_STOP_ALL);
    return;
  }
  /* 敵出現データを読み込む */
  Root->StageMax = 0;
  Root->EnemyCnt = 0;
  while(fgets(buff, 255, fp)) {
    if (buff[0] == ';' || buff[0] == '\n')
      continue;
    if (!Root->StageMax)
      StageDatas = (StageData **)KXL_Malloc(sizeof(StageData *));
    else
      StageDatas = (StageData **)KXL_Realloc(StageDatas, sizeof(StageData *) * (Root->StageMax + 1));
    StageDatas[Root->StageMax] = (StageData *)KXL_Malloc(sizeof(StageData));
    sscanf(buff,"%d%d%d%d",
           &(StageDatas[Root->StageMax]->Time),
           &(StageDatas[Root->StageMax]->CreateNo),
           &(StageDatas[Root->StageMax]->Max),
           &(StageDatas[Root->StageMax]->Step));
    StageDatas[Root->StageMax]->Flag = False;
    StageDatas[Root->StageMax ++]->StepTime = 0;
  }
  fclose(fp);

  switch (Root->Stage) {
  case 0:
    PixBack   = LoadImage("back1", 255, 3, 1, CHECK_PER);
    PixSky    = LoadImage("sky1", 255, 1, 1, CHECK_PER);
    PixWall   = LoadImage2Strech("wall", 0, CHECK_PER);
    PixBoss1  = LoadImage2Strech("boss1_f", 0, CHECK_PER);
    PixBoss2  = LoadImage2Strech("boss1_b", 0, CHECK_PER);
    PixBoss3  = LoadImage2Strech("boss1_do", 0, CHECK_PER);
    break;
  case 1:
    PixBack   = LoadImage("back2", 255, 3, 1, CHECK_PER);
    PixSky    = LoadImage("sky2", 255, 1, 1, CHECK_PER);
    PixWall   = LoadImage2Strech("wall2", 0, CHECK_PER);
    PixBoss1  = LoadImage2Strech("boss2_f", 0, CHECK_PER);
    PixBoss2  = LoadImage2Strech("boss2_b", 0, CHECK_PER);
    PixBoss3  = LoadImage2Strech("boss2_do", 0, CHECK_PER);
    break;
  }
}

/**********************
  ステージ別キャラクタ削除
 **********************/
void DeleteStage(void)
{
  while (Root->StageMax)
    KXL_Free(StageDatas[-- Root->StageMax]);
  KXL_Free(StageDatas);

  switch (Root->Stage) {
  case 0:
  case 1:
    UnLoadPixmaps(PixBack,   3 * 1);
    UnLoadPixmaps(PixSky,    1 * 1);
    UnLoadPixmaps(PixWall, MAX_Z);
    UnLoadPixmaps(PixBoss1, MAX_Z);
    UnLoadPixmaps(PixBoss2, MAX_Z);
    UnLoadPixmaps(PixBoss3, MAX_Z);
    break;
  }
}
