/*
 * arcane - A rogue-like game engine
 * Copyright (C) 2005  Petr Baudis <pasky@ucw.cz>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <cassert>
#include <cctype>
#include <string>
#include <iostream>
using namespace std;

#include "game.h"
#include "mainui.h"
#include "mapobj.h"
#include "player.h"
#include "term.h"
#include "util.h"


class MainUI *ui;


/* XXX: Plenty of this should live in own objects. */


void
MainUI::render() const
{
	int y = 0;

	term_.color(COLOR_GRAY, COLOR_BLACK);
	term_.clear(0, y, term_.width() - 1, y + 1).cursor(0, y) << msgbuf;
	y += 2;

	int bx = max(0, term_.width() - game_.curlevel()->width()) / 2;
	int by = max(0, term_.height() - 5 - game_.curlevel()->height()) / 2 + y;

	game_.curlevel()->draw(term_, bx, by);
#if 0
	while (game_.draw_queue.begin() != game_.draw_queue.end()) {
		std::list<DrawableContainer *>::iterator obj = game_.draw_queue.begin();
		(*obj)->draw(term_, bx, by);
		delete *obj;
		game_.draw_queue.erase(obj);
	}
#endif

	y = term_.height() - 3;
	term_.color(COLOR_GRAY, COLOR_BLACK);
	term_.clear(0, y, term_.width() - 1, y + 2);

	term_.cursor(0, y)
	     .put("  ").put(game_.player().name())
	     .cursor(term_.width() - 9, y)
	     .put("Sp:").put(game_.player().speed(), 4)
	     ;
	y++;

	term_.cursor(0, y)
	     .put("  St:").put(game_.player().st(), 3)
	     .put("  To:").put(game_.player().to(), 3)
	     .put("  Dx:").put(game_.player().dx(), 3)
	     .put("  Pe:").put(game_.player().pe(), 3)
	     ;
	y++;

	term_.cursor(0, y)
	     .put("  DV:").put(game_.player().dv())
	     .put("/PV:").put(game_.player().pv())
	     .put("/AV:").put(game_.player().av())
	     .cursor(20, y)
	     .put("H:").put(game_.player().hp(), 2)
	     .put("/").put(game_.player().maxhp(), 2)
	     .cursor(40, y)
	     .put("L:-/").put((unsigned long)(game_.player().xp()))
	     // debugging only
	     .cursor(60, y)
	     .put("H:").put(game_.player().height())
	     .put("/W:").put(game_.player().weight())
	     ;
}

void
MainUI::msg(const std::string &str)
{
	if (!msgbuf.empty()) msgbuf += " ";
	msgbuf += str;
}

void
MainUI::event_loop()
{
	Key key;
	int ch;
	bool turn_done = false;

	// XXX: this is needed for the initial exploration
	game_.tick();
#if 0
	game_.player().tick(game_);
	game_.curlevel()->posttick(game_);
#endif
	render();

	while ((ch = int(term_ >> key)) != 'q') {
		switch (ch) {
			case KEY_PREV_PAGE: ch = '9';
			case KEY_UP: ch = '8'; break;
			case KEY_HOME: ch = '7'; break;
			case KEY_RIGHT: ch = '6'; break;
			case KEY_LEFT: ch = '4'; break;
			case KEY_NEXT_PAGE: ch = '3'; break;
			case KEY_DOWN: ch = '2'; break;
			case KEY_END: ch = '1'; break;
		}
		if (isdigit(ch)) {
			if (ch != '0' && ch != '5') {
				static enum Direction m[] = {
					DIR_SW, DIR_S, DIR_SE,
					DIR_W,  DIRS,  DIR_E,
					DIR_NW, DIR_N, DIR_NE
				};

				try {
					game_.player().move(m[ch - '1']);
					turn_done = true;
				} catch (class MapObject::X_rockdir x) {
					ui->msg("You squarely hit the wall.");
				}
			} else if (ch == '5') {
				turn_done = true;
			}
		} else if (ch == ',') {
			game_.player().pick();
			turn_done = true;
		} else if (ch == 'd') {
			game_.player().drop();
			turn_done = true;
		}

		if (turn_done) {
			game_.tick();
			render();
			msgbuf = "";
			turn_done = false;
		}
	}
}




#if 0
void
UI::render(void) const
{
	term.put("xyzzy").cursor(1,2).put("bam").color(COLOR_LIGHTBLUE).put("foo bar").color(COLOR_GREEN).put("baz").color(COLOR_LIGHTGREEN);
	term << "lolz!" << 'x';
}

void
UI::event_loop(void)
{
	Key key;

	while ((term >> key) != KEY_ESCAPE) {
		if (key == KEY_UP) {
			term << " foo!" << int(KEY_UP);

			std::string str;
			term >> str;
			term.color(COLOR_YELLOW).put(str);
		}
	}
}
#endif
