#ifndef _MATRIX_H
#define _MATRIX_H

#include "Arduino.h"
#include "Print.h"
#include "ks_glcdfont.c"
#include <avr/pgmspace.h>

#define MATRIX_LED_ON 2
#define MATRIX_LED_OFF 0

#define HT16K33_BLINK_CMD 0x80
#define HT16K33_BLINK_DISPLAYON 0x01
#define HT16K33_BLINK_OFF 0
#define HT16K33_BLINK_2HZ  1
#define HT16K33_BLINK_1HZ  2
#define HT16K33_BLINK_HALFHZ  3

//#define HT16K33_CMD_BRIGHTNESS 0x0E
#define matrix_swap(a, b) { int16_t t = a; a = b; b = t; }
// this is the raw HT16K33 controller


class Matrix : public Print{
public:
  Matrix(uint8_t sda_port,uint8_t scl_port);
  void begin(uint8_t _addr);
  void setBrightness(uint8_t b);
  void blinkRate(uint8_t b);
  void writeDisplay(void);
  void clear(void);
  void drawStr(String);
  uint16_t displaybuffer[8]; 
  void drawPixel(int16_t x, int16_t y, uint16_t color);
  void init(uint8_t a);
  void constructor(int16_t w, int16_t h);  
  void invertDisplay(boolean i);
  void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
  void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
  void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
  void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  void fillScreen(uint16_t color);
  void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
  void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color);
  void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
  void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color);
  void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
  void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
  void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
  void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
  void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
  void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
  virtual size_t write(uint8_t);
  void setCursor(int16_t x, int16_t y);
  void setTextColor(uint16_t c);
  void setTextColor(uint16_t c, uint16_t bg);
  void setTextSize(uint8_t s);
  void setTextWrap(boolean w);
  int16_t height(void);
  int16_t width(void);
  void setRotation(uint8_t r);
  uint8_t getRotation(void);
  uint8_t SCL_pin,SDA_pin;
protected:
  int16_t  WIDTH, HEIGHT;   // this is the 'raw' display w/h - never changes
  int16_t  _width, _height; // dependent on rotation
  int16_t  cursor_x, cursor_y;
  uint16_t textcolor, textbgcolor;
  uint8_t  textsize;
  uint8_t  rotation;
  boolean  wrap; // If set, 'wrap' text at right edge of display
private:
  uint8_t i2c_addr;
  void IICbegin(uint8_t sdapin,uint8_t sclpin);
  bool IICstart(uint8_t addr);
  bool IICrestart(uint8_t addr);
  void IICstop();
  uint8_t IICread(uint8_t last);
  bool IICwrite(uint8_t data);
};

#endif

