// ========================================
void ViewQuad(int i, int j, byte mycolor) // отрисовка 1-го квадрата
{ if (j < 3) return;

  int wy = SmeY + (j - 3) * razmer - j;
  int wx = SmeX + i * razmer - i;
  if (mycolor != 0)
  {
    myGLCD.setColor(0, 0, 0);
    //tft.drawRect(wx,wy,razmer, razmer, BLACK);
    myGLCD.drawRect(wx, wy, wx + razmer - 2, wy + razmer - 2);
    // delay(500);
    myGLCD.setColor(MasCol[mycolor]);
    // tft.fillRect(wx+1, wy+1, razmer-2 , razmer-2, MasCol[mycolor]);
    // myGLCD.fillRect(wx+1, wy+1, wx+1+razmer-4 ,wy+1+razmer-4);
    myGLCD.fillRect(wx + 1, wy + 1, wx + 1 + razmer - 4 , wy + 1 + razmer - 4);
    // delay(500);

    /*   myGLCD.setColor(0, 0, 0);
      myGLCD.drawRect(dx,dy+razmer*i-i,dx+razmer,dy+razmer*i-i+razmer);
      myGLCD.setColor(MasCol[fignext[i]]);
      //tft.fillRect(dx+1,dy+razmer*i-i+1, razmer-2, razmer-2,MasCol[fignext[i]]);
      myGLCD.fillRect(dx+1,dy+razmer*i-i+1,dx+1+razmer-2,dy+razmer*i-i+1+razmer-2);
    */

  } else
  { //myGLCD.setColor(255, 255, 255);
    myGLCD.setColor(98, 65, 32);

    myGLCD.fillRect(wx + 1, wy - 1, wx + 1 + razmer - 3, wy - 2 + razmer);
    //tft.fillRect(wx+1, wy-1, razmer-2 , razmer, WHITE);
  }
}
//==================================================
void ViewStacan()
{ char myStr2[3];


  //myGLCD.setColor(255, 0, 0);
  // myGLCD.setFont(BigFont);
  myGLCD.setFont(Ubuntubold);
  if (OldScore != Score || FlNew)
  { myGLCD.setColor(BLACK);
    //tft.fillRect(LL,113*3,30,8,);
    //  myGLCD.fillRect(29,279,29+45, 269+49);
    // tft.setCursor(LL, 113*2);
    //myGLCD.print("SCORE",LL,100*3);
    sprintf(myStr2, "%03d", Score );
    //myGLCD.setColor(255, 0, 0);
    myGLCD.setColor (VGA_RED);
    myGLCD.setBackColor(BLACK);
    myGLCD.print(myStr2, 30, 290);
    //tft.print(myStr2);
    OldScore = Score;
  }

  if (OldRecord != Record || FlNew)
  { // tft.setCursor(LL, 148*2);
    sprintf(myStr2, "%03d", Record );
    myGLCD.setColor (BLACK);
    myGLCD.setBackColor(BLACK);
    // myGLCD.fillRect(29,379,29+45, 379+49);
    //tft.fillRect(LL,148*2,30,8,WHITE);
    myGLCD.setColor(255, 0, 0);
    myGLCD.print(myStr2, 30, 390);
    //tft.print(myStr2);
    OldRecord = Record;
  }
  if (OldLevel != Level || FlNew) {
    myGLCD.setBackColor(BLACK);
    myGLCD.setColor (BLACK);
    myGLCD.fillRect(48, 180, 70, 210);
    //tft.fillRect(107*2,73*2,30,20,WHITE);
    // tft.setCursor(107*2, 73*2);
    myGLCD.setFont(Ubuntubold);
    myGLCD.setColor(255, 0, 0);
    myGLCD.printNumI(Level, 50, 183);
    // tft.print(Level);
    OldLevel = Level;
  }
  FlNew = false;

  for (int j = 3; j < MaxY; j++)
    for (int i = 0; i < MaxX; i++)
      if (MasSt[i][j] != MasOld[i][j]) ViewQuad(i, j, MasSt[i][j]);

  myGLCD.setColor(0, 0, 0);
  //    myGLCD.drawLine(razmer*i+SmeX-i,SmeY, razmer*i+SmeX-i, SmeY+(MaxY-3)*razmer-MaxY);//V
  // tft.drawFastHLine(3,156*2,razmer*MaxX-MaxX,BLACK);
  myGLCD.drawLine(SmeX, SmeY + (MaxY - 3)*razmer - MaxY, razmer * MaxX + SmeX - (MaxX / 2), SmeY + (MaxY - 3)*razmer - MaxY); //H
  //   myGLCD.drawLine(3, 156*3, 3, 156*3+razmer*MaxX+5-MaxX);//H

  for (int j = 3; j < MaxY; j++)
    for (int i = 0; i < MaxX; i++)
      MasOld[i][j] = MasSt[i][j];

}
//==================================================
void ClearMas(int MasStx[MaxX][MaxY])
{
  for (int j = 0; j < MaxY; j++)
    for (int i = 0; i < MaxX; i++)
      (MasStx[i][j] = 0);
}
//==================================================
void Sosed(int i, int j, int dx, int dy, byte mode)
{ int nx = i + dx;
  int ny = j + dy;
  if (nx >= 0 && ny >= 0 && nx < MaxX && ny < MaxY && MasSt[nx][ny] == MasSt[i][j])
  { if (mode == 1) MasTmp[i][j]++; else if (mode == 2 && (MasTmp[nx][ny] > 1 || MasTmp[i][j] > 2 ))
    { MasTmp[nx][ny] = 3;
      MasTmp[i][j] = 3;
    } else if (mode == 3 && MasTmp[nx][ny] == 3) if (MasTmp[i][j] != 3) {
        MasTmp[i][j] = 3;
        fl = true;
      }
  }
}
//==================================================
void Sos(int i, int j, byte mode)
{ for (byte k = 0; k < 4; k++)
    Sosed(i, j, mmm[k][0], mmm[k][1], mode);
}
//==================================================
bool FindFull() // ищем одноцветные цепочки
{ int i, j, k; bool res;
  res = false;

  for (int k = 2; k < 8; k++) // по каждому цвету
  { ClearMas(MasTmp);
    for (j = 3; j < MaxY; j++)
      for (i = 0; i < MaxX; i++)
        if (MasSt[i][j] == k) Sos(i, j, 1);

    for (j = 3; j < MaxY; j++)
      for (i = 0; i < MaxX; i++)
        if (MasTmp[i][j] > 1) Sos(i, j, 2);
    do
    { fl = false;
      for (j = 3; j < MaxY; j++)
        for (i = 0; i < MaxX; i++)
          if (MasTmp[i][j] > 0) Sos(i, j, 3);
    } while (fl);

    for (j = 3; j < MaxY; j++)
      for (i = 0; i < MaxX; i++)
        if (MasTmp[i][j] == 3) {
          MasSt[i][j] = 1;
          TScore++;
        }
  }
  //if (TScore>999)TScore=100;
  if (TScore > 0)
  { ViewStacan();
    FlZ = true;
    mydelay(500);
  }

  for (j = 0; j < MaxY; j++)
    for (i = 0; i < MaxX; i++)
    { while (MasSt[i][MaxY - 1 - j] == 1)
      { for (k = 0; k < MaxY - 2 - j; k++) MasSt[i][MaxY - 1 - k - j] = MasSt[i][MaxY - 2 - k - j];
        res = true;
      }
    }
  return (res);
}
//==================================================
void GetNext()
{ int dx = 50; int dy = 27;
  x = 3; y = 0;
  for (int i = 0; i < 3; i++)
  { //fig[i]=fignext[i];
    if (!Demo) MasSt[x][i] = fignext[i];
    fignext[i] = random(NumCol) + 2;
    // tft.drawRect(dx,dy+razmer*i-i,razmer, razmer, BLACK);
    // myGLCD.drawRect(x1,y1,x2,y2);
    myGLCD.setColor(0, 0, 0); //цвет места под Next
    myGLCD.drawRect(dx, dy + razmer * i - i, dx + razmer, dy + razmer * i - i + razmer);
    myGLCD.setColor(MasCol[fignext[i]]);
    //tft.fillRect(dx+1,dy+razmer*i-i+1, razmer-2, razmer-2,MasCol[fignext[i]]);
    myGLCD.fillRect(dx + 1, dy + razmer * i - i + 1, dx + 1 + razmer - 2, dy + razmer * i - i + 1 + razmer - 2);
  }
  if (!Demo) {
    Counter++;
    if (Counter == NextLevel) {
      Counter = 0;
      Level++;
      if (Level > MaxLevel) Level = MaxLevel;
    }
    tempspeed = MasSpeed[Level - 1] * 2;
  }
}
//==================================================
void MyScore()
{
  TScore = 0;
  while (FindFull())
  { if (TScore > 7) Score = Score + TScore + (TScore - 8) * 2;
    else Score = Score + TScore;
    // if (!Demo) analogWrite(pin_Speaker,5); // издаем звук
    if ((Demo) && (Score > 500)) break;

    ViewStacan();
    // analogWrite(pin_Speaker,0);
    FlZ = true;
    mydelay(1000);
  }
  FlZ = false;
}
//==================================================
void ProcDemo()// демо режим
{ int st = 0;
  Score = 0;
  GetNext();
  for (int j = 3; j < MaxY; j++)
    for (int i = 0; i < MaxX; i++)
      MasSt[i][j] = random(6) + 2;
  ViewStacan();
  mydelay(1000);
  if (!Demo) return;



  while (1)//задержка массива на 5 сек в демо режиме
  { but();
    if (myTouch.dataAvailable())
    {
      myTouch.read();
      xt = myTouch.getX();
      yt = myTouch.getY();
      valBtnT = 1;
    }
    st++;
    if (valBtnL || valBtnR || valBtnT || valBtnD)
    { valBtnPause = 0;
      break;
    }
    if (st > 100)
    { st = 0;
      break;
    }
    delay(50);

  }
  //  delay(5000);
  MyScore();
  if (Record < Score) Record = Score;
}
//**********************  ТЕЛО ИГРЫ  ************************************************************
void mydelay(int md)
{
  unsigned long starttime = millis();
  while (millis() - starttime < md)
  {
    but();
    //***********  T  O  U  C  H  ********************
    if (myTouch.dataAvailable())
    {
      myTouch.read();
      xt = myTouch.getX();
      yt = myTouch.getY();
      Serial.print("xt=");
      Serial.println(xt);
      Serial.print("yt=");
      Serial.println(yt);
      if ((xt >= 470) && (xt <= 550)) // Upper row
      {
        if ((yt >= 20) && (yt <= 60)) // Button: 1
        {
          valBtnPause = 1;
          myGLCD.setColor(WHITE);
          myGLCD.drawLine(480, 29, 480 + 60, 29);
          myGLCD.drawLine(480, 30, 480 + 60, 30);
          //myGLCD.drawLine(480, 45,480+60, 45);
        }
        if ((yt >= 240) && (yt <= 270)) // Button: 1
        {
          valBtnL = 1; //LEFT
          myGLCD.setColor(WHITE);
          myGLCD.drawLine(484, 257, 484 + 60, 257);
          myGLCD.drawLine(484, 258, 484 + 60, 258);
        }
      }
      if ((xt >= 560) && (xt <= 640)) // Upper row
      {
        if ((yt >= 110) && (yt <= 140)) // Button: 1
        {
          valBtnT = 1; //UP
          myGLCD.setColor(WHITE);
          myGLCD.drawLine(572, 130, 572 + 60, 130);
          myGLCD.drawLine(572, 131, 572 + 60, 131);
        }
        if ((yt >= 400) && (yt <= 460)) // Button: 1
        {
          valBtnD = 1; //DOWN
          myGLCD.setColor(WHITE);
          myGLCD.drawLine(572, 426, 572 + 60, 426);
          myGLCD.drawLine(572, 425, 572 + 60, 425);
        }
      }
      if ((xt >= 680) && (xt <= 760)) // Upper row
      {
        if ((yt >= 240) && (yt <= 270)) // Button: 1
        {
          valBtnR = 1; //RIGHT
          myGLCD.setColor(WHITE);
          myGLCD.drawLine(693, 257, 693 + 60, 257);
          myGLCD.drawLine(693, 258, 693 + 60, 258);
        }

      }
      if ((xt >= 730) && (xt <= 760)) // Upper row
      {
        if ((yt >= 30) && (yt <= 70)) // Button: 1
        {
          exit_menu = 1; //ВЫХОД
        }

      }
    }
    delay(100);
    //*************************************************************************************

    if (exit_menu == 1)
    { exit_menu = 0;
      loop();
    }
    if (valBtnPause == 1)
    { valBtnPause = 0;
      myGLCD.setColor(RED);
      // myGLCD.setBackColor (98,65,32);

      myGLCD.setBackColor(VGA_TRANSPARENT);
      // myGLCD.setColor(98,65,32);
      myGLCD.print("P A U S E", (MaxX * razmer / 2) + SmeX - 110, 158);

      delay(500);
      while (1)
      { //delay(500);
        but();
        if (myTouch.dataAvailable())
        {
          myTouch.read();
          xt = myTouch.getX();
          yt = myTouch.getY();
          valBtnT = 1;
        }
        if (valBtnL || valBtnR || valBtnT || valBtnD)
        { valBtnPause = 0;
          myGLCD.setColor(98, 65, 32);
          // myGLCD.print("         ",(MaxX*razmer/2)+SmeX-110,158);
          myGLCD.print("P A U S E", (MaxX * razmer / 2) + SmeX - 110, 158);
          myGLCD.setColor(BLACK);
          myGLCD.drawLine(480, 29, 480 + 60, 29);
          myGLCD.drawLine(480, 30, 480 + 60, 30);
          delay(1000);
          break;
        }
      }
    }


    VAL = 0;

    if (valBtnR == 1) // обрабатываем повороты энкодера
    { VAL = 1;
      valBtnR = 0;
    } else if (valBtnL == 1)
    { VAL = -1;
      valBtnL = 0;
    }
    if (valBtnD == 1 && !FlZ) tempspeed = 50; // падение
    if (valBtnD == 1)
    { VAL = 0;
      valBtnD = 0;
      delay(500);
    }

    // **КНОПКИ  ЦВЕТ*****************************
    myGLCD.setColor(BLACK);
    myGLCD.drawLine(484, 257, 484 + 60, 257);
    myGLCD.drawLine(484, 258, 484 + 60, 258);
    myGLCD.drawLine(693, 257, 693 + 60, 257);
    myGLCD.drawLine(693, 258, 693 + 60, 258);
    myGLCD.drawLine(572, 130, 572 + 60, 130);
    myGLCD.drawLine(572, 131, 572 + 60, 131);
    myGLCD.drawLine(572, 426, 572 + 60, 426);
    myGLCD.drawLine(572, 425, 572 + 60, 425);
    //***************************************************

    if ((VAL != 0 || Mp != 0) && Demo) {
      Demo = false;
      NewGame();
    }
    if (VAL != 0 && figmove(VAL, 0) && !FlZ)
    { for (int i = 0; i < 3; i++)
      { MasSt[x + VAL][y + i] = MasSt[x][y + i];
        MasSt[x][y + i] = 0;
      }
      ViewStacan();
      if (MasSt[x][y + 3] == 0)
        // tft.drawFastHLine(SmeX+x*razmer-x+1,SmeY+y*razmer-y-3,razmer-2,WHITE);
        //  myGLCD.setColor(255, 255, 255);
        myGLCD.setColor(98, 65, 32);
      myGLCD.drawLine(SmeX + x * razmer - x + 1, SmeY + y * razmer - y - 3, SmeX + x * razmer - x + 1 + razmer - 2, SmeY + y * razmer - y - 3); //H
      x = x + VAL;
    }
    if (valBtnT == 1 && !FlZ) // перемена цветов фигуры
    { int aa = MasSt[x][y];
      MasSt[x][y] = MasSt[x][y + 2];
      MasSt[x][y + 2] = MasSt[x][y + 1];
      MasSt[x][y + 1] = aa;
      valBtnT = 0;
      ViewStacan();
    }


  }
}
//================================================
void NewGame()
{
  for (int i = 0; i < MaxX + 1; i++)
  { myGLCD.setColor(0, 0, 0);
    //    tft.drawFastVLine(3+razmer*i-i,2,155,BLACK); // направляющие _______
    myGLCD.drawLine(razmer * i + SmeX - i, SmeY, razmer * i + SmeX - i, SmeY + (MaxY - 3)*razmer - MaxY); //V
    for (int j = 3; j < MaxY; j++) // заполним буфер сравнения значением, которого нет
      for (int i = 0; i < MaxX; i++)
        MasOld[i][j] = 255;

    Score = 0;
    FlNew = true;
    OldScore = Score;
    ClearMas(MasSt);
    Arbeiten = true;
    GetNext();

    Counter = 0;
    Level = 1;
    tempspeed = MasSpeed[0] * 2;
    Record = myrecord;
    ViewStacan();

  }
}
//================================================
void gameover()
{
  Arbeiten = false;


  // tft.drawRect(7,40,81,50, BLACK);
  //myGLCD.setColor(WHITE);
  myGLCD.setColor(98, 65, 32);
  myGLCD.fillRect((MaxX * razmer / 2) + SmeX - (2 * razmer), 62 * 2, (MaxX * razmer / 2) + SmeX + (2 * razmer) - 8, 130 * 2);
  myGLCD.setColor(BLACK);
  myGLCD.drawRect((MaxX * razmer / 2) + SmeX - (2 * razmer), 62 * 2, (MaxX * razmer / 2) + SmeX + (2 * razmer) - 8, 130 * 2);

  //tft.fillRect(8,41,79,48);
  // tft.setCursor(25, 47);
  myGLCD.setColor(RED);
  // myGLCD.setBackColor(WHITE);
  myGLCD.setColor(98, 65, 32);
  // tft.setTextSize(2);
  // tft.setTextColor(RED);
  myGLCD.print("GAME", (MaxX * razmer / 2) + SmeX - 40, 80 * 2);
  //tft.print("GAME");
  // tft.setCursor(25, 67);
  // tft.print("OVER");
  myGLCD.print("OVER", (MaxX * razmer / 2) + SmeX - 40, 100 * 2);
  if (Score > myrecord) myrecord = Score;
  for (int i = 0; i < 20; i++) {
    if (i & 1)
    { myGLCD.setColor(WHITE);
      // myGLCD.setColor(98,65,32);
      myGLCD.fillRect((MaxX * razmer / 2) + SmeX - (2 * razmer), 62 * 2, (MaxX * razmer / 2) + SmeX + (2 * razmer) - 8, 130 * 2);
      myGLCD.setColor(BLACK);
      myGLCD.drawRect((MaxX * razmer / 2) + SmeX - (2 * razmer), 62 * 2, (MaxX * razmer / 2) + SmeX + (2 * razmer) - 8, 130 * 2);
      myGLCD.setColor(RED);
      myGLCD.setBackColor(WHITE);
      //myGLCD.setColor(98,65,32);
      myGLCD.print("GAME", (MaxX * razmer / 2) + SmeX - 50, 80 * 2);
      myGLCD.print("OVER", (MaxX * razmer / 2) + SmeX - 50, 100 * 2);
      delay(100);
    }
    else
    {
      myGLCD.setColor(RED);
      myGLCD.fillRect((MaxX * razmer / 2) + SmeX - (2 * razmer), 62 * 2, (MaxX * razmer / 2) + SmeX + (2 * razmer) - 8, 130 * 2);
      myGLCD.setColor(BLACK);
      myGLCD.drawRect((MaxX * razmer / 2) + SmeX - (2 * razmer), 62 * 2, (MaxX * razmer / 2) + SmeX + (2 * razmer) - 8, 130 * 2);

      myGLCD.setColor(WHITE);
      //myGLCD.setColor(98,65,32);
      myGLCD.setBackColor(RED);
      myGLCD.print("GAME", (MaxX * razmer / 2) + SmeX - 50, 80 * 2);
      myGLCD.print("OVER", (MaxX * razmer / 2) + SmeX - 50, 100 * 2);
      delay(100);
    }
  }
  gmov = true;
  columns();
}
//**********************************************************
void columns()
{ myFiles.load(0, 0, 800, 480, "play/17.raw" , 32, 0);
  for (int j = 0; j < MaxY; j++)
  { for (int i = 0; i < MaxX; i++)
    { (MasSt[i][j] = 0);
      (MasTmp[i][j] = 0);
      (MasOld[i][j] = 0);
    }
  }


  fl = 0;
  Demo = true;
  myfl = false;
  Arbeiten = false;
  FlNew = 0;
  FlZ = false;
  VAL = 0;
  Mp = 0;
  x = 0;
  y = 0;
  tempspeed = 0;
  Counter = 0;
  Score = 0;
  TScore = 0;
  Record = 0;

  uint32_t tim = millis();
  myGLCD.setFont(BigFont);

  if ( gmov == false) //если заходим из гланого меню gmov=false
  {
    myGLCD.setColor (VGA_WHITE);
    //  myGLCD.setColor(98,65,32);
    myGLCD.setBackColor(VGA_TRANSPARENT);
    myGLCD.print("TAP TO CONTINUE", CENTER, 450);

    int st = 0;
    while (st < 100) {
      delay(100);
      but();
      st++;
      if (st > 98)exit_menu = 1;
      if (valBtnL || valBtnR || valBtnT || valBtnD)
      { valBtnPause = 0;
        exit_menu = 0;
        break;
      }
      if (myTouch.dataAvailable())
      { exit_menu = 0;
        break;
      }
    }

    if (exit_menu == 1)
    { exit_menu = 0;
      loop();
    }
  }
  else
  { gmov = false ;
    delay(3000);
  }
  //********************************************************************************************************
  // myGLCD.fillScr(98,65,32);
  myFiles.load(0, 0, 800, 480, "play/16.raw" , 32, 0);
  //myGLCD.setCursor(LL, 61*2);
  // myGLCD.setTextColor(BLACK);
  // myGLCD.setBackColor(210, 210, 200);
  //  myGLCD.setBackColor(98,65,32);
  myGLCD.setBackColor(VGA_TRANSPARENT);
  myGLCD.setColor(250, 250, 250);
  myGLCD.print("LEVEL", 25, 155);
  // myGLCD.print("LEVEL");
  // myGLCD.setCursor(LL, SmeY);
  // myGLCD.print("NEXT");
  // myGLCD.print("NEXT",razmer*MaxX+SmeX+razmer-10,SmeY);
  myGLCD.print("SCORE", 25, 260);
  // myGLCD.setCursor(LL,100*2);

  myGLCD.print("TOP", 40, 360);

  FlNew = true;

  ViewStacan();
  GetNext();


  while (1) {
    but();

    if (Demo)
    { ProcDemo();
    }
    else
    { if (Arbeiten)
      { mydelay(tempspeed);
        figmove(0, 1);
      } else {
        if (myTouch.dataAvailable())  {
          valBtnL = 1;
        }
        if (valBtnL || valBtnR || valBtnT || valBtnD)
        { NewGame();
          Mp = 1;
        }

      }
    }
  }

}
//================================================
