#include <ESPVGAX.h>
#include <fonts/arial12.h>

ESPVGAX vga;
File root;
String txt=" Welcome\n />", linia="", his="", fname="";
int lines=2, lines_his;
bool editor=0, wykonaj=0, odbior=0;

void upsc()
{
       vga.setFont((uint8_t*)fnt_arial12_data, FNT_ARIAL12_SYMBOLS_COUNT, 
     FNT_ARIAL12_HEIGHT, FNT_ARIAL12_GLYPH_WIDTH);
     ESPVGAX::PrintInfo end;
     end=vga.print_P(txt.c_str(), 3, 3, true);
 }

int keyboard()
{
  //while (!Serial.available()){}
   int x = Serial.read();
   char znak = getKeyChar(x);
  if(x==0x66)//backspace
  {
    if(linia.length()>0)
    {
txt.remove(txt.length()-1);
linia.remove(linia.length()-1);
vga.clear();
     upsc();
    }
     return -1;
  }
  else if(x==0x76) //Esc
  {
    editor=0;
    vga.clear();
   txt=his+"\n />";
   lines=lines_his;
   linia="";
   his="";
   upsc();
   return -1;
  }
  else if(x==5)
  {
/*F1  5
F2  6
F3  4
F4  12
F5  3
F6  11
F7  13
F8  10
F9  1
F10 9
F11 120
F12 7*/
    vga.clear();
   his=txt;
   lines_his=lines;
   if(editor==0)
   txt=" Press Esc to exit                    ========= HELP =========\n\n Commands:\n ECHO <VALUE>\n HI - replies HELLO\n PING - replies PONG\n EDITOR - opens text editor\n LS - lists files\n RM - removes files\n CLS - clear console\n LOGOUT - logs you out\n\n Key shortcuts:\n Esc - exit program or clear console\n F1 - opens this help";
   else
   txt=" Press Esc to exit                 ========= EDITOR HELP =========\n\n Key shortcuts:\n Esc - exit program\n F1 - opens this help\n F10 - save file";
   upsc();
   for(;;)
   {
    int t = Serial.read(); 
    if(t==0x76)
    break;
    vga.delay(10);
   }
    vga.clear();
   txt=his;
   lines=lines_his;
   his="";
   upsc();
   return -1;
  
  }
  else if(x==9 && editor==1)//F10
  {
    Serial.write(3);//saving file name
    Serial.print(fname);
    Serial.print('\0');
    Serial.print(linia);
    Serial.print('\0');

   vga.clear();
   txt=his+"\n />";
   lines=lines_his;
   his="";
   editor=0;
   linia="";
   upsc();
   return -1;
  }
  else
  {return x;}
}

void login()
{
  String login_var;
  linia="";
  vga.clear();
  txt=" Login: ";
  upsc();
  for(;;)
  {
    int key = Serial.read();
    //Serial.print(key);
    if(key!=-1)
    {
      char znak=getKeyChar(key);
     if(znak=='\n')
     {
      login_var=linia;
      break;
     }
     else if(key==0x66)//backspace
  {
    if(linia.length()>0)
    {
txt.remove(txt.length()-1);
linia.remove(linia.length()-1);
vga.clear();
     upsc();
    }
     
  }
     else
     {
      txt=txt+znak;
     linia=linia+znak;
     }
    upsc();
    }
    vga.delay(10);  
  }

  linia="";
  txt=txt+"\n PASSWORD: ";
  vga.clear();
  upsc();
  for(;;)
  {
    int key = Serial.read();
    //Serial.print(key);
    if(key!=-1)
    {
      char znak=getKeyChar(key);
     if(znak=='\n' && linia=="12345" && login_var=="KRIS")
     {
      break;
     }
     else if(znak=='\n')
     {
      login();
     }
     else if(key==0x66)//backspace
  {
    if(linia.length()>0)
    {
txt.remove(txt.length()-1);
linia.remove(linia.length()-1);
vga.clear();
     upsc();
    }
     
  }
     else
     {
      txt=txt+'*';
     linia=linia+znak;
     }
    upsc();
    }
    vga.delay(10);  
  }
  vga.clear();
  txt=" Welcome "+login_var+"\n />";
  upsc();
}

