#ifndef DISPLAY_H
#define DISPLAY_H

#include <hardware/spi.h>

namespace lib
{

class PixelStream;

class Display
{
  friend PixelStream;

public:
  Display(uint8_t sck, uint8_t tx, uint8_t cs, uint8_t dc, int baudrate);

  void set_update_area(uint16_t left, uint16_t top, uint16_t width,
                       uint16_t height);
  void fill(uint16_t left, uint16_t top, uint16_t width, uint16_t height,
            uint8_t r, uint8_t g, uint8_t b);
  void fill(uint16_t left, uint16_t top, uint16_t width, uint16_t height,
            const uint8_t* src);

  PixelStream pixels();
  void clear();

private:
  uint8_t sck, tx, cs, dc;
  spi_inst_t* spi;
  int dma;
  bool frame;

  void begin_dma(const volatile uint8_t* src, uint32_t transfer_count,
                 uint32_t pixel_count);

  void send_command(uint8_t command);
  void send_command(uint8_t command, uint8_t param);
  void send_command(uint8_t command, const uint8_t* params,
                    size_t param_count);

  void send_command_and_begin_data_stream(uint8_t command);
  void send_data(uint8_t data);
  void send_data(const uint8_t* data, size_t data_len);
  void end_data_stream();
};

}

#endif // DISPLAY_H
