/**
 * Nametry
 * (c) Kenta Cho (cs8k-cyu@asahi-net.or.jp)
 * http://www.asahi-net.or.jp/~cs8k-cyu/
 *
 * titlemng.c(title display)
 */

#include <sys/bios.h>
#include "il_sound.h"

#include "nametry.h"

/* sprite index for gameover letters */
#define GOLSPR_IDX 0

/* number of top player ranking */
#define RANKING_NUM 10

static Ranking ranking[RANKING_NUM];

Boolean loadPrefs() {
  return loadPreferences((char far *)&ranking, sizeof(ranking));
}

Boolean savePrefs() {
  return savePreferences((char far *)&ranking, sizeof(ranking));
}

/**
 * Initialize title screen.
 */
static void drawTitle() {
  static int ttlStr[] = {13, 0, 12, 4, 19, 17, 24};
  int i;
  clearDisplay();
  for ( i=0 ; i<7 ; i++ ) {
    drawBgAlp(ttlStr[i], i*3+4, 8);
  }
}

static int ttly[3];
static int ttlStr[3][SCREEN_WIDTH];
static int ttlCnt;

void gotoTitle() {
  int i;
  for ( i=0 ; i<SPRITE_RANGE ; i++ ) {
    sprite_set_location(i, DISAP_POS, DISAP_POS);
  }
  drawTitle();
  gameStatus.status = TITLE;
  initTitleState();
  ttly[0] = 1; ttly[1] = 3; ttly[2] = 4;
  ttlCnt = 0;
}

/**
 * Initialize gameover stage effect.
 */
static int ttld;

static void startDrawGameover() {
  static int goStr[] = {6,0,12,4,14,21,4,17};
  int i;
  for ( i=0 ; i<8 ; i++ ) {
    sprite_set_char(i*4+GOLSPR_IDX  , 0x1800+goStr[i]*2+AB_IDX);
    sprite_set_char(i*4+GOLSPR_IDX+1, 0x1800+goStr[i]*2+AB_IDX+1);
    sprite_set_char(i*4+GOLSPR_IDX+2, 0x1800+goStr[i]*2+AB_IDX+52);
    sprite_set_char(i*4+GOLSPR_IDX+3, 0x1800+goStr[i]*2+AB_IDX+53);
  }
  ttld = 64;
}

