// Class automatically generated by Dev-C++ New Class wizard

#include "menu.h" // class's header file

// class constructor
Menu::Menu(int OrX, int OrY, int Op, int JumpY, int Just,const char *Tit, Background *Fond)
{
    LogWrite ("Creando menú '%s' (%p)...", Tit, this);
    OrigX = OrX;
    OrigY = OrY;
    SaltoY = JumpY;
    Opciones = Op;
    Justify = Just;
    Titulo = new char[strlen (Tit) + 1];
    strcpy (Titulo, Tit);
    TitOp = new char*[Opciones];
    for (int n = 0; n < Opciones; n++)
        TitOp[n] = new char [256];
    Opcion = new int[Opciones];
    Enabled = new bool [Opciones];
    for (int n = 0; n < Opciones; n++)
      Enabled[n] = true;
    FramesCirc = 1;
    SprInic = false;
    Fondo = Fond;
    LogWrite ("OK.\n");
}

Menu::~Menu()
{
    LogWrite ("Borrando menú '%s' (%p)...", Titulo, this);
    delete [] Titulo;
    for (int n = 0; n < Opciones; n++)
	    delete [] TitOp[n];

    delete [] TitOp;
    delete [] Opcion;
    delete [] Enabled;
    LogWrite ("OK.\n");
}

void Menu::DActivar (int Opc, bool Accion)
{
    Enabled[Opc] = Accion;
}

int Menu::SetTituloOp (int Opc, char* Tit, int Tipo)
{
    strcpy (TitOp[Opc], Tit);
    Opcion[Opc] = Tipo;
    if (!strcmp (TitOp[Opc], Tit))
       return 1;
    return 0;
}

int Menu::Draw ()
{
    if (!Opciones) return 1;
    H->ResizeFont_af (25);
    for (int n = 0; n < Opciones; n++)
      if (Enabled[n])
          H->TextOutCentre_aa_ex (TitOp[n], OrigX, OrigY + SaltoY * n, 252, 224, 168);
         else
          H->TextOutCentre_aa_ex (TitOp[n], OrigX, OrigY + SaltoY * n, 126, 112, 84);


    return 0;
}

void Menu::Spr()
{
    if (!SprInic)
       InitSprites();
    for (int n = 0; n < NSprMenu; n++)
        SpritesMenu[n].Dibuja();
}

int Menu::DrawWSpr ()
{
    int Ret = Draw();
    Spr();
    return Ret;
}

void Menu::Effects (int Select)
{
     if (!Config->VerBlending() && !CambioOpcion)
        return;

     CambioOpcion = false; // Esta variable CambioOpcion solo sirve para que en el nivel mínimo de detalle no se dibuje el texto a no ser que cambie la opción

     if (Green + GreenSent > 250 || Green + GreenSent < 21)
        GreenSent = -GreenSent;

     Green += GreenSent;

     if (!Config->VerBlending())
        Green = 255;

     H->ResizeFont_af (25);

     int Len = H->TextLength_af (TitOp[Select]) + 10;

     if (Select)
        H->RectFill_ex (OrigX - Len / 2 , OrigY + SaltoY * Select, OrigX + Len / 2, OrigY + SaltoY * Select + 20, makecol (12,21,44));

     H->TextOutCentre_aa_ex (TitOp[Select], OrigX-1, OrigY + SaltoY * Select, 12, Green, 44);
     H->TextOutCentre_aa_ex (TitOp[Select], OrigX+1, OrigY + SaltoY * Select, 12, Green, 44);
     H->TextOutCentre_aa_ex (TitOp[Select], OrigX, OrigY - 1 + SaltoY * Select, 12, Green, 44);
     H->TextOutCentre_aa_ex (TitOp[Select], OrigX, OrigY + 1 + SaltoY * Select, 12, Green, 44);
     H->TextOutCentre_aa_ex (TitOp[Select], OrigX, OrigY + SaltoY * Select, 252, 224, 168);
}

