#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/bios.h>
#include "tenji.h"
#include "display.h"
#include "memo.h"
#include "text.h"

#define BLOCKS ((TEXT_MAX+127)/128)

static int cursor_blink_count;
#define CURSOR_BLINK_PERIOD 8

void init_screens() {
   int i;

   display_control(0x01);

   r_fill_char_incr(SCREEN1, 0, 0, SCREEN_W, SCREEN_H, 0);
   clear_rect(SCREEN1, 0, 0, SCREEN_W, SCREEN_H);

   for (i=0; i<SCREEN_W; i++) {
      draw_char(SCREEN1, i, MAIN_WINDOW_H, 0x0f);
      draw_char(SCREEN1, i, TENJI_WINDOW_Y-1, 0x0f);
   }

   lcd_set_color(0x6420, 0xfca8);
   palette_set_color(0, 0x7530);
   palette_set_color(1, 0x0357);
}


enum menu_item_id {
   MENU_HELP = 0, MENU_CANCEL, MENU_SAVE, MENU_LOAD
};
struct menu_item {
   int id;
   int button;
   char* string;
} menu[] = {
     { MENU_HELP, 0x01, "ヘルプ"}, 
     { MENU_CANCEL, 0x08, "キャンセル"}, 
     { MENU_SAVE, 0x04, "保存(未実装)"}, 
     { MENU_LOAD, 0x02, "読込(未実装)"}, 
     { -1, 0, 0}
};

void help() {
   clear_rect(SCREEN1, 
	      MAIN_WINDOW_X, MAIN_WINDOW_Y, MAIN_WINDOW_W, MAIN_WINDOW_H);

   draw_tenji_help(SCREEN1, MAIN_WINDOW_X, MAIN_WINDOW_Y);
   while(key_press_check() != 0)
     sys_wait(5);
   while(key_press_check() == 0)
     sys_wait(5);
}

void process_menu(){
   int i;
   int key, button;

   clear_rect(SCREEN1, 
	      MAIN_WINDOW_X, MAIN_WINDOW_Y, MAIN_WINDOW_W, MAIN_WINDOW_H);
   draw_string(SCREEN1, MAIN_WINDOW_X, MAIN_WINDOW_Y, 
	       "****** メニュー ******");
   for(i=0; menu[i].id >= 0; i++) {
      draw_button(SCREEN1, MAIN_WINDOW_X+2, MAIN_WINDOW_Y+i+2, 
		  menu[i].button>>4);
      draw_button(SCREEN1, MAIN_WINDOW_X+3, MAIN_WINDOW_Y+i+2, 
		  menu[i].button&0x0f);
      draw_string(SCREEN1, MAIN_WINDOW_X+5, MAIN_WINDOW_Y+i+2,
		  menu[i].string);
   }

   while(1) {
      key = key_press_check();
      button = key >> 4;
      if ((key & 0x02) || button == menu[MENU_CANCEL].button) {
	 while(key_press_check() == 0)
	   sys_wait(5);
	 break;
      }
      if (button == menu[MENU_HELP].button) {
	 while(key_press_check() == 0)
	   sys_wait(5);
	 help();
	 break;
      }
      sys_wait(5);
   }
   print_all();
}

#define FILENAME_X MAIN_WINDOW_X
#define FILENAME_Y (MAIN_WINDOW_Y+MAIN_WINDOW_H-1)
#define FILELIST_MAX 15
char filelist[FILELIST_MAX][MAXFNAME+1];
int num_filelist;
void select_file_draw_all(char* title, char* filename, int selected) {
   int i;
   clear_rect(SCREEN1, 
	      MAIN_WINDOW_X, MAIN_WINDOW_Y, MAIN_WINDOW_W, MAIN_WINDOW_H);
   draw_char(SCREEN1, MAIN_WINDOW_X, MAIN_WINDOW_Y+1+selected, 0x1a);
   for(i=0; i<num_filelist; i++)
     draw_string(SCREEN1, MAIN_WINDOW_X+1, MAIN_WINDOW_Y+1+i,
		 filelist[i]);
   draw_string(SCREEN1, MAIN_WINDOW_X, MAIN_WINDOW_Y, title);
   draw_string(SCREEN1, FILENAME_X, FILENAME_Y, filename);
}

