/**
 * Nametry
 * (c) Kenta Cho (cs8k-cyu@asahi-net.or.jp)
 * http://www.asahi-net.or.jp/~cs8k-cyu/
 *
 * dispmng.c(handle screen buffer)
 */

#include <sys/bios.h>
#include <sys/libwwc.h>
#include <stdlib.h>

#include "nametry.h"
#include "pattern.h"

static unsigned short txtPal[][4] = {
  {0x0fff, 0x05ad, 0x036c, 0x0124},
  {0x0fff, 0x0ad5, 0x06c3, 0x0141},
  {0x0fff, 0x05ad, 0x036c, 0x0124},
  {0x0fff, 0x0ec8, 0x0a84, 0x0321},
};
static unsigned short sprPal[][4] = {
  {0x0fff, 0x08e8, 0x06d6, 0x0141},
  {0x0fff, 0x0d55, 0x0c33, 0x0411},
  {0x0fff, 0x055d, 0x033c, 0x0114},
};

/**
 * Initialize WonderSwan/color display.
 */
void initDisplay() {
  int i, j;
  lcd_set_segments(0x4);
  display_control(0x0000f);
  screen_set_scroll(SCREEN1, 0, 0);
  screen_set_scroll(SCREEN2, 0, 0);
  clearDisplay();
  if ( wwc_get_hardarch() == HARDARCH_WSC ) {
    wwc_set_color_mode(COLOR_MODE_4COLOR);
    for ( j=3 ; j<7 ; j++ ) {
      for ( i=0 ; i<4 ; i++ ) {
	wwc_palette_set_color(j, i, txtPal[j-3][i]);
      }
    }
    for ( j=12 ; j<15 ; j++ ) {
      for ( i=0 ; i<4 ; i++ ) {
	wwc_palette_set_color(j, i, sprPal[j-12][i]);
      }
    }
  } else {
    for ( j=0 ; j<15 ; j++ ) {
      palette_set_color(j, 0xfac0);
    }
    palette_set_color(13, 0x8f40);
  }
  lcd_set_color(0x6420, 0xfca8);
  sprite_set_range(0, SPRITE_RANGE);
  for ( i=0 ; i<SPRITE_RANGE ; i++ ) {
    sprite_set_location(i, DISAP_POS, DISAP_POS);
  }
  for ( i=0 ; i<4 ; i++ ) {
    font_set_colordata(i, 1, spcPtn);
  }
  font_set_colordata(ALP_IDX, ALP_NUM, alpPtn);
  font_set_colordata(NUM_IDX, NUM_NUM, numPtn);
  font_set_colordata(SBL_IDX, SBL_NUM, sblPtn);
  font_set_colordata(AB_IDX, AB_NUM, abPtn);
  font_set_colordata(NB_IDX, NB_NUM, nbPtn);
  font_set_colordata(SB_IDX, SB_NUM, sbPtn);
  font_set_colordata(LINE_IDX, LINE_NUM, linePtn); 
  font_set_colordata(LCK_IDX, LCK_NUM, lckPtn); 
  font_set_colordata(HTO_IDX, HTO_NUM, htoPtn); 
  font_set_colordata(END_IDX, END_NUM, endPtn); 
}

void closeDisplay() {
  if ( wwc_get_hardarch() == HARDARCH_WSC ) {
    wwc_set_color_mode(COLOR_MODE_GRAYSCALE);
  }
}

void clearDisplay() {
  screen_fill_char(SCREEN1, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0x0800);
  screen_fill_char(SCREEN2, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0x0800);
}

/**
 * Draw character patterns(line, letter, ...).
 */
void drawLinePtn(int ptn[], int x, int y, int w, int h) {
  int i, j, k;
  int lx, ly;
  k = 0;
  for ( i=0, ly=y ; i<h ; i++, ly++ ) {
    for ( j=0, lx=x ; j<w ; j++, lx++, k++ ) {
      if ( ptn[k] != 0 ) {
	screen_fill_char(SCREEN2, lx, ly, 1, 1, 0x0a00+ptn[k]+LINE_IDX-1);
      }
    }
  }
}

void drawAlp(int c, int x, int y) {
  screen_fill_char(SCREEN2, x, y, 1, 1, 0x0800+c+ALP_IDX);
}

void drawAlpPtn(int ptn[], int x, int y, int w, int h) {
  int i, j, k;
  int lx, ly;
  k = 0;
  for ( i=0, ly=y ; i<h ; i++, ly++ ) {
    for ( j=0, lx=x ; j<w ; j++, lx++, k++ ) {
      screen_fill_char(SCREEN2, lx, ly, 1, 1, 0x0800+ptn[k]+ALP_IDX);
    }
  }
}

void drawBgAlp(int c, int x, int y) {
  drawBgAlpScr(SCREEN2, c, x, y);
}

void drawBgAlpScr(int screen, int c, int x, int y) {
  int i, j, k, ak;
  if ( c == -1 ) {
    k = 0x0800; 
    ak = 0;
  } else if ( c >= 36 ) {
    k = (c-36)*2 + SB_IDX + 0x0800;
    ak = 8;
  } else if ( c >= 26 ) {
    k = (c-26)*2 + NB_IDX + 0x0800;
    ak = 18;
  } else {
    k = c*2 + AB_IDX + 0x0800;
    ak = 50; 
  }
  for ( i=y ; i<y+2 ; i++ ) {
    for ( j=x ; j<x+2 ; j++, k++ ) {
      screen_fill_char(screen, j, i, 1, 1, k);
    }
    k += ak;
  }
}

void drawNum(long n, int x, int y) {
  if ( n == 0 ) {
    screen_fill_char(SCREEN2, x, y, 1, 1, 0x0800+NUM_IDX);
  } else {
    while ( n > 0 ) {
      screen_fill_char(SCREEN2, x, y, 1, 1, 0x0800+n%10+NUM_IDX);
      n /= 10;
      x--;
    }
  }
}

int drawBgNum(long n, int x, int y) {
  int i, j, k;
  int c = 0;
  if ( n == 0 ) {
    screen_fill_char(SCREEN2, x, y, 1, 1, 0x0800+NUM_IDX);
    k = NB_IDX + 0x0800;
    for ( i=y ; i<y+2 ; i++ ) {
      for ( j=x ; j<x+2 ; j++, k++ ) {
	screen_fill_char(SCREEN2, j, i, 1, 1, k);
      }
      k += 18;
    }
    c++;
  } else {
    while ( n > 0 ) {
      k = (n%10)*2 + NB_IDX + 0x0800;
      for ( i=y ; i<y+2 ; i++ ) {
	for ( j=x ; j<x+2 ; j++, k++ ) {
	  screen_fill_char(SCREEN2, j, i, 1, 1, k);
	}
	k += 18;
      }
      n /= 10;
      x -= 2;
      c++;
    }
  }
  return c;
}

void clearChr(int x, int y, int w, int h) {
  screen_fill_char(SCREEN2, x, y, w, h, 0x0800);
}

void clearChrScr(int screen, int x, int y, int w, int h) {
  screen_fill_char(screen, x, y, w, h, 0x0800);
}