void exec(String cmd)
{
  lines++;
  String odp;
  if(cmd=="PING")
  {odp="PONG";txt=txt+"\n "+odp+"\n />";}
  else if(cmd=="LS")//LS
  {
    Serial.write(1);
    //vga.delay(100);
    String dane="";
    /*for(;;){
     if(Serial.available() > 0) {
dane = Serial.readStringUntil('\0');
break;
}}*/
dane = Serial.readStringUntil('\0');
txt=txt+"\n "+dane+" />";upsc();
  }
  else if(cmd.startsWith("CAT"))
  {
    String plik="";
    if(cmd.length()>4)for(int i = 4; i < cmd.length(); i++) plik = plik + cmd[i];
    Serial.write(2);//CAT
    Serial.print(plik);
    String dane="";
    odbior=1;
    for(;;){if(Serial.available() > 0) {dane = Serial.readStringUntil('\0');break;}}
txt=txt+"\n "+dane+"\n />"; upsc();
  }
  else if(cmd.startsWith("RM"))
  {
    String plik="";
    if(cmd.length()>3)for(int i = 3; i < cmd.length(); i++) plik = plik + cmd[i];
    Serial.write(4);//REMOVE
    Serial.print(plik);
    
txt=txt+"\n />"; upsc();
  }
  else if(cmd=="HI")
  {odp="HELLO";txt=txt+"\n "+odp+"\n />";}
  else if(cmd.startsWith("EDITOR"))
  {
   if(cmd.length()<=7)
   {
   vga.clear();
   editor=1;
   his=txt;
   lines_his=lines;
   txt=" text editor v0.1                                     New Buffer\n\n";
   }
   else
   {
    linia="";
     for(int i = 7; i < cmd.length(); i++) linia = linia + cmd[i];
     Serial.write(2);//CAT
    fname=linia; linia="";
    Serial.print(fname);
    for(;;){if(Serial.available() > 0) {linia = Serial.readStringUntil('\0');break;}}
    vga.clear();
   editor=1;
   his=txt;
   lines_his=lines; 
   txt=" text editor v0.1                                     "+fname+"\n\n"+linia;
   }
   }
   else if(cmd.startsWith("ECHO"))
   {
    odp="";
    if(cmd.length()>5)for(int i = 5; i < cmd.length(); i++) odp = odp + cmd[i];
    txt=txt+"\n "+odp+"\n />";
   }
   else if(cmd=="CLS")
   {
    editor=0;
    vga.clear();
   txt=his+" />";
   lines=lines_his;
   linia="";
   his="";
   upsc();
    }
    else if(cmd=="LOGOUT")
    {
    txt="";
    linia="";
    login();  
    }
   else
   {txt=txt+"\n "+odp+"\n />";}
}

void loop() {
  while(1)
  {
    int key = keyboard();
    //Serial.print(key);
    if(key!=-1)
    {
      char znak=getKeyChar(key);
     if(znak=='\n')
     {
      lines++;
      if(editor==0)
      {exec(linia); if(editor==0)linia="";}
      else
      {txt=txt+znak;linia=linia+znak;}
     }
     else
     {
      txt=txt+znak;
     linia=linia+znak;
     }
     if(lines>=37)
     {
        lines=0;
        txt=" />";
        vga.clear();
     }
    upsc();
    }
  vga.delay(5);
  }
}
void setup() {
  vga.begin();
  Serial.begin(115200);
upsc();
login();
}


char getKeyChar(int keyCode) {
  switch(keyCode) {
    case 0x1C: return 'A';
    case 0x32: return 'B';
    case 0x21: return 'C';
    case 0x23: return 'D';
    case 0x24: return 'E';
    case 0x2B: return 'F';
    case 0x34: return 'G';
    case 0x33: return 'H';
    case 0x43: return 'I';
    case 0x3B: return 'J';
    case 0x42: return 'K';
    case 0x4B: return 'L';
    case 0x3A: return 'M';
    case 0x31: return 'N';
    case 0x44: return 'O';
    case 0x4D: return 'P';
    case 0x15: return 'Q';
    case 0x2D: return 'R';
    case 0x1B: return 'S';
    case 0x2C: return 'T';
    case 0x3C: return 'U';
    case 0x2A: return 'V';
    case 0x1D: return 'W';
    case 0x22: return 'X';
    case 0x35: return 'Y';
    case 0x1A: return 'Z';
    case 0x45: return '0';
    case 0x16: return '1';
    case 0x1E: return '2';
    case 0x26: return '3';
    case 0x25: return '4';
    case 0x2E: return '5';
    case 0x36: return '6';
    case 0x3D: return '7';
    case 0x3E: return '8';
    case 0x46: return '9';
    case 0x5A: return '\n';
    case 0x49: return '.';
    case 0x4A: return '/';
    case 0x29: return ' ';
    case 0x52: return '\'';
    default: return '■';
  }

  return '\0';
}