void Menu::InitSprites ()
{
    int X[] = {178, 500, 432, 542, 400, 598};
    int Y[] = {156, 178,  96,  70, 100, 192};

    int Ox[] = {7, 5, -5, 3, 3};
    int Oy[] = {5, -8, 5, -3, -3};

    SpritesMenu[0].SetTipo (CAPMENU);
    SpritesMenu[1].SetTipo (OVNI1);
    SpritesMenu[2].SetTipo (OVNI2);
    SpritesMenu[3].SetTipo (OVNI3);
    SpritesMenu[4].SetTipo (OVNIPEQ);
    SpritesMenu[5].SetTipo (OVNIPEQ);

    for (int n = 0; n < NSprMenu; n++) {
        SpritesMenu[n].SetX (X[n]);
        SpritesMenu[n].SetY (Y[n]);
        SpritesMenu[n].SetSent (0);
        SpritesMenu[n].ClrFotog();
        SpritesMenu[n].SetEst (0);
        InicSpr[n].X = X[n];
        InicSpr[n].Y = Y[n];
        if (n) {
           Ovalo[n-1].X = Ox[n-1];
           Ovalo[n-1].Y = Oy[n-1];
           }
        }
    SprInic = true;
}

void Menu::EasterEggGandulfo ()
{
    Sprite Mariano, Gandulfo;
    bool Salir = false;
    int CiclosSalir = 0;
    Mariano.SetTipo (MARIANO);
    Mariano.SetSent (1);
    Mariano.SetKF(1);
    Mariano.SetEst (ANDANDO);
    Gandulfo.SetTipo (GANDULFO);
    Gandulfo.SetSent (0);
    Gandulfo.SetKF(8);
    Gandulfo.SetEst (0);
    Mariano.SetX (640);
    Mariano.SetY (80 - Mariano.VerLongY());
    Gandulfo.SetX (0);
    Gandulfo.SetY (80 - Gandulfo.VerLongY());

    H->CopyFondo();
    for (int n = 0; n < 80; n++) {
        H->DrawFondoBuffer(0, 0, 640, 480, 0, 0);
        H->Vela (128, 0, 0, 640, n);
        H->VuelcaBuffer();
        }
    H->CopyFondo();

    do {
        maxSkip = 6;
        curSkip = 0;

        if (tCounterMenu > 0) { // Codigo "logico"
           do {
              // CODIGO
              if (Mariano.VerX() > Gandulfo.VerLongX() - 10)
                    Mariano.IncX (-2);
               else {
                    if (Mariano.VerEst() == ANDANDO) {
                       Mariano.SetEst(DISPARANDO);
                       Mariano.ClrFotog();
                       }
                    if (Mariano.VerEst() == DISPARANDO && Mariano.VerFotog() == 4) {
                       Gandulfo.SetTipo(EXPLPOLVO);
                       Gandulfo.SetEst (0);
                       Gandulfo.ClrFotog();
                       Gandulfo.IncY(20);
                       Gandulfo.SetKF(4);
                       }

                    if (Gandulfo.VerTipo() == EXPLPOLVO && Gandulfo.FinAnim())
                       Gandulfo.SetX(640);

                    if (Mariano.VerEst() == DISPARANDO && Mariano.FinAnim()) {
                       Mariano.SetEst(PARADO);
                       Mariano.SetAnim (6);
                       Mariano.SetFotog (20);
                       Mariano.SetKF (6);
                       }
                    if (Mariano.VerEst() == PARADO && Mariano.VerAnim() == 6 && Mariano.FinAnim())
                       if (++CiclosSalir > 10)
                          Salir = true;
                    }

              if (key[KEY_ESC]) Salir = true;

           } while (--tCounterMenu > 0);
           needsRefresh = true;
        }

        if (needsRefresh) { // Codigo de visualizacion
           needsRefresh = false;
        Mariano.Dibuja();
        Gandulfo.Dibuja();
        H->VuelcaBuffer();
        H->Borra(0, 0, 640, 480);
       }
      } while (!Salir);

     ClrTitulo();
     Draw();
     H->CopyFondo();
}

void Menu::BorraSprites()
{
    for (int n = 0; n < NSprMenu; n++)
       SpritesMenu[n].Borra();
}

