#include <SFML/Graphics.hpp>

#include<iostream>

#include "Textures.hpp"
#include "GameObjects.hpp"
#include "NatureObjects.hpp"
#include "Player.hpp"

std::vector < GameObject* > gameObjects;
Player* player;

void loadTextures();
void createGameObjects();
bool collisions(GameObject* object, float dx, float dy);
bool collisionTwoElipses(float x1, float y1, float rx1, float ry1, float x2, float y2, float rx2, float ry2);

int main()
{
    sf::RenderWindow* window = new sf::RenderWindow(sf::VideoMode(1280, 720), "RPG");
    window->setFramerateLimit(60);
    
    loadTextures();
    createGameObjects();
    player = new Player();
    player->setPosition(70, 100);
    while (window->isOpen())
    {
        sf::Event event;
        while (window->pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window->close();

            if (event.type == sf::Event::KeyPressed) {
                // WASD
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && !collisions(player, 0, -player->stepSize)) player->move(0);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::D) && !collisions(player, player->stepSize, 0)) player->move(1);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) && !collisions(player, 0, player->stepSize)) player->move(2);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::A) && !collisions(player, -player->stepSize, 0)) player->move(3);

                // UP DOWN LEFT RIGHT
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && !collisions(player, 0, -player->stepSize)) player->move(0);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && !collisions(player, player->stepSize, 0)) player->move(1);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && !collisions(player, 0, player->stepSize)) player->move(2);
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && !collisions(player, -player->stepSize, 0)) player->move(3);
            }


        } //while

        // UPDATES
        cout << "cursor at: " << sf::Mouse::getPosition(*window).x << "," << sf::Mouse::getPosition(*window).y << endl;

        for (auto& go : gameObjects)
            go->update();
        player->update();



        // RENDER
        window->clear(sf::Color(64,128,64));
        for (auto& go : gameObjects)
            go->render(window);
        player->render(window);
        window->display();
        sf::sleep(sf::milliseconds(150));

    } //while
    return 0;
}

void loadTextures()
{
    loadTexture("assets/tree1.png", 58, 106);
    loadTexture("assets/rocks1.png", 67, 83);

}

void createGameObjects()
{
    // trees
    gameObjects.push_back(new NatureObject(100, 50, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(150, 200, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(200, 300, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(300, 30, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(400, 70, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(50, 250, 16, getTexture("tree1.png")));

    gameObjects.push_back(new NatureObject(420, 270, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(650, 100, 16, getTexture("tree1.png")));
    gameObjects.push_back(new NatureObject(600, 280, 16, getTexture("tree1.png")));


    // rocks
    gameObjects.push_back(new NatureObject(30, 150, 40, getTexture("rocks1.png")));
    gameObjects.push_back(new NatureObject(320, 170, 40, getTexture("rocks1.png")));
    gameObjects.push_back(new NatureObject(350, 350, 40, getTexture("rocks1.png")));

}

bool collisions(GameObject* object, float dx, float dy)
{
    for (auto& go : gameObjects) {
        if ( go!=object && collisionTwoElipses(object->x+dx, object->y+dy, object->radius, object->radius / 2.f, go->x, go->y, go->radius, go->radius / 2.f))
            return true;
    }

    return false;
}

bool collisionTwoElipses(float x1, float y1, float rx1, float ry1, float x2, float y2, float rx2, float ry2)
{
    // Obliczamy odległość między środkami elips
    float dx = x2 - x1;
    float dy = y2 - y1;
    float d = sqrt(dx * dx + dy * dy);

    // Sprawdzamy czy suma promieni jest większa niż odległość między środkami elips
    if (d <= rx1 + rx2 && d <= ry1 + ry2)
        return true;
    else
        return false;
}