#include "Tile.h"
#include "CollisionHandler.h"
#include "Level.h"

#include <iostream>
#include <sstream>

using namespace std;

Tile::Tile()
:Object()
{
}

Tile::Tile(Sprite* sprite, bool collidable, int x, int y, double depth)
:Object(),_sprite(sprite),_draw(true),_existDBox(false)
{
	_type = TILE;
	// FIXME  make this general
	stringstream id;
	id <<this;
	_id = id.str();

	_collidable = collidable;
	_box.x = x;
	_box.y = y;

	_box.w = _sprite->width();
	_box.h = _sprite->height();

	_drawBox = _box;

	_depth = depth;
}

Object *Tile::copy()
{
	return new Tile(*this);
}

void Tile::collide( Object* o )
{
	 //does nothing
}
void Tile::draw()
{
	if(_draw) {
		if(_existDBox)
			_sprite->drawBox(_box.x,_box.y,_drawBox);
		else
			_sprite->draw(_box.x,_box.y);
	}
}

void Tile::update()
{
	_sprite->update();
}

void Tile::calcDrawBox()
{
	if(_draw) {
		_drawBox = getSquare(_sprite, _depth);

		for(int i = _box.x; i < _box.x + _drawBox.w; i += Level::tileWidth) {
			for(int j = _box.y; j < _box.y + _drawBox.h; j += Level::tileHeight) {
				Tile *t = Level::instance()->getTileFromPixels(i,j);
				if(t && t->_sprite == _sprite && t->_depth == _depth) {
					t->_draw = false;
				}
			}
		}

		_draw = true;
		_existDBox = true;
	}
}

SDL_Rect Tile::getSquare(Sprite *sprite, double depth)
{
	SDL_Rect square = _box;
	Tile *diag = Level::instance()->getTileFromPixels(_box.x+Level::tileWidth,_box.y+Level::tileHeight);
	if(diag == NULL || (sprite != diag->_sprite || diag->_depth <= depth)) {
		int i = _box.y + Level::tileHeight;
		Tile *t1 = Level::instance()->getTileFromPixels(_box.x,i);

		int j = _box.x + Level::tileWidth;
		Tile *t2 = Level::instance()->getTileFromPixels(j,_box.y);

		
		if(t1 != NULL) {
			while(t1 != NULL && (sprite == t1->_sprite && t1->_depth > depth)) {
				square.h += Level::tileHeight;

				i += Level::tileHeight;
				t1 = Level::instance()->getTileFromPixels(_box.x,i);
			}
		}
		
		else if(t2 != NULL) {
			while(t2 != NULL && (sprite == t2->_sprite && t2->_depth > depth)) {
				square.w += Level::tileWidth;

				j += Level::tileWidth;
				t2 = Level::instance()->getTileFromPixels(j,_box.y);
			}
		}
	}
	else {
		SDL_Rect diagBox = diag->getSquare(sprite, depth);

		for(int i = _box.x + Level::tileWidth; i < _box.x + diagBox.w + Level::tileWidth; i += Level::tileWidth) {
			Tile *t = Level::instance()->getTileFromPixels(i,_box.y);

			if(t == NULL || (sprite != t->_sprite || t->_depth <= depth))
				break;
			else
				square.w += Level::tileWidth;
		}

		for(int i = _box.y + Level::tileHeight; i < _box.y + diagBox.h + Level::tileHeight; i += Level::tileHeight) {
			Tile *t = Level::instance()->getTileFromPixels(_box.x,i);
			if(t == NULL || (sprite != t->_sprite || t->_depth <= depth))
				break;
			else
				square.h += Level::tileHeight;
		}
	}

	return square;
}