// Includes
#include "engine.h"

// Variables
SDL_Surface* assets;
Music* music;
Engine *engine;

// Functions
// Quit function
void quit()
{
    // Free assets
    SDL_FreeSurface(assets);
    delete engine;
    // Exit program
    exit(0);
}

// Main function
int main(int argc, char* argv[])
{   
    engine = new Engine("Game", 800, 600);
    engine->initSound();
    engine->targetFrameRate = 60;

    // Load assets
    assets = SDL_LoadBMP("example_assets/sprites.bmp");
    music = new Music("example_assets/crystal_zone.mp3");
    
    // frame map
    std::map<std::string, SDL_Rect> idle = {
        { "idle", { 76, 456, 68, 128 } },
    };

    std::map<std::string, SDL_Rect> front = {
        { "front", { 4, 456, 68, 125 } },
        { "front2", { 76, 456, 68, 128 } },
        { "front3", { 148, 456, 68, 125 } }
    };

    std::map<std::string, SDL_Rect> back = {
        { "back", { 662, 456, 68, 125 } },
        { "back2", { 734, 456, 68, 128 } },
        { "back3", { 806, 456, 68, 125 } }
    };

    std::map<std::string, SDL_Rect> walk = {
        { "walk", { 220, 456, 68, 124 } },
        { "walk2", { 292, 456, 73, 127 } },
        { "walk3", { 369, 456, 68, 124 } }
    };

    std::map<std::string, SDL_Rect> test = {
        { "test", { 4, 2095, 68, 59 } },
        { "test2", { 76, 2095, 68, 59 } }
    };

    // Create sprite and animation
    Sprite* sprite = new Sprite(engine->renderer, assets);
    AnimationManager* animations = new AnimationManager(sprite);
    animations->addAnimation("idle", idle, 10, false, true, false, false);
    animations->addAnimation("walk_left", walk, 10, false, true, true, false);
    animations->addAnimation("walk_right", walk, 10, true, true, true, false);
    animations->addAnimation("walk_back", back, 10, false, true, true, false);
    animations->addAnimation("walk_front", front, 10, false, true, true, true);
    animations->addAnimation("test", test, 20, false, true, false, false);
    animations->setAnimation("idle");

    // Play music
    music->play();

    // Main loop
    while (true)
    {
        // Start time
        engine->startFrame();

        // Update input
        engine->update();

        // Exit if window s closed
        if (engine->input.exit || engine->input.activeKeys[SDLK_ESCAPE])
        {
            quit();
        } 

        if (engine->input.activeKeys[SDLK_d] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_RIGHT] || engine->input.controllers[0].leftStickX > 8000)
        {
            animations->setAnimation("walk_right");
            sprite->move({ 1, 0 });
        }
        if (engine->input.activeKeys[SDLK_a] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_LEFT]  || engine->input.controllers[0].leftStickX < -8000)

        {
            animations->setAnimation("walk_left");
            sprite->move({ -1, 0 });
        }
        if (engine->input.activeKeys[SDLK_w] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_UP] || engine->input.controllers[0].leftStickY < -8000)
        {
            animations->setAnimation("walk_back");
            sprite->move({ 0, -1 });
        }
        if (engine->input.activeKeys[SDLK_s] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_DOWN] || engine->input.controllers[0].leftStickY > 8000)
        {
            animations->setAnimation("walk_front");
            sprite->move({ 0, 1 });
        }
        if (engine->input.activeKeys[SDLK_SPACE] || engine->input.controllers[0].buttons[CBUTTONS::A])
        {
            animations->playAnimation("test");
        }
        if (!engine->input.keysPressed({ SDLK_w, SDLK_a, SDLK_s, SDLK_d }) && engine->input.controllers[0].leftStickX < 8000 && engine->input.controllers[0].leftStickX > -8000 &&
            engine->input.controllers[0].leftStickY < 8000 && engine->input.controllers[0].leftStickY > -8000 &&
            !engine->input.controllerPressed({ CBUTTONS::DPAD_UP, CBUTTONS::DPAD_DOWN, CBUTTONS::DPAD_LEFT, CBUTTONS::DPAD_RIGHT }))
        {
            animations->setAnimation("idle");
        }
    
        // Update animation
        animations->update();

        // Clear screen
        engine->clear({ 100, 150, 255, 255 });

        // Draw sprite
        animations->draw(engine->renderer);

        // Update screen    
        engine->render();
    }
    return 0;
}