#ifndef CARD_H
#define CARD_H

#include "flash.h"

#include <pico/stdlib.h>

class CardSlot
{
private:
  static constexpr size_t FLASH_SIZE_MB = 8;

public:
  CardSlot(lib::Flash& flash, uint16_t card_index);

  void set_name(const uint8_t* name, uint8_t length);
  void set_cmc(uint8_t cmc);
  void set_colors(uint8_t colors);

  void mark_unused(lib::Flash& flash);
  void save_data(lib::Flash& flash);
  void erase(lib::Flash& flash);

  uint16_t get_image_start_page_index() const;

  bool is_used() const;
  uint32_t times_erased() const;
  uint8_t get_colors() const;
  uint8_t get_cmc() const;
  const uint8_t* get_name() const;
  uint8_t get_name_length() const;

  bool operator<=(const CardSlot&) const;
  bool operator>=(const CardSlot&) const;

  void each_pixel(lib::Flash& flash, void (*fn)(void*, uint8_t),
                  void* userdata);

  static int32_t get_unused(lib::Flash& flash);

private:
  static constexpr size_t IMAGE_LENGTH = 320 * 240 * 3;

  static constexpr size_t NAME_BITS = 5;
  static constexpr size_t MAX_NAME_LENGTH = 1 << NAME_BITS;

  struct
  {
    bool in_use;
    uint8_t cmc;
    uint8_t colors;
    uint8_t name_length : NAME_BITS;
    uint32_t times_erased;
  } status;
  uint8_t name[MAX_NAME_LENGTH];

  uint16_t card_index;

  void load_data(lib::Flash& flash);

public:
  static constexpr size_t IMAGE_PAGE_COUNT
    = IMAGE_LENGTH / lib::Flash::Page::SIZE;

  // round up to nearest multiple of 16 since
  // that's how many pages there are per sector
  static constexpr size_t TOTAL_PAGE_COUNT
    = 16 * ((IMAGE_PAGE_COUNT + 16) / 16);

  // based on flash size
  static constexpr uint16_t MAX_CARDS
    = FLASH_SIZE_MB * 1024 * 1024
      / (lib::Flash::Page::SIZE * TOTAL_PAGE_COUNT);
};

#endif // CARD_H
