#include <windows.h>
#include <SFML\Graphics.hpp>
#include <SFML/Graphics.hpp>
#include <Box2D\Box2D.h>

static const float SCALE = 30.f;

sf::Event event;

void CreateBox(b2World& World, int MouseX, int MouseY)
{
	b2BodyDef BodyDef;
	BodyDef.position = b2Vec2(MouseX / SCALE, MouseY / SCALE);
	BodyDef.type = b2_dynamicBody;

	b2Body* Body = World.CreateBody(&BodyDef);
	Body->SetUserData("BOX");

	b2PolygonShape Shape;
	Shape.SetAsBox((32.f / 2) / SCALE, (32.f / 2) / SCALE);

	b2FixtureDef FixtureDef;
	FixtureDef.density = 1.f;
	FixtureDef.friction = 0.7f;
	FixtureDef.restitution = 0.5f;
	FixtureDef.shape = &Shape;

	Body->CreateFixture(&FixtureDef);
}

void CreateCircle(b2World& World, int MouseX, int MouseY)
{
	b2BodyDef BodyDef;
	BodyDef.position = b2Vec2(MouseX / SCALE, MouseY / SCALE);
	BodyDef.type = b2_dynamicBody;

	b2Body* Body = World.CreateBody(&BodyDef);
	Body->SetUserData("CIRCLE");

	b2CircleShape Shape;
	Shape.m_radius = 16/SCALE;

	b2FixtureDef FixtureDef;
	FixtureDef.density = 1.f;
	FixtureDef.friction = 0.7f;
	FixtureDef.restitution = 0.5f;
	FixtureDef.shape = &Shape;

	Body->CreateFixture(&FixtureDef);
}

void CreateBody(b2World& World, float X, float Y, float a, float b, float radian=0.0)
{
	b2BodyDef BodyDef;
	BodyDef.position = b2Vec2(X / SCALE, Y / SCALE);
	BodyDef.type = b2_staticBody;
	BodyDef.angle = radian;
	
	b2PolygonShape Shape;
	Shape.SetAsBox((a / 2) / SCALE, (b / 2) / SCALE);

	b2FixtureDef FixtureDef;
	FixtureDef.shape = &Shape;

	b2Body* Body = World.CreateBody(&BodyDef);
	Body->CreateFixture(&FixtureDef);
}

int main()
{
	// ukrywanie konsoli
	HWND hWnd = GetConsoleWindow();
	ShowWindow(hWnd, SW_HIDE);

	// tworzenie okna //
	sf::RenderWindow Window(sf::VideoMode(1300, 700, 32), "Window", sf::Style::Default);
	Window.setFramerateLimit(100);
	
	// tworzenie świata //
	b2Vec2 Gravity(0.f, 9.8f);
	b2World World(Gravity, true);

	// tworzenie ciał //
	CreateBody(World, 0, 409, 1000, 250, 0.8);
	CreateBody(World, 556, 644, 1111, 113);
	CreateBody(World, 1206, 501, 186, 399);


	// tworzenie tekstur //
	sf::Texture GroundTexture;
	GroundTexture.loadFromFile("graphics/ground.png");

	sf::Texture BoxTexture;
	BoxTexture.loadFromFile("graphics/box.png");
	
	sf::Texture CircleTexture;
	CircleTexture.loadFromFile("graphics/circle.gif");

	sf::Sprite sprajt;
	sprajt.setTexture(GroundTexture);


	// główna pętla programu //
	while (Window.isOpen())
	{
		while (Window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed)
				Window.close();

			if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
				Window.close();
		}

		// obsuga myszki //
		if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
		{
			int MouseX = sf::Mouse::getPosition(Window).x;
			int MouseY = sf::Mouse::getPosition(Window).y;
			CreateBox(World, MouseX, MouseY);
		}

		if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
		{
			int MouseX = sf::Mouse::getPosition(Window).x;
			int MouseY = sf::Mouse::getPosition(Window).y;
			CreateCircle(World, MouseX, MouseY);
		}

		// krok czasowy //
		World.Step(1 / 60.f, 8, 3);

		Window.draw(sprajt);

		int BodyCount = 0;

		// łączenie ciał i tekstur //
		for (b2Body* BodyIterator = World.GetBodyList(); BodyIterator != 0; BodyIterator = BodyIterator->GetNext())
		{
			if (BodyIterator->GetType() == b2_dynamicBody)
			{
				if (BodyIterator->GetUserData() == "BOX")
				{
					sf::Sprite Sprite;
					Sprite.setTexture(BoxTexture);
					Sprite.setOrigin(16.f, 16.f);
					Sprite.setPosition(SCALE * BodyIterator->GetPosition().x, SCALE * BodyIterator->GetPosition().y);
					Sprite.setRotation(BodyIterator->GetAngle() * 180 / b2_pi);
					Window.draw(Sprite);
					++BodyCount;
				}
				else if(BodyIterator->GetUserData() == "CIRCLE")
				{
					BodyIterator->GetUserData();
					sf::Sprite Sprite;
					Sprite.setTexture(CircleTexture);
					Sprite.setOrigin(16, 16);
					Sprite.setPosition(SCALE * BodyIterator->GetPosition().x, SCALE * BodyIterator->GetPosition().y);
					Sprite.setRotation(BodyIterator->GetAngle() * 180 / b2_pi);
					Window.draw(Sprite);
					++BodyCount;
				}
			}
		}

		Window.display();
	}

	return 0;
}