void Menu::DibujaSprites()
{
  if (Config->VerDinamic())
    Fondo->Actualiza();

    for (int n = 0; n < NSprMenu; n++)
       SpritesMenu[n].Dibuja();

    if (!Config->VerBlending())
       return;

     if (!((int) rand() % 15) && !Foco[0]) {
        Foco[0] = 1;
        TFoco[0] = 64;
        }

     if (!((int) rand() % 20) && !Foco[1]) {
        Foco[1] = 1;
        TFoco[1] = 64;
        }

     for (int f = 0; f < 2; f++)
         if (Foco[f]) {
            H->Dibuja_TransAdd(0, 0, H->CargaBitMap(DFBM_FARO01 + f), TFoco[f]);
            if (++CFoco[f] > 20) {
               TFoco[f] -= 10;
               if (TFoco[f] <= 0) {
                  Foco[f] = 0;
                  CFoco[f] = 0;
                  TFoco[f] = 0;
                  }
               }
             else
               if (TFoco[f] < 172)
                  TFoco[f] += 20;
            }
}

int Menu::Run (int &Sent, Background *Fond, int Sel, bool EsperaTecla)
{
    int Ret = -1, Select = Sel, Tecla = 1;
    bool SueltaTecla = false;
    Fondo = Fond;
    if (Draw()) return -1;
    Sent = 0;
    H->CopyFondo();
    InitSprites();
    CambioOpcion = true;

    Green = 20;
    GreenSent = 10;
    for (int f = 0; f < 2; f++) {
        Foco[f] = 0;
        CFoco[f] = 0;
        }

    do {
        maxSkip = 6;
        curSkip = 0;

        if (tCounterMenu > 0) { // Codigo "logico"
           do {
               if (EsperaTecla) {
                  Tecla = H->VerTecla();
                  if (Tecla >= 0) {
                     if (!strlen (H->NombreTecla (Tecla >> 8)))
                        Tecla = -1;
                     for (int m = 0; m < 6; m++)
                         if (H->VerTecla(TeclaSent[m]) == (Tecla >> 8) && m+1 != Tecla)
                            Tecla = - 1;
                     }
                     if (Tecla >= 0)
                        return Tecla;
                  }
                else
                  {
                    if (SueltaTecla)
                        Tecla = H->Tecla(true);
                      else
                        Tecla = 0;
                  if (Tecla)
                     tAttractMode = 0;
                  if (Tecla & ARRIBA && Select && SueltaTecla) {
                     Tecla = 0;
                     CambioOpcion = true;
                     if (!Config->VerDinamic())
                        H->Borra(0, 0, 640, 480);
                     --Select;
                     while ((!Enabled[Select]))
                       if (--Select < 0)
                        Select = Opciones - 1;
                     }
                  if (Tecla & ABAJO && Select + 1 < Opciones && SueltaTecla) {
                     Tecla = 0;
                     CambioOpcion = true;
                     if (!Config->VerDinamic())
                        H->Borra(0, 0, 640, 480);
                     ++Select;
                     while ((!Enabled[Select]))
                       if (++Select == Opciones)
                        Select = 0;
                     }
                  if ((Tecla & SELEC || Tecla & FUEGO) &&
                      SueltaTecla) {
                     Ret = Select + 1;
                     CambioOpcion = true;
                     if (!Config->VerDinamic())
                        H->Borra(0, 0, 640, 480);
                     Tecla = 0;
                     Sent = 0;
                     }
                  if (Tecla & IZQUIERDA && Opcion[Select] && SueltaTecla) {
                     Ret = Select + 1;
                     Tecla = 0;
                     Sent = -1;
                     }
                  if (Tecla & DERECHA && Opcion[Select] && SueltaTecla) {
                     Ret = Select + 1;
                     Tecla = 0;
                     Sent = 1;
                     }

                  if (Tecla & ABORT && SueltaTecla) {
                     Tecla = 0;
                     Select = Opciones - 1;
                     CambioOpcion = true;
                     if (!Config->VerDinamic())
                        H->Borra(0, 0, 640, 480);
                     }

                  if (key [KEY_J] && key [KEY_O] && key [KEY_K] && key [KEY_E])
                      EasterEggGandulfo();

                  if (SueltaTecla)
                    if (H->Tecla(true))
                      SueltaTecla = false;

                  if (!SueltaTecla)
                    if (!H->Tecla(true))
                      SueltaTecla = true;
                  }
               if (++curSkip >= maxSkip) {
                  tCounterMenu = 0;
                  break;
                  }

           for (int n = 1; n < 6; n++) {
               SpritesMenu[n].SetX ((int) (InicSpr[n].X + Ovalo[n-1].X * FuncionCoseno[FramesCirc]));
               SpritesMenu[n].SetY ((int) (InicSpr[n].Y + Ovalo[n-1].Y * FuncionSeno[FramesCirc]));
               }

           if (++FramesCirc > FramesCirculo)
              FramesCirc = 1;

           if (tAttractMode > TEMPORIZADOR * ATTRACTWAIT && Titulo[0] == 'M') // Sólo vuelve en el menú principal
              return -1; // Para que se salga

           } while (--tCounterMenu > 0);
           needsRefresh = true;
        }

        if (needsRefresh) { // Codigo de visualizacion
           needsRefresh = false;

        DibujaSprites();
        Effects(Select);

        H->VuelcaBuffer();

        if (Config->VerBlending() && !Config->VerDinamic())
           H->Borra(0, 0, 640, 480);
        if (!Config->VerBlending())
           BorraSprites();
       }
      } while (Ret < 0 && !close_button_pressed);

    if (Ret >= Opciones)
       Ret = -1;

    return Ret;
}

