#ifndef _classSSD1963_H_
#define _classSSD1963_H_

#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#include "tipos.h"
#include "classPio.h"
#include "asf.h"

/*************************************
* Color Definition
*************************************/
#define WHITE         	 0xFFFF
#define BLACK         	 0x0000
#define BLUE         	 0x001F
#define BRED             0XF81F
#define GRED 			 0XFFE0
#define GBLUE			 0X07FF
#define RED           	 0xF800
#define MAGENTA       	 0xF81F
#define GREEN         	 0x07E0
#define CYAN          	 0x7FFF
#define YELLOW        	 0xFFE0
#define BROWN 			 0XBC40
#define BRRED 			 0XFC07
#define GRAY  			 0X8430
#define DARKBLUE      	 0X01CF
#define LIGHTBLUE      	 0X7D7C
#define GRAYBLUE       	 0X5458
#define LIGHTGREEN     	 0X841F
#define LGRAY 			 0XC618
#define LGRAYBLUE        0XA651
#define LBBLUE           0X2B12

// VGA color palette
#define VGA_BLACK		0x0000
#define VGA_WHITE		0xFFFF
#define VGA_RED			0xF800
#define VGA_GREEN		0x0400
#define VGA_BLUE		0x001F
#define VGA_SILVER		0xC618
#define VGA_GRAY		0x8410
#define VGA_MAROON		0x8000
#define VGA_YELLOW		0xFFE0
#define VGA_OLIVE		0x8400
#define VGA_LIME		0x07E0
#define VGA_AQUA		0x07FF
#define VGA_TEAL		0x0410
#define VGA_NAVY		0x0010
#define VGA_FUCHSIA		0xF81F
#define VGA_PURPLE		0x8010
#define VGA_TRANSPARENT	0xFFFFFFFF


// the SSD1963 controller can be connected to the TFT screen with 18 or 24 data lines. So we need to tell the constructor which one.
static const uint8_t TFTBUS16 = 16;
static const uint8_t TFTBUS18 = 18;
extern classPio Puerto;

class classSSD1963{

    private:

