#include <curses.h>
#include <iostream>
#include <sstream>
#include "console.h"

#ifndef CONSOLE_CC
#define CONSOLE_CC

int console::created = 0;
int console::deleted = 0;

console::console() {
  w = NULL;
  created++;
}
console::console(WINDOW *win) {
  w = win;
  created++;
}

console console::operator<<(std::string &s) {
  str(s);
  return *this;
}
console console::operator<<(char *s) {
  str(s);
  return *this;
}
console console::operator<<(char c) {
  ch(c);
  return *this;
}
console console::operator<<(int i) {
	std::ostringstream s;
  s << i;
  str(s.str());
  return *this;
}

int console::cattr(int color) {
  switch(color) {
    case RED:
    case GREEN:
    case BROWN:
    case BLUE:
    case PURPLE:
    case CYAN:
    case GREY:
      return COLOR_PAIR(color);
      break;
    case BRIGHTRED:
    case BRIGHTGREEN:
    case YELLOW:
    case BRIGHTBLUE:
    case BRIGHTPURPLE:
    case BRIGHTCYAN:
    case WHITE:
      return COLOR_PAIR(color - 7) | A_BOLD;
      break;
  }
}
void console::setcol(int c) {
  if(w == NULL) attrset(cattr(c));
  else wattrset(w, cattr(c));
}

void console::ch(char c) {
  if(w == NULL) addch(c);
  else waddch(w, c);
}
void console::ch(char c, int col) {
  col = cattr(col);
  if(w == NULL) {
    attrset(col);
    addch(c);
  }
  else {
    wattrset(w, col);
    waddch(w, c);
  }
}
void console::mvch(int y, int x, char c) {
  if(w == NULL) mvaddch(y, x, c);
  else mvwaddch(w, y, x, c);
}
void console::mvch(int y, int x, char c, int col) {
  col = cattr(col);
  if(w == NULL) {
    attrset(col);
    mvaddch(y, x, c);
  }
  else {
    wattrset(w, col);
    mvwaddch(w, y, x, c);
  }
}
void console::mv(int y, int x) {
  if(w == NULL) move(y, x);
  else wmove(w, y, x);
}
void console::ch(chtype c, int col) {
  col = cattr(col);
  if(w == NULL) addch(c | col);
  else waddch(w, c | col);
}
void console::str(std::string s) {
  if(w == NULL) addstr(s.c_str());
  else waddstr(w, s.c_str());
}
void console::str(std::string s, int col) {
  col = cattr(col);
  if(w == NULL) {
    attrset(col);
    addstr(s.c_str());
  }
  else {
    wattrset(w, col);
    waddstr(w, s.c_str());
  }
}
void console::mvstr(int y, int x, std::string s) {
  if(w == NULL) mvaddstr(y, x, s.c_str());
  else mvwaddstr(w, y, x, s.c_str());
}
void console::mvstr(int y, int x, std::string s, int col) {
  col = cattr(col);
  if(w == NULL) {
    attrset(col);
    mvaddstr(y, x, s.c_str());
  }
  else {
    wattrset(w, col);
    mvwaddstr(w, y, x, s.c_str());
  }
}
void console::clr() {
  if(w == NULL) clear();
  else wclear(w);
}

int console::getwidth() {
  if(w == NULL) return COLS;
  int x, y;
  getmaxyx(w, y, x);
  return x;
}
int console::getheight() {
  if(w == NULL) return LINES;
  int x, y;
  getmaxyx(w, y, x);
  return y;
}
  
std::string console::input() {
  char a = getch();
  std::string inp = "";
  while(a != '\n') {
    if(a == 7) {
      if(inp.length() > 0) {
	inp = inp.substr(0, inp.length() - 1);
	int x, y;
	if(w == NULL) getyx(stdscr, y, x);
	else getyx(w, y, x);
	mvch(y, x-1, ' ');
	if(w == NULL) move(y, x-1);
	else wmove(w, y, x-1);
      }
    }
    else {
      inp = inp + a;
      ch(a);
    }
    a = getch();
  }
  ch('\n');
  return inp;
}
char console::get() {
  return getch();
}

int console::print() {
	using std::cout;
	using std::endl;
  if(created == 0 && deleted == 0) return 0;
  cout << "--console--" << endl;
  cout << "  Created: " << created << endl;
  cout << "  Deleted: " << deleted << endl;
  cout << endl;
  return created != deleted;
}

console::~console() {
  delete w;
  deleted++;
}

#endif