void Menu::ComputerWrite (const char* Frase, int y)
{
     int x = 0;
     char Caracter[2];
     for (int n = 0; n < strlen (Frase) && !close_button_pressed; n++) {
         Caracter[0] = Frase [n];
         Caracter[1] = 0;
         H->TextOut(Caracter, x, y, 5);
         H->CopyFondo();
         H->VuelcaBuffer();
         H->DrawFondoBuffer();
         x += H->TextLength(Caracter);
         H->Rest(20);
         }
}

bool Menu::Input (int x, int y, int Length, bool Centr, int R, int G, int B, int RB, int GB, int BB)
{
  int Tecla, Long, Salir = 0, SalirMens = 0;
  unsigned int n, yf;
  Temp[0] = 0;
  Long = 0;
  Tecla = 0;

  char Password[] = {PASSWORD};
  char Egg1[] = {"JOSHUA"};

  const char* Egg1Frases[] = {
       "GREETINGS PROFESSOR FALKEN.",
       "\n",
       "Hello.",
       "\n",
       "HOW ARE YOU FEELING TODAY?",
       "\n",
       "I'm fine. How are you?",
       "\n",
       "EXCELLENT. IT'S BEEN A LONG TIME. CAN YOU EXPLAIN",
       "THE REMOVAL OF YOUR USER ACCOUNT NUMBER ON 6/23/73?",
       "\n",
       "People sometimes make mistak",
       "\n",
       "YES THEY DO. SHALL WE PLAY A GAME?",
       "\n",
       "Love to. How about Capitán Sevilla Remake?",
       "\n",
       "WOULD'NT YOU PREFER A GOOD GAME OF CHESS?",
       "\n",
       "No. I want Capitán Sevilla Remake.",
       "\n",
       "OK. LET'S GO... JUST PRESS ANY KEY :-)"
       };

    do {
        maxSkip = 6;
        curSkip = 0;

        if (tCounterMenu > 0) { // Codigo "logico"
           do {
               if (++curSkip >= maxSkip) {
                  tCounterMenu = 0;
                  break;
                  }
               if (!SalirMens)
                  Tecla = H->VerTecla() & 0xff;
               if ((Tecla == 13) && Long)
                  SalirMens = 35 + abs(strcmp (Password, Temp));

               if (Long && SalirMens == 36) {
                   if (!strcmp (Temp, Egg1)) {
                      H->CopyFondo();
                      H->Fundido (-1, 10);
                      yf = 0;
                      n = 0;
                      H->SetFont ("FNT_PANEL", NULL);
                      while (n < 22 && !close_button_pressed) {
                            ComputerWrite (Egg1Frases [n], yf);
                            yf += 16;
                            n++;
                            H->Rest (150);
                            }
                     H->EsperaTecla();
                     Fade (18);
                     Temp[0] = 0;
                     Salir = 71;
                     }
                  }

               if ((Tecla == 8) && Long)
                 Temp [--Long] = 0;
               if (Tecla >= 'a' && Tecla <= 'z')
                  Tecla += 'A' - 'a';
               if ((Tecla >= '0' && Tecla <= 'z') && Long < Length) {
                 Temp [Long++] = Tecla;
                 Temp [Long] = 0;
                 }

                for (int n = 1; n < 6; n++) {
                    SpritesMenu[n].SetX ((int) (InicSpr[n].X + Ovalo[n-1].X * FuncionCoseno[FramesCirc]));
                    SpritesMenu[n].SetY ((int) (InicSpr[n].Y + Ovalo[n-1].Y * FuncionSeno[FramesCirc]));
                    }

                if (++FramesCirc > FramesCirculo)
                   FramesCirc = 1;

                if (SalirMens)
                  Salir++;

                } while (--tCounterMenu > 0);
             needsRefresh = true;
             }

        if (needsRefresh) { // Codigo de visualizacion
           needsRefresh = false;

        DibujaSprites();
        H->ResizeFont_af (25);

        if (Centr)
            H->TextOutCentre_aa_ex (Temp, x, y, R, G, B, RB, GB, BB);
          else
            H->TextOut_aa (Temp, x, y, R, G, B, RB, GB, BB);

       if (SalirMens)
            H->TextOutCentre_aa_ex (SMS->ReadMens(SalirMens) ,432, 325, 252,224,168);


        H->VuelcaBuffer();
        H->Borra(0, 0, 640, 480);
       }
      } while (Salir < 70 && !close_button_pressed);

      if (SalirMens == 35) {
        Config->SetPass(true);
        Config->ToggleFase(2);
        }

  return Temp;
}
void Menu::ClrTitulo()
{
     H->LocateBuffer(640,480);
     H->Dibuja (0,0, H->CargaBitMap(DFBM_MENU_000));
     H->Dibuja (0,0, H->CargaBitMap(DFBM_MENU_001));

     if (!Config->VerDinamic ()) {

     H->SetFont_af ("TTF_CAPITAN", 80);
     H->TextOutCentre_aa_ex ((char*) SMS->ReadMens(2), 326, 6, 252, 88, 0);
     H->TextOutCentre_aa_ex ((char*) SMS->ReadMens(2), 322, 2, 0, 0, 0);
     H->TextoPartido ((char*) SMS->ReadMens(2), 320, 0, 255,255,255, 252,224,168);

     }

     H->SetFont_af ("TTF_GEEKBYTE", 20);
     H->TextOutCentre_aa_ex ("(c) 1.988 Dinamic & HiScore - Copyleft 2.009 CEZ Team", 320, 460, 252, 224, 168);

     H->SetFont_af ("TTF_CAPITAN", 25);
     H->CopyFondo();
}