        static const uint8_t SSD1963_NOP                   = 0x00;
        static const uint8_t SSD1963_SoftReset             = 0x01;
        static const uint8_t SSD1963_GetPowerMode          = 0x0A;
        static const uint8_t SSD1963_GetAddressMode        = 0x0B;
        static const uint8_t SSD1963_GetDisplayMode        = 0x0D;
        static const uint8_t SSD1963_GetTearEffectsStatus  = 0x0E;
        static const uint8_t SSD1963_EnterSleepMode        = 0x10;
        static const uint8_t SSD1963_ExitSleepMode         = 0x11;
        static const uint8_t SSD1963_EnterPartialMode      = 0x12;
        static const uint8_t SSD1963_EnterNormalMode       = 0x13;
        static const uint8_t SSD1963_ExitInvertMode        = 0x20;
        static const uint8_t SSD1963_EnterInvertMode       = 0x21;
        static const uint8_t SSD1963_SetGammaCurve         = 0x26;
        static const uint8_t SSD1963_SetDisplayOff         = 0x28;
        static const uint8_t SSD1963_SetDisplayOn          = 0x29;
        static const uint8_t SSD1963_SetColumnAddress      = 0x2A;
        static const uint8_t SSD1963_SetPageAddress        = 0x2B;
        static const uint8_t SSD1963_WriteMemoryStart      = 0x2C;
        static const uint8_t SSD1963_ReadMemoryStart       = 0x2E;
        static const uint8_t SSD1963_SetPartialArea        = 0x30;
        static const uint8_t SSD1963_SetScrollArea         = 0x33;
        static const uint8_t SSD1963_SetTearOff            = 0x34;
        static const uint8_t SSD1963_SetTearOn             = 0x35;
        static const uint8_t SSD1963_SetAddressMode        = 0x36;
        static const uint8_t SSD1963_SetScrollStart        = 0x37;
        static const uint8_t SSD1963_ExitIdleMode          = 0x38;
        static const uint8_t SSD1963_EnterIdleMode         = 0x39;
        static const uint8_t SSD1963_WriteMemoryContinue   = 0x3C;
        static const uint8_t SSD1963_ReadMemoryContinue    = 0x3E;
        static const uint8_t SSD1963_SetTearScanline       = 0x44;
        static const uint8_t SSD1963_GetScanline           = 0x45;
        static const uint8_t SSD1963_ReadDDB               = 0xA1;
        static const uint8_t SSD1963_SetLCDMode            = 0xB0;
        static const uint8_t SSD1963_GetLCDMode            = 0xB1;
        static const uint8_t SSD1963_SetHoriPeriod         = 0xB4;
        static const uint8_t SSD1963_GetHoriPeriod         = 0xB5;
        static const uint8_t SSD1963_SetVertPeriod         = 0xB6;
        static const uint8_t SSD1963_GetVertPeriod         = 0xB7;
        static const uint8_t SSD1963_SetGPIOConf           = 0xB8;
        static const uint8_t SSD1963_GetGPIOConf           = 0xB9;
        static const uint8_t SSD1963_SetGPIOValue          = 0xBA;
        static const uint8_t SSD1963_GetGPIOValue          = 0xBB;
        static const uint8_t SSD1963_SetPostProc           = 0xBC;
        static const uint8_t SSD1963_GetPostProc           = 0xBD;
        static const uint8_t SSD1963_SetPWMConf            = 0xBE;
        static const uint8_t SSD1963_GetPWMConf            = 0xBF;
        static const uint8_t SSD1963_SetLCDGen0            = 0xC0;
        static const uint8_t SSD1963_GetLCDGen0            = 0xC1;
        static const uint8_t SSD1963_SetLCDGen1            = 0xC2;
        static const uint8_t SSD1963_GetLCDGen1            = 0xC3;
        static const uint8_t SSD1963_SetLCDGen2            = 0xC4;
        static const uint8_t SSD1963_GetLCDGen2            = 0xC5;
        static const uint8_t SSD1963_SetLCDGen3            = 0xC6;
        static const uint8_t SSD1963_GetLCDGen3            = 0xC7;
        static const uint8_t SSD1963_SetGPIO0Rop           = 0xC8;
        static const uint8_t SSD1963_GetGPIO0Rop           = 0xC9;
        static const uint8_t SSD1963_SetGPIO1Rop           = 0xCA;
        static const uint8_t SSD1963_GetGPIO1Rop           = 0xCB;
        static const uint8_t SSD1963_SetGPIO2Rop           = 0xCC;
        static const uint8_t SSD1963_GetGPIO2Rop           = 0xCD;
        static const uint8_t SSD1963_SetGPIO3Rop           = 0xCE;
        static const uint8_t SSD1963_GetGPIO3Rop           = 0xCF;
        static const uint8_t SSD1963_SetDBCConf            = 0xD0;
        static const uint8_t SSD1963_GetDBCConf            = 0xD1;
        static const uint8_t SSD1963_SetDBCTh              = 0xD4;
        static const uint8_t SSD1963_GetDBCTh              = 0xD5;
        static const uint8_t SSD1963_SetPLL                = 0xE0;
        static const uint8_t SSD1963_SetPLLMN              = 0xE2;
        static const uint8_t SSD1963_GetPLLMN              = 0xE3;
        static const uint8_t SSD1963_GetPLLStatus          = 0xE4;
        static const uint8_t SSD1963_SetDeepSleep          = 0xE5;
        static const uint8_t SSD1963_SetLShiftFreq         = 0xE6;
        static const uint8_t SSD1963_GetLShiftFreq         = 0xE7;
        static const uint8_t SSD1963_SetPixelDataInterface = 0xF0;
        static const uint8_t SSD1963_GetPixelDataInterface = 0xF1;

        static const uint16_t SSD1963_EMODE = 0x0003;