void select_file(char* title, char* filename) {
   int key, button, button_last;
   static int result0, result1;
   int pos;
   int i, j, selected;
   int blink_count;
   struct stat statbuf;

   draw_string(SCREEN1, 1, MAIN_WINDOW_H+2, "ヘルプ :");
   draw_button(SCREEN1, 7, MAIN_WINDOW_H+2, MENU_BUTTON>>4);
   draw_button(SCREEN1, 8, MAIN_WINDOW_H+2, MENU_BUTTON&0x0f);
   draw_string(SCREEN1, 2, MAIN_WINDOW_H+3, "決定 : START ボタン ");

   num_filelist = 0;
   for(i=0; i<nument(NULL); i++) {
      if (getent(NULL, i, &statbuf) != E_FS_SUCCESS)
	break;
      if (statbuf.count != -1) {
	 for(j=0; j<MAXFNAME; j++)
	   filelist[num_filelist][j] = statbuf.name[j];
	 filelist[num_filelist][MAXFNAME]=0;
	 num_filelist++;
	 if (num_filelist >= FILELIST_MAX)
	   break;
      }
   }

   blink_count = 0;
   button_last = 0;
   pos = 0;
   selected = 0;
   strcpy(filename, filelist[selected]);
   select_file_draw_all(title, filename, selected);
   while(1) {
      key = key_press_check();
      button = key >> 4;
      if (key&2) {
	 r_set_attr1(SCREEN1, FILENAME_X+pos, FILENAME_Y, 0);
	 while(key_press_check() != 0)
	   sys_wait(5);
	 break;
      }
      if (button != button_last) {
	 r_set_attr1(SCREEN1, FILENAME_X+pos, FILENAME_Y, 0);
	 button_last = button;
	 process_button(button, &result0, &result1);
	 switch(result0) {
	  case BACKSPACE:
	    if (pos > 0) {
	       pos--;
	       draw_char(SCREEN1, FILENAME_X+pos, FILENAME_Y, ' ');
	       filename[pos] = 0;
	    }
	    break;
	  case DOWN:
	    selected = (selected + 1)%num_filelist; 
	    strcpy(filename, filelist[selected]);
	    pos = strlen(filename);
	    select_file_draw_all(title, filename, selected);
	    break;
	  case UP:
	    selected = (selected - 1 + num_filelist)%num_filelist;
	    strcpy(filename, filelist[selected]);
	    pos = strlen(filename);
	    select_file_draw_all(title, filename, selected);
	    break;
	  case MENU:
	    help();
	    select_file_draw_all(title, filename, selected);
	    break;
	  case ENTER:
	  case ESCAPE:
	  case RIGHT:
	  case LEFT:
	  case PAGEDOWN:
	  case PAGEUP:
          case CONTROL:
	  case SHIFT:
	  case 0:
	    break;
	  default:
	    if (((result0 >= 'a' && result0 <= 'z') || result0 == '.') && 
		pos < MAXFNAME) {
	       draw_char(SCREEN1, FILENAME_X+pos, FILENAME_Y, result0);
	       filename[pos] = result0;
	       filename[pos+1] = 0;
	       pos++;
	    }
	 }
      }
      sys_wait(5);
      if (blink_count%16 < 8)
	r_set_attr1(SCREEN1, FILENAME_X+pos, FILENAME_Y, 1);
      else
	r_set_attr1(SCREEN1, FILENAME_X+pos, FILENAME_Y, 0);
      blink_count++;
   }
}

int main() {
   int key, button, button_last;
   static int result0, result1;
   char filename[MAXFNAME+1];

   init_screens();
   init_tenji(SCREEN1, TENJI_WINDOW_X, TENJI_WINDOW_Y);

   process_button(0, &result0, &result1);

   chdir("/rom0");
   do {
      select_file("読込", filename);
   } while(read_file(filename));

   init_text(SCREEN1, 
	     MAIN_WINDOW_X, MAIN_WINDOW_Y, MAIN_WINDOW_W, MAIN_WINDOW_H);
   print_all();

   draw_string(SCREEN1, 1, MAIN_WINDOW_H+2, "メニュー:");
   draw_button(SCREEN1, 7, MAIN_WINDOW_H+2, MENU_BUTTON>>4);
   draw_button(SCREEN1, 8, MAIN_WINDOW_H+2, MENU_BUTTON&0x0f);
   draw_string(SCREEN1, 2, MAIN_WINDOW_H+3, "終了 : START ボタン ");

   button_last = 0;
   cursor_blink_count = 0;
   while(1) {
      key = key_press_check();
      button = key >> 4;
      if (key&2) {
	 hide_cursor();
	 while(key_press_check() != 0)
	   sys_wait(5);
	 break;
      }
      if (button != button_last) {
	 hide_cursor();
	 cursor_blink_count = 0;
	 button_last = button;
	 process_button(button, &result0, &result1);
	 switch(result0) {
	  case BACKSPACE:
	    backspace_char();
	    break;
	  case ENTER:
	    insert_char(result0);
	    break;
	  case ESCAPE:
	    break;

	  case RIGHT:
	    cursor_right();
	    break;
	  case LEFT:
	    cursor_left();
	    break;
	  case DOWN:
	    cursor_down();
	    break;
	  case UP:
	    cursor_up();
	    break;
	  case PAGEDOWN:
	    page_down();
	    break;
	  case PAGEUP:
	    page_up();
	    break;

	  case CONTROL:
	    break;
	  case SHIFT:
	    break;
	  case MENU:
	    process_menu();
	    break;
	  default:
	    if (result0) {
	       insert_char(result0);
	       if (result1) 
		 insert_char(result1);
	    }
	 }
      }
      if (cursor_blink_count % (CURSOR_BLINK_PERIOD*2) == 0)
	show_cursor();
      if (cursor_blink_count % (CURSOR_BLINK_PERIOD*2) ==
	  CURSOR_BLINK_PERIOD)
	hide_cursor();
      cursor_blink_count++;
      sys_wait(5);
   }
   write_file(filename);
}