void startGameover() {
  int i;
  clearChr(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
  for ( i=0 ; i<SPRITE_RANGE ; i++ ) {
    sprite_set_location(i, DISAP_POS, DISAP_POS);
  }
  startDrawGameover();
  gameStatus.status = GAMEOVER;
  gameStatus.time = 64;
  playBgm(BGM_GAMEOVER, PLAY_SINGLE);
}

/**
 * Initialize gameover.
 */
void startGameGameover() {
  clearChr(0, IPT_Y, SCREEN_WIDTH, 2);
  resetCursor();
  resetFlyingLetter();
  sprite_set_window(0, 0, 0, 0);
  startDrawGameover();
  gameStatus.status = GAME_GAMEOVER;
  gameStatus.time = 64;
  gameStatus.atrcStat = START_ENTRY;
  gameStatus.atrcTime = 18;
  stopBgm();
  playBgm(BGM_GAMEOVER, PLAY_SINGLE);
}

/**
 * Initialize name entry.
 */
void initRanking() {
  int i;
  for ( i=0 ; i<RANKING_NUM ; i++ ) {
    ranking[i].name[0] = 0+i;
    ranking[i].name[1] = 1+i;
    ranking[i].name[2] = 0+i;
    ranking[i].score = (long)1000000*(10-i);
  }
}

static int etrRank;

void startRanking() {
  int i;
  etrRank = -1;
  for ( i=0 ; i<RANKING_NUM ; i++ ) {
    if ( ranking[i].score < score ) {
      etrRank = i;
      for ( i=RANKING_NUM-2 ; i>=etrRank ; i-- ) {
	ranking[i+1].score = ranking[i].score;
	ranking[i+1].name[0] = ranking[i].name[0];
	ranking[i+1].name[1] = ranking[i].name[1];
	ranking[i+1].name[2] = ranking[i].name[2];
      }
      ranking[etrRank].score = score;
      break;
    }
  }
  if ( etrRank == -1 ) {
    gotoTitle();
    return;
  }
  clearChr(0, 0, SCREEN_WIDTH, 3);
  clearChrScr(SCREEN1, 0, 0, SCREEN_WIDTH, 3);
  clearChr(0, SCREEN_HEIGHT-2, SCREEN_WIDTH, 2);
  sprite_set_char(MYSPR_IDX  , 0x1c00+HTO_IDX);
  sprite_set_char(MYSPR_IDX+1, 0xc00+HTO_IDX+1);
  sprite_set_char(MYSPR_IDX+2, 0xc00+HTO_IDX+2);
  sprite_set_char(MYSPR_IDX+3, 0xc00+HTO_IDX+2);
  sprite_set_window(LTCNT_X-8, LTCNT_Y-8, 24, 24);
  drawBottomRank(etrRank, IPT_Y-2);
  drawBgNum(score, 17, IPT_Y);
  nmIdx = 0;
  crsCnt = 0;
  tableNum = 3;
  setEntryTable();
  gameStatus.status = RANKING;
  gameStatus.atrcStat = NONE;
  playBgm(BGM_RANKING, PLAY_LOOP);
}

/**
 * Initialize game pause.
 */
static int pauseMsgs[3][28] = {
  {0,0,0,0,0,0,0,0,0,16,0,1,0,21,0,19,0,5,0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,16,21,19,8,0,1,37,2,0,20,15,0,18,5,19,21,13,5,0,0,0,0,0},
  {0,0,0,0,0,16,21,19,8,0,19,20,1,18,20,0,20,15,0,17,21,9,20,0,0,0,0,0}
};

void startPause() {
  int i, j;
  int ps;
  for ( i=0 ; i<3 ; i++ ) {
    for ( j=0 ; j<28 ; j++ ) {
      ps = pauseMsgs[i][j];
      if ( ps != 0 ) {
	screen_fill_char(SCREEN2, j, i*2+3, 1, 1, 0x0600 + ps-1 + ALP_IDX);
      } else {
	screen_fill_char(SCREEN2, j, i*2+3, 1, 1, 0x0600);
      }
    }
  }
  gameStatus.status = PAUSE;
}

/**
 * Handle title screen.
 */
static int ttlMsgs[2][28] = {
  {0,0,0,0,0,16,21,19,8,0,1,37,2,0,20,15,0,19,20,1,18,20,0,0,0,0,0,0},
  {0,0,0,0,0,16,21,19,8,0,19,20,1,18,20,0,20,15,0,17,21,9,20,0,0,0,0,0}
};

static void setTitleStr() {
  int i, j, k, tc, ts, x;
  long n;
  tc = (ttlCnt>>8);
  for ( i=0 ; i<28 ; i++ ) {
    ts = ttlMsgs[tc&1][i];
    if ( ts == 0 ) {
      ttlStr[0][i] = 0x0800;
    } else {
      ttlStr[0][i] = 0x0800 + ts-1 + ALP_IDX;
    }
  }
  for ( i=0 ; i<28 ; i++ ) {
    ttlStr[1][i] = 0x0800;
    ttlStr[2][i] = 0x0800;
  }
  tc *= 2;
  for ( j=1 ; j<3 ; j++, tc++ ) {
    i = 5;
    if ( tc == 9 ) {
      ttlStr[j][i] = 0x0800 + 1 + NUM_IDX;
      ttlStr[j][i+1] = 0x0800 + NUM_IDX;
    } else {
      ttlStr[j][i+1] = 0x0800 + tc+1 + NUM_IDX;
    }
    i += 2;
    if ( tc < 3 ) {
      ttlStr[j][i] = 0x0800 + rankPtn[tc*2] + ALP_IDX;
      ttlStr[j][i+1] = 0x0800 + rankPtn[tc*2+1] + ALP_IDX;
    } else {
      ttlStr[j][i] = 0x0800 + rankPtn[6] + ALP_IDX;
      ttlStr[j][i+1] = 0x0800 + rankPtn[7] + ALP_IDX;
    }
    i += 2+1+8; x = i;
    n = ranking[tc].score;
    while ( n > 0 ) {
      ttlStr[j][x] = 0x0800 + n%10 + NUM_IDX;
      n /= 10;
      x--;
    }
    i += 2;
    for ( k=0 ; k<3 ; k++, i++ ) {
      ttlStr[j][i] = 0x0800 + ranking[tc].name[k] + ALP_IDX;
    }
  }
}

void handleTitle() {
  int key = key_press_check();
  int tc = ttlCnt&255, lc;
  if ( tc < 84 ) {
    if ( tc == 0 ) {
      setTitleStr();
      clearChr(0, ttly[0], SCREEN_WIDTH, 4);
    }
    lc = tc/28;
    screen_set_char(SCREEN2, 27-tc%28, ttly[lc], tc%28+1, 1, &(ttlStr[lc][0]));
  }
  ttlCnt++; if ( ttlCnt >= 1280 ) ttlCnt = 0;
  moveLetters(0);
  drawLetters();
  if ( !(key & KEY_START) ) {
    startPrsd = FALSE;
  } else if ( !startPrsd ) { 
    startPrsd = TRUE;
    loopf = FALSE;
    return;
  }
  if ( !(key & KEY_A) ) {
    aPrsd = FALSE;
  } else if ( !aPrsd ) { 
    aPrsd = TRUE;
    startGameover();
    return;
  }    
  if ( !(key & KEY_B) ) {
    bPrsd = FALSE;
  } else if ( !bPrsd ) { 
    bPrsd = TRUE;
    startGameover();
    return;
  }
}

/**
 * Handle gameover stage effect.
 */
static void drawGameover(int oy) {
  int i, x, y, d;
  d = ttld;
  for ( i=0 ; i<8 ; i++ ) {
    x = -(costbl[d]>>1)+SCREEN_WIDTH*8/2-8;
    y = ((sintbl[d]*gameStatus.time)>>8)+oy;
    sprite_set_location(i*4+GOLSPR_IDX  , x, y);
    sprite_set_location(i*4+GOLSPR_IDX+1, x+8, y);
    sprite_set_location(i*4+GOLSPR_IDX+2, x, y+8);
    sprite_set_location(i*4+GOLSPR_IDX+3, x+8, y+8);
    d += 8+(gameStatus.time>>4); if ( i == 3 ) d += 4; 
    d &= 255;
  }
  ttld += (gameStatus.time>>2); ttld &= 255;
}

void handleGameover() {
  int key;
  key = key_press_check();
  if ( !(key & KEY_A) ) {
    aPrsd = FALSE;
  } else if ( !aPrsd ) { 
    aPrsd = TRUE;
    initGame();
    startGame();
    return;
  }    
  if ( !(key & KEY_B) ) {
    bPrsd = FALSE;
  } else if ( !bPrsd ) { 
    bPrsd = TRUE;
    initGame();
    startGame();
    return;
  }
  gameStatus.time--;
  if ( gameStatus.time <= 0 ) {
    if ( gameStatus.time <= -64 ) {
      initGame();
      startGame();
    }
    return;
  }
  drawGameover(SCREEN_HEIGHT*8/2-8);
}

/**
 * Handle game over.
 */
void handleGameGameover() {
  int key;
  gameStatus.time--;
  if ( gameStatus.time <= 0 ) {
    if ( gameStatus.time <= -128 ) {
      startRanking();
    }
    key = key_press_check();
    if ( !(key & KEY_A) ) {
      aPrsd = FALSE;
    } else if ( !aPrsd ) { 
      aPrsd = TRUE;
      startRanking();
    }    
    if ( !(key & KEY_B) ) {
      bPrsd = FALSE;
    } else if ( !bPrsd ) { 
      bPrsd = TRUE;
      startRanking();
    }
    return;
  }
  if ( gameStatus.atrcTime > 9 ) {
    gameStatus.atrcTime--;
    moveLetters(0);
    drawLetters();
  } else {
    int i;
    for ( i=LTRSPR_IDX ; i<LTRSPR_IDX+64 ; i++ ) {
      sprite_set_location(i, DISAP_POS, DISAP_POS);
    }
  }
  drawGameover(IPT_Y*8-gameStatus.time);
}

/**
 * Handle name entry.
 */
void handleRanking() {
  int i, key;
  if ( nmIdx < 3 ) {
    moveFlyingLetter();
    inputLetter();
    if ( nmIdx == 3 ) {
      sprite_set_char(ILSPR_IDX  , 0x0800+END_IDX);
      sprite_set_char(ILSPR_IDX+1, 0x0800+END_IDX+1);
      sprite_set_char(ILSPR_IDX+2, 0x0800+END_IDX+2);
      sprite_set_char(ILSPR_IDX+3, 0x0800+END_IDX+3);
      sprite_set_location(ILSPR_IDX  , LTCNT_X-4, LTCNT_Y-4);
      sprite_set_location(ILSPR_IDX+1, LTCNT_X+4, LTCNT_Y-4);
      sprite_set_location(ILSPR_IDX+2, LTCNT_X-4, LTCNT_Y+4);
      sprite_set_location(ILSPR_IDX+3, LTCNT_X+4, LTCNT_Y+4);
      for ( i=LTRSPR_IDX ; i<LTRSPR_IDX+64 ; i++ ) {
	sprite_set_location(i, DISAP_POS, DISAP_POS);
      }
      for ( i=MYSPR_IDX ; i<MYSPR_IDX+4 ; i++ ) {
	sprite_set_location(i, DISAP_POS, DISAP_POS);
      }
      resetCursor();
      resetFlyingLetter();
    }
  } else {
    drawRankScore();
    key = key_press_check();
    if ( !(key & KEY_A) ) {
      aPrsd = FALSE;
    } else if ( !aPrsd ) {
      aPrsd = TRUE;
      endRanking();
      return;
    }
    if ( !(key & KEY_B) ) {
      bPrsd = FALSE;
    } else if ( !bPrsd ) { 
      bPrsd = TRUE;
      drawBgAlp(-1, nmIdx*2+20, IPT_Y);
      nmIdx--;
      ilIdx = -1;
    }
  }
}

void endRanking() {
  ranking[etrRank].name[0] = iptlt[0];
  ranking[etrRank].name[1] = iptlt[1];
  ranking[etrRank].name[2] = iptlt[2];
  resetCursor();
  stopBgm();
  sys_wait(64);
  gotoTitle();
}

/**
 * Handle game pause.
 */
static void endPause() {
  clearChr(0, 3, SCREEN_WIDTH, 5);
  gameStatus.status = GAME_IN_PROGRESS;
}

void handlePause() {
  int key = key_press_check();
  if ( !(key & KEY_START) ) {
    startPrsd = FALSE;
  } else if ( !startPrsd ) { 
    startPrsd = TRUE;
    loopf = FALSE;
    return;
  }
  if ( !(key & KEY_A) ) {
    aPrsd = FALSE;
  } else if ( !aPrsd ) { 
    aPrsd = TRUE;
    endPause();
  }    
  if ( !(key & KEY_B) ) {
    bPrsd = FALSE;
  } else if ( !bPrsd ) { 
    bPrsd = TRUE;
    endPause();
  }
}