        static const uint16_t SSD1963_TRI = 0x8000;
        static const uint16_t SSD1963_DFM = 0x4000;
        static const uint16_t SSD1963_BGR = 0x1000;
        static const uint16_t SSD1963_HWM = 0x0200;
        static const uint16_t SSD1963_ORG = 0x0080;
        static const uint16_t SSD1963_ID0 = 0x0000;
        static const uint16_t SSD1963_ID1 = 0x0010;
        static const uint16_t SSD1963_ID2 = 0x0020;
        static const uint16_t SSD1963_ID3 = 0x0030;
        static const uint16_t SSD1963_AM  = 0x0008;

        static const uint16_t   HDP=799;
        static const uint16_t   HT=928;
        static const uint16_t   HPS=46;
        static const uint16_t   LPS=15;
        static const uint8_t    HPW=48;

        static const uint16_t   VDP=479;
        static const uint16_t   VT=525;
        static const uint16_t   VPS=16;
        static const uint16_t   FPS=8;
        static const uint8_t    VPW=16;
		
		uint16_t _width;
		uint16_t _height;
		uint8_t rotation;

        void command(uint16_t cmd);
        void data8(uint8_t cmd);
        void data(uint16_t cmd);
       
		
		 //===================================================
    // Definicion de macros
    
    #define TFT_BKL_ON()   Puerto.set_pin_high(PIOD,TFT_BKL_PIN_bp);
    #define TFT_BKL_OFF()  Puerto.set_pin_low(PIOD,TFT_BKL_PIN_bp);
    #define TFT_RST_OFF()  Puerto.set_pin_high(PIOD,TFT_RST_PIN_bp);
    #define TFT_RST_ON()   Puerto.set_pin_low(PIOD,TFT_RST_PIN_bp);
    
	
	//Fast Macros
	#define TFT_CS_LOW()   PIOD->PIO_CODR = 1 << (TFT_CS_PIN_bp & 0x1F);
    #define TFT_CS_HIGH()  PIOD->PIO_SODR = 1 << (TFT_CS_PIN_bp & 0x1F);
    #define TFT_DC_LOW()   PIOD->PIO_CODR = 1 << (TFT_DC_PIN_bp & 0x1F);
    #define TFT_DC_HIGH()  PIOD->PIO_SODR = 1 << (TFT_DC_PIN_bp & 0x1F);	
	#define TFT_RD_LOW()   PIOD->PIO_CODR = 1 << (TFT_RD_PIN_bp & 0x1F);
    #define TFT_RD_HIGH()  PIOD->PIO_SODR = 1 << (TFT_RD_PIN_bp & 0x1F);	
	#define TFT_WR_LOW()   PIOD->PIO_CODR = 1 << (TFT_WR_PIN_bp & 0x1F);
	#define TFT_WR_HIGH()  PIOD->PIO_SODR = 1 << (TFT_WR_PIN_bp & 0x1F);

    protected:
         uint8_t bus_width;
        void setAddrWindow(int x0, int y0, int x1, int y1);
        int _brightness;
   public:
        // default constructor
        classSSD1963();
        // default destructor
        ~classSSD1963();
       

        static const int Width = 800; // Don't use this any more!
        static const int Height = 480; // Don't use this any more!

        void fillScreen(uint16_t color);
        void setPixel(int x, int y, uint16_t color);
        void drawVerticalLine(int x, int y, int h, uint16_t color);
        void drawHorizontalLine(int x, int y, int w, uint16_t color);
        void fillRectangle(int x, int y, int w, int h, uint16_t color);
        void setRotation(int r);
        void invertDisplay(bool i);
        void displayOn();
        void displayOff();

        uint16_t colorAt(int x, int y);

        void initializeDevice(void);

       

        void windowData(uint16_t d);
        void windowData(const uint16_t *d, int num);
        void openWindow(int, int, int, int);

        void enableBacklight();
        void disableBacklight();
        void setBacklight(int b);

};


   


#endif


