#include "map.h"
#include <iostream>
#include <fstream>

#ifndef MAP_CC
#define MAP_CC

int map::created = 0;
int map::deleted = 0;

int DIRX[] = {0, 1, 1, 1, 0,-1,-1,-1, 0};
int DIRY[] = {1, 1, 0,-1,-1,-1, 0, 1, 0};

map::map(int x, int y) {
	height = y;
	width = x;
	for(int i = 0; i < height; i++) {
		rows.push_back(new row(width));
	}
	created++;
}

void map::makeborder(sprite* s) {
	for(int i = 0; i < getwidth(); i++) {
		setsprite(i, 0, s);
		setsprite(i, height-1, s);
		setsprite(0, i, s);
		setsprite(width-1, i, s);
	}
}
void map::scatter(sprite* s, int num) {
	int x, y;
	for(int i = 0; i < num; i++) {
		do {
			x = (rand()%(width-2)) + 1;
			y = (rand()%(height-2)) + 1;
		} while (s->setpos(x, y) != 0);
		setsprite(x, y, s);
	}
}

int map::getwidth() {return width;}
int map::getheight() {return height;}

void map::extendx(int x) {
	if(x == 0) return;
	if(x > 0) width += x; else width -= x;
	for(int i = 0; i < height; i++) {
		rows[i]->extend(x);
	}
}
void map::extendy(int y) {
	if(y == 0) return;
	if(y < 0) {
		height -= y;
		for(int i = y; i < 0; i++) {
			rows.insert(rows.begin(), new row(width));
		}
	} else {
		height += y;
		for(int i = 0; i < y; i++) {
			rows.push_back(new row(width));
		}
	}
}

void map::addrow(int y) {
	if(y < 0 || y >= height) return;
	rows.insert(rows.begin() + y, new row(width));
	height++;
}
void map::addcol(int x) {
	if(x < 0 || x >= width) return;
	for(int y = 0; y < height; y++) {
		rows[y]->addspace(x);
	}
	width++;
}
void map::remrow(int y) {
	if(y < 0 || y >= height) return;
	delete rows[y];
	rows.erase(rows.begin() + y);
	height--;
}
void map::remcol(int x) {
	if(x < 0 || x >= width) return;
	for(int y = 0; y < height; y++) {
		rows[y]->remspace(x);
	}
	width--;
}

sprite* map::spriteat(int x, int y) {
	if(!inbounds(x, y)) return NULL;
	return rows[y]->spriteat(x);
}
void map::setsprite(int x, int y, sprite* s) {
	if(!inbounds(x, y)) return;
	rows[y]->setsprite(x, s);
}

bool map::inbounds(int x, int y) {
	if(x < width && x >= 0 && y < height && y >= 0) return true;
	return false;
}

void map::setcon(console *con) {c = con;}

void map::printmap() {
	if(c == NULL) return;
	c->mv(0,0);
	int x, y;
	for(y = 0; y < getheight(); y++) {
		for(x = 0; x < getwidth(); x++) {
			sprite* s = spriteat(x, y);
			if (s == NULL) {
				c->setcol(BLACK);
				*c << ' ';
			}
			else
			{
				c->ch(s->mychar(), s->mycol());
			}
		}
		*c << '\n';
	}
	*c << '\n';
}

bool map::savemap(std::string fname) {
	std::ofstream file(fname.c_str(), std::ios::out);
	if(!file) return false;

	int x, y;
	for(int y = 0; y < height; y++) {
		for(x = 0; x < width; x++) {
			file << spriteat(x, y)->mysavechar();
		}
		if(y != height) file << '\n';
	}
}

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

map::~map() {
	while(rows.size() > 0) {
		delete rows[0];
		rows.erase(rows.begin());
	}
	deleted++;
}

#endif
