#pragma once

#include "assets.h"
#include "cell.h"

#include <onidev/core/primitives.h>
#include <onidev/window/view.h>
#include <vector>

namespace jewels
{
using Posu = od::Posu;

class Game
{
public:
    enum {
        CellSize = 32
    };
    
    Game(GameAssets& assets, od::Sizeu size);
    
    void updateGamePhysics(float dt);
    void updateSoftDieEffect(float dt);
    void spawnGems();
    
    bool swapSelectedGems(float dt);
    void selectGems(float dt);
    
    void step(od::Posi mouse, float dt);
    void predraw(const od::View& view);
    void draw() const;
    
    bool mouseCell(Posu& pos) const;
    bool mousePressCell(Posu& p) const;
    
    Cell& at(Posu p);
    const Cell& at(Posu p) const;
    
    // break line of jewels >= 3
    bool eat(Posu p, int min);
    
    bool stable() const { return _stable; }
    
    // swap1 <=> swap2
    void swap();
    
    static bool aligned(od::Posi p1, od::Posi p2);
    static float distance(od::Posi p1, od::Posi p2);
    
private:
    od::Renderer _renderer;
    od::Sizeu _size;
    std::vector<Cell> _cells;
    bool _stable = false;
    
    bool _valid1 = false;
    bool _valid2 = false;
    
    od::Posi _mouse;
    Posu swap1;
    Posu swap2;
    bool _swapped = false;
};

}