#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h> // library required for IIC communication
#include "FastLED_timers.h"
#include "myGfx.h"
#include "waves.h"
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // initialization for the used OLED display

// the arrays below are generated from the image2cpp tool, scroll down for the actual code
enum waveTypes{SIN8,QUAD8,CUBIC8};

// counter for the currently displayed frame of the animation

void setup(void) {
  u8g2.begin(); // start the u8g2 library
  Serial.begin(115200);

      u8g2.clearBuffer();					// clear the internal memory
crircleAni();
  u8g2.sendBuffer();	
}

void loop(void) {

//waveAni();

	
}
void crircleAni(){
// center 64/110 r70
int16_t radius = 70;
int16_t centerX = 64;
int16_t  centerY = 110;
for (int theta = 0; theta <256; theta++){
int32_t xpos = centerX - (radius *(sin8(theta)-127) /127);
int32_t ypos = centerY - (radius *(cos8(theta)-127) /127);
  int32_t x0 = xcenter + (r_max * cos16(i) / 32767 ) ;
  int32_t y0 = ycenter + (r_max * sin16(i)  / 32767 ) ;
u8g2.drawPixel(xpos,  ypos  );
//  u8g2.drawCircle( xpos,  ypos,  radius  );
}
}

DEGTO16(deg);
  uint16_t DEGTO16(int32_t theta) { return (wrap(theta,0,360) * 182);}
  
const uint8_t aniSpeed[11] ={14,14,14,13,12,11,10,8,5,5,4};

void waveAni(){
 static int xOff = u8g2.getDisplayWidth();// /2-32;
 static uint8_t xStep = 1;
 static int8_t stepDir = 1;
 if(xStep < 11 && xOff >= -127){
  EVERY_N_MILLIS(25){
    
    xOff-=aniSpeed[xStep];
    u8g2.clearBuffer();					// clear the internal memory
    u8g2.drawHLine(0, 16 ,  128) ;
    drawWave(2,24, xOff);
    u8g2.sendBuffer();					// transfer internal memory to the display
    
    if(xStep > 0){xStep+= stepDir;}
    if(xStep == 0 && xOff <= -65){delay(3000); xOff = u8g2.getDisplayWidth();stepDir = 1; xStep=1;}//Serial.println(aniSpeed[xStep]);delay(50); }
    }
 }
 else if(xStep == 11){ Serial.println(xOff); delay(3000);stepDir=-1;xStep=10;}
}

int yCenter =40;
int yOff =1;
int yUp =yCenter+yOff;
int yDown = yCenter-yOff;
//const 
void drawWave(int xCompress, int yCompress,int xOff){
  static int disp_w =u8g2.getDisplayWidth();
  int lenWave = disp_w / xCompress;
  //static int xOff = 0; // from: -lenWave to disp_w + lenWave
  //
  //EVERY_N_MILLIS(100){xOffQuad++;}
  //EVERY_N_MILLIS(12){xOffCubic++;}
  if(xOff > 0 ){
    u8g2.drawHLine(0, yCenter -yOff ,  xOff) ;
    u8g2.drawHLine(0, yCenter +yOff ,  xOff) ;
    }
  if(xOff+lenWave < disp_w){ 
    u8g2.drawHLine( xOff+lenWave,  yCenter -yOff ,  disp_w-(xOff+lenWave)); 
    u8g2.drawHLine( xOff+lenWave,  yCenter +yOff ,  disp_w-(xOff+lenWave)); 
    }
  static int yLast = yCenter; // avoid gaps in y direction 
  for(int x = 0; x < 64; x++){
    if(x+xOff >= -1 && x+xOff < disp_w+1){
      
      int xPosQuad = wrap(x*xCompress,0,127);// wrap(xOffQuad + i,0, 127);
      int yPosQuad =getWaveY(QUAD8,xPosQuad)/yCompress;
      
      int y = yPosQuad;
      

      if(abs(y-yLast) > 1 && x != 0 && x!= 63){
        fill_y_gaps(x+xOff, yCenter+y+yOff, yCenter+yLast+yOff);
        fill_y_gaps(x+xOff,yCenter-y-yOff,yCenter - yLast -yOff);
        }
     // if(yLast > y && (yLast-y) > 1 || y > yLast && (y-yLast) > 1){fill_y_gaps(x+xOff,y,yLast);}
      u8g2.drawPixel(x+xOff ,yCenter-y-yOff) ;
      u8g2.drawPixel(x+xOff ,yCenter-y+yOff);
     // Serial.print(x);Serial.print('\t');Serial.print(y);Serial.print('\t');Serial.println(yLast);delay(50);
      yLast = y;
    }
  }
}
void fill_y_gaps( int16_t x, int16_t y, int16_t yLast){
  int16_t start, stop;
  if(yLast < y){start=yLast; stop=y;}
  else{start=y; stop=yLast;}
  for(int y1 = start+1; y1 < stop; y1++){ u8g2.drawPixel(x,y1); }
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
oled1:GND
oled1:VCC
oled1:SCL
oled1:SDA