#include <ncurses.h>
#include <cstdint>
#include <climits>
#include <cstdarg>
#include <cstring>

#include "draw_dungeon.h"

char monster_chars[] = "0123456789abcdef";

const char *win_string[] = {
"                                                                                ",
"                                                                                ",
"                                                                                ",
"                                                               *                ",
"                                      **                      ***               ",
"                                      **                       *                ",
"**   ****      ****   **   ****        **    ***    ****                        ",
" **    ***  * * ***  * **    ***  *     **    ***     ***  * ***   ***  ****    ",
" **     **** *   ****  **     ****      **     ***     ****   ***   **** **** * ",
" **      ** **    **   **      **       **      **      **     **    **   ****  ",
" **      ** **    **   **      **       **      **      **     **    **    **   ",
" **      ** **    **   **      **       **      **      **     **    **    **   ",
" **      ** **    **   **      **       **      **      **     **    **    **   ",
" **      ** **    **   **      **       **      **      *      **    **    **   ",
"  *********  ******     ******* **       ******* *******       **    **    **   ",
"    **** ***  ****       *****   **       *****   *****        *** * ***   ***  ",
"          ***                                                   ***   ***   *** ",
"   *****   ***                                                                  ",
" ********  **                                                                   ",
"*      ****                                                                     ",
"                                                                                ",
"                                                                                ",
"                                                                                "
};

const char *lose_string[] = {
"                                                                                ",
"                                                                                ",
"                                          ***                                   ",
"                                           ***                                  ",
"                                            **                                  ",
"                                            **                                  ",
"    **   ****      ****   **   ****         **     ****     ****                ",
"     **    ***  * * ***  * **    ***  *     **    * ***  * * **** *   ***       ",
"     **     **** *   ****  **     ****      **   *   **** **  ****   * ***      ",
"     **      ** **    **   **      **       **  **    ** ****       *   ***     ",
"     **      ** **    **   **      **       **  **    **   ***     **    ***    ",
"     **      ** **    **   **      **       **  **    **     ***   ********     ",
"     **      ** **    **   **      **       **  **    **       *** *******      ",
"     **      ** **    **   **      **       **  **    **  ****  ** **           ",
"      *********  ******     ******* **      **   ******  * **** *  ****    *    ",
"        **** ***  ****       *****   **     *** * ****      ****    *******     ",
"              ***                            ***                     *****      ",
"       *****   ***                                                              ",
"     ********  **                                                               ",
"    *      ****                                                                 ",
"                                                                                ",
"                                                                                ",
"                                                                                "
};

void init_screen() {
  // Initialize ncurses screen
  initscr();
  start_color();
  
  init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
  init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
  init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
  init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
  init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
  init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
  init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
  init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
  
  timeout(100);
  set_escdelay(0);
  
  // Unbuffered input
  cbreak();
  
  // Don't echo back characters that are typed
  noecho();
  
  // Hide the cursor
  curs_set(0);
  nonl();
  intrflush(stdscr, FALSE);
  
  // Make it so keypad characters do what we expect
  keypad(stdscr, TRUE);
  
  // Clear the screen
  clear();
}

void destroy_screen() {
  endwin();
}

void display_message(const char *fmt, ...) {
  attron(COLOR_PAIR(COLOR_WHITE));
  
  move(0, 0);
  clrtoeol();
  
  move(0, 0);
  
  va_list args;
  va_start(args, fmt);
  vwprintw(stdscr, fmt, args);
  va_end(args);
  
  attroff(COLOR_PAIR(COLOR_WHITE));
}

void refresh_screen() {
  refresh();
}

const char *instruction = "Press any key to exit.";

void display_win() { 
  attron(COLOR_PAIR(COLOR_WHITE));
  
  int i;
  clear();
  for (i = 0; i < 23; i++) {
    mvaddstr(i, 0, win_string[i]);
  }
  mvaddstr(23, (80 - strlen(instruction)) / 2, instruction);
  refresh();
  while(getch()==-1);
  
  attroff(COLOR_PAIR(COLOR_WHITE));
}

void display_lose() {  
  attron(COLOR_PAIR(COLOR_WHITE));
  
  int i;
  clear();
  for (i = 0; i < 23; i++) {
    mvaddstr(i, 0, lose_string[i]);
  }
  mvaddstr(23, (80 - strlen(instruction)) / 2, instruction);
  refresh();
  while(getch()==-1);
  
  attroff(COLOR_PAIR(COLOR_WHITE));
}

void print_char(char c, int color) {
  attron(COLOR_PAIR(color));
  addch(c);
  attroff(COLOR_PAIR(color));
}