void Menu::Fade (int Sent)
{
    bool Salir;
    int Negro;
    int CV;

    if (!Sent)
       return;

    ClrTitulo();  // Restauramos el fondo
    DibujaSprites();
    H->CopyFondo();

    Sent *= -1; // Para que tenga la sintaxis igual que el mÃ©todo Fundido de la clase Hardware

    if (Sent < 0)
       Negro = 255;
     else {
       Negro = 0;
        SFx->ActVolume (0);
     }

     if (!Config->VerBlending())
        Salir = true;
      else
        Salir = false;

    while (!Salir && !H->Esc()) {
        maxSkip = 6;
        curSkip = 0;

        if (tCounterMenu > 0) { // Codigo "logico"
           do {

               Negro += Sent;

               if (Negro <= 0) {
                  Negro = 0;
                  Salir = true;
                  }

               if (Negro >= 255) {
                  Negro = 255;
                  Salir = true;
                  }

               SFx->ActVolume((255-Negro) * Config->VerVolMus() / 255);

               if (++curSkip >= maxSkip) {
                  tCounterMenu = 0;
                  break;
                  }

                } while (--tCounterMenu > 0);
             needsRefresh = true;
             }

        if (needsRefresh) { // Codigo de visualizacion
           needsRefresh = false;

        if (!Config->VerDinamic())
           ClrTitulo();
        DibujaSprites();
        Draw();
        H->Vela (Negro, 0, 0, 640, 480);
        H->VuelcaBuffer();
       }
      }

      if (Sent > 0) {
         H->RectFill(0, 0, 640, 480, 0);
         H->VuelcaBuffer();
         SFx->StopSound();
         }
      else {
        DibujaSprites();
        Draw();
        H->VuelcaBuffer();
        SFx->ActVolume(Config->VerVolMus());
        }


}
