#include <SFML/Graphics.hpp>
#include <iostream>


#include <cmath>
bool checkCircleRectCollision(const sf::CircleShape& circle, const sf::RectangleShape& rect) {
    // Circle's center
    sf::Vector2f circleCenter = circle.getPosition() + sf::Vector2f(circle.getRadius(), circle.getRadius());

    // Rectangle's boundaries
    sf::FloatRect rectBounds = rect.getGlobalBounds();

    // Find the closest point on the rectangle to the circle's center
    float closestX = std::max(rectBounds.left, std::min(circleCenter.x, rectBounds.left + rectBounds.width));
    float closestY = std::max(rectBounds.top, std::min(circleCenter.y, rectBounds.top + rectBounds.height));

    // Calculate the distance between the circle's center and this closest point
    float dx = circleCenter.x - closestX;
    float dy = circleCenter.y - closestY;

    // If the distance is less than the radius, there's a collision
    float distanceSquared = dx * dx + dy * dy;
    return distanceSquared <= (circle.getRadius() * circle.getRadius());
}


bool checkCircleCollision(const sf::CircleShape& circle1, const sf::CircleShape& circle2) {
    float dx = circle1.getPosition().x - circle2.getPosition().x;
    float dy = circle1.getPosition().y - circle2.getPosition().y;
    float distance = std::sqrt(dx * dx + dy * dy);
    float combinedRadius = circle1.getRadius() + circle2.getRadius();
    return distance < combinedRadius;
}
// Add your collision functions here...
bool checkAABBCollision(const sf::RectangleShape& rect1, const sf::RectangleShape& rect2) {
    return rect1.getGlobalBounds().intersects(rect2.getGlobalBounds());
}

bool pixelPerfectCollision(const sf::Sprite& sprite1, const sf::Sprite& sprite2) {
    sf::FloatRect intersection;
    if (!sprite1.getGlobalBounds().intersects(sprite2.getGlobalBounds(), intersection)) {
        return false; // No AABB collision means no need for pixel check.
    }

    sf::Image img1 = sprite1.getTexture()->copyToImage();
    sf::Image img2 = sprite2.getTexture()->copyToImage();

    for (int x = intersection.left; x < intersection.left + intersection.width; ++x) {
        for (int y = intersection.top; y < intersection.top + intersection.height; ++y) {
            sf::Vector2f localPos1 = sprite1.getInverseTransform().transformPoint(x, y);
            sf::Vector2f localPos2 = sprite2.getInverseTransform().transformPoint(x, y);

            if (img1.getPixel(localPos1.x, localPos1.y).a > 0 &&
                img2.getPixel(localPos2.x, localPos2.y).a > 0) {
                return true; // Overlapping opaque pixels detected.
            }
        }
    }
    return false;
}

int main() {
    sf::RenderWindow window(sf::VideoMode(800, 600), "Circle-Rectangle Collision");

    sf::CircleShape circle(50);
    circle.setPosition(200, 150);


    sf::RectangleShape rect(sf::Vector2f(120, 80));
    rect.setPosition(400, 300);

    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) window.close();
        }

        // Example: Moving the circle with arrow keys to test collision
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) circle.move(-1, 0);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) circle.move(1, 0);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) circle.move(0, -1);
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) circle.move(0, 1);

        bool isColliding = checkCircleRectCollision(circle, rect);

        // Render everything
        window.clear();
        window.draw(circle);
        window.draw(rect);

        // Change color if colliding
        if (isColliding) {
            rect.setFillColor(sf::Color::Red);
        }
        else {
            rect.setFillColor(sf::Color::Green);
        }

        window.display();
    }

    return 0;
}

//int main() {
//    sf::RenderWindow window(sf::VideoMode(800, 600), "Collision Detection Demo");
//    // Setup shapes for demonstration
//    sf::RectangleShape rect1(sf::Vector2f(100, 100));
//    sf::RectangleShape rect2(sf::Vector2f(100, 100));
//    rect1.setPosition(100, 100);
//    rect2.setPosition(300, 300);
//
//    while (window.isOpen()) {
//        sf::Event event;
//        while (window.pollEvent(event)) {
//            if (event.type == sf::Event::Closed) window.close();
//        }
//
//        // Basic movement with arrow keys for testing
//        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) rect1.move(-1, 0);
//        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) rect1.move(1, 0);
//        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) rect1.move(0, -1);
//        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) rect1.move(0, 1);
//
//        // Check and display collision results
//        bool aabbCollision = checkAABBCollision(rect1, rect2);
//
//        // Render everything
//        window.clear();
//        window.draw(rect1);
//        window.draw(rect2);
//
//        window.display();
//    }
//
//    return 0;
//}