// ST7789 library example
// (c) 2019 Pawel A. Hernik

// requires RRE Font library:
// https://github.com/cbm80amiga/RREFont

/*
 ST7789 240x240 IPS (without CS pin) connections (only 6 wires required):

 #01 GND -> GND
 #02 VCC -> VCC (3.3V only!)
 #03 SCL -> D13/SCK
 #04 SDA -> D11/MOSI
 #05 RES -> D8 or any digital
 #06 DC  -> D7 or any digital
 #07 BLK -> NC
*/

#define TFT_DC    7
#define TFT_RST   8 
#define SCR_WD   240
#define SCR_HT   320   // 320 - to access to full 240x320 frame buffer
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Arduino_ST7789_Fast.h>
Arduino_ST7789 lcd = Arduino_ST7789(TFT_DC, TFT_RST);

#include "RREFont.h"
#include "rre_times_98v.h"
#include "rre_tahoma_65v.h"

RRE_Font *rFont = &rre_Times98v;
//RRE_Font *rFont = &rre_tahoma_65v;

uint16_t bg = 0x0000, fg = 0xffff;
int maxy = 320; // internal ST7789 fb is 240x320
int screenWd = 240, screenHt = 240;
int spacing = 1;
int sx = 1, sy = 1;
int scrollStep = 2;
int scrollDelay = 10;
int cnt = 0;
int ycnt = 0, yscr = 0;
int offsY = 30;
unsigned long ms;


int scrollCharRRE(unsigned char c)
{
  if(c<rFont->firstCh || c>rFont->lastCh) return 0;
  uint16_t recIdx = pgm_read_word(&(rFont->offs[c-rFont->firstCh]));
  uint16_t recNum = pgm_read_word(&(rFont->offs[c-rFont->firstCh+1]))-recIdx;
  int chWd = recNum>0 ? pgm_read_byte(rFont->rects + (recNum-1+recIdx)*3)+1 : 0;
  //Serial.println(String(char(c))+": "+chWd);
  spacing = (c==' ') ? rFont->wd/3 : 4;
  int idx = recIdx*3;
  for(int col = 0; col<chWd+spacing; col++) {
    ms = millis();
    yscr += scrollStep;
    if(yscr>=maxy) yscr-=maxy;
    lcd.setScroll(yscr);
    ycnt=yscr+240;
    if(ycnt>=maxy) ycnt-=maxy;
    //Serial.println(String("ycnt=")+ycnt);
    int scrHOffs = screenHt-1;
    int scrWOffs = screenWd-1;
    int lineY = scrHOffs-(screenHt-sx-ycnt);
    int wd;
    if(col>=chWd) { // draw empty column (spacing)
      wd = sy*rFont->ht;
      lcd.fillRect(scrWOffs-offsY-wd, lineY, wd, sx, bg);
      while(millis()-ms<scrollDelay);
      continue;
    }
    int hf,yf,xf = pgm_read_byte(rFont->rects+idx+0);
    int ybg = 0;
    //yf = pgm_read_byte(font_Rects+idx+1); Serial.print("yf="); Serial.println(yf);
    while(xf==col) { // draw all lines for current column
      yf = pgm_read_byte(rFont->rects+idx+1);
      hf = pgm_read_byte(rFont->rects+idx+2);
      if(yf>0) { // bg line top
        wd = (yf-ybg)*sy;
        lcd.fillRect(scrWOffs-(offsY+ybg*sy)-wd, lineY, wd, sx, bg);
      }
      ybg = yf+hf;
      wd = hf*sy;
      lcd.fillRect(scrWOffs-(offsY+yf*sy)-wd, lineY, wd, sx, fg);
      idx+=3;
      xf = pgm_read_byte(rFont->rects+idx+0);
    }
   //Serial.println("ys = "+String(ys)+"  "+String(charHt));
    
    if(ybg<rFont->ht-1) { // last bg line
      wd = (rFont->ht-ybg)*sy;
      lcd.fillRect(scrWOffs-(offsY+ybg*sy)-wd, lineY, wd, sx, bg);
    }
    while(millis()-ms<scrollDelay);
  }
}

void scrollString(char *c)
{
  while(*c) {
    uint8_t r,g,b;
    lcd.rgbWheel(cnt*32, &r, &g ,&b);
    fg = RGBto565(r,g,b);
    bg = cnt&1 ? RGBto565(40,40,40) : RGBto565(20,20,20);
    cnt++;
    scrollCharRRE(*c++);
  }
}

void setup() 
{
  Serial.begin(9600);
  lcd.init(SCR_WD, SCR_HT);
  lcd.fillScreen(BLACK);
  lcd.setScrollArea(0,0);
}

void loop()
{
  scrollStep = 1; sx = 1;  sy = 2; scrollDelay = 6; offsY = (240-rFont->ht*sy)/2;
  //scrollString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-!?.: ");
  scrollString("This is an example of super-smooth scrolling with ordinary Arduino, ST7789 240x240 IPS LCD library and large 97x98 RRE font ...    ");
}