/*
  crossword -- a crossword game
  Copyright (C) 2000 Falk Hueffner

  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 2 of the License, or (at your option)
  any later version.
  
  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

  $Id: Board.cc,v 1.7 2000/11/21 20:07:48 falk Exp $
*/

#include <assert.h>
#include <iomanip>
#include <iostream>

#include "Board.hh"

Board::Board(istream& in) : tiles(vector<Tile>(Rules::numFields())), _empty(false) {
    Pos p = 0;
    for (unsigned int y = 0; y < Rules::ysize(); ++y) {
	string line;
	getline(in, line);
	assert(line.length() == Rules::xsize());
	for (unsigned int x = 0; x < Rules::xsize(); ++x)
	    tiles[p++] = (line[x] == ' ' ? EMPTY : line[x]);
    }
}

void Board::put(const string& s, Pos p, Dir d) {
    assert(s.length() > 0);
    for (unsigned int i = 0; i < s.length(); ++i) {
	//tiles[p] = Rules::findTile(s[i]);
	tiles[p] = s[i];
	p += d;
    }
    _empty = false;
}

void Board::apply(const Move& move) {
    assert (!move.empty());
    for (Move::const_iterator i = move.begin(); i != move.end(); ++i)
	tiles[i->pos()] = i->tile();
    _empty = false;
}

ostream& operator<<(ostream& out, const Board& b) {
    out << "  ";
    for (unsigned int x = 0; x < Rules::xsize(); ++x)
	out << "   " << char('A' + x);
    out << endl;
    for (unsigned int y = 0; y < Rules::ysize(); ++y) {
	out << "   ";
	for (unsigned int x = 0; x < Rules::xsize(); ++x)
	    out << "+---";
	out << "+\n" << setw(2) << y + 1 << ' ';;
	for (unsigned int x = 0; x < Rules::xsize(); ++x) {
	    out << "| ";
	    Pos p = x + y * Rules::xsize();
	    if (p == Rules::startPos() && b.at(p) == EMPTY)
		out << '*';	// start marker
	    else
		if (b.at(p) == EMPTY) {
		    if (Rules::letterMultiplier(p) == 2)
			out << '·';
		    else if (Rules::letterMultiplier(p) == 3)
			out << ':';
		    else if (Rules::wordMultiplier(p) == 2)
			out << '\'';
		    else if (Rules::wordMultiplier(p) == 3)
			out << '"';
		    else
			out << ' ';
		} else {
		    out << char(b.at(p));
		}
	    out << ' ';
	}
	out << "| " << y + 1 << endl;
    }
    out << "   ";
    for (unsigned int x = 0; x < Rules::xsize(); ++x)
	out << "+---";
    out << "+\n  ";
    for (unsigned int x = 0; x < Rules::xsize(); ++x)
	out << "   " << char('A' + x);

    return out << endl;
}

// Well, I don't want a Pos.cc so this goes here
ostream& operator <<(ostream& out, PPos p) {
    return out << char(p.p % Rules::xsize() + 'A') << p.p / Rules::xsize() + 1;
}


