unit menu;

interface
uses math,types3d,math3d,opengl,windows,texfont;
const BtnCnt = 5;
      CirCnt = 16;
      LinCnt = 5;
type TBtn = RECORD
      Caption,Units: String;
      Value: GLint;
      W,A,MaxW: GLfloat;
      MoveTime,LeaveTime: LongWord;
      MouseIn,MouseInFirst: Boolean; //mouseinfirst sa pri hoveri na button nastavi na true; ked tuto informaciu spracujem (prehram sampel), nastavim si ju manualne na false, cize sampel sa prehra len raz
      Shape: set of (BT_NORMAL,BT_OPTION,BT_INVISIBLE);
     END;
     TLin = RECORD
      Siz,Pos,Now: GLfloat; //hrubka a povodna a sucastna pozicia ciarky
      Spd: GLint;       //rychlost udana v milisekundach, za ktore prejde obrazovkou
      Up: Boolean;      //ci ide hore
     END;
     TCir = RECORD
      P_: Array[0..3] of TCoord2D;
      P: TCoord2D;
      Size: GLfloat;
     END;
var Btn: Array[0..BtnCnt-1] of TBtn;
    Lin: Array[0..LinCnt-1] of TLin;
    Cir: Array[0..CirCnt-1] of TCir;
    I_,I_Last: GLfloat;

    //ovladanie klavesnicou
    KeyButton: GLint=-1; //index gombika na ktorom je/bola mys
    TmpX,TmpY: GLfloat;
    KeyMenu: set of (MoveUp,MoveDown)=[];

procedure initbuttonsMenu(_Width_,_Height_: GLint);
procedure initbuttonsOpti(_Width_,_Height_: GLint);
procedure menuanim(T: LongWord; TexCursor,TexBackground,TexCircle,TexButton,TexHalo,TexFont, _Width_,_Height_,_X_,_Y_, When,Btns: GLint);

implementation

procedure stuffinit(_Width_,_Height_: GLint);
var C: GLint;
begin
  for C:=0 to LinCnt-1 do begin
   Lin[C].Siz:=2+Random(3000)/1000;
   Lin[C].Pos:=Random(_Height_);
   Lin[C].Up:=1=Random(2);
   Lin[C].Spd:=14000+Random(14000);
  end;

  for C:=0 to CirCnt-1 do begin
   Cir[C].P_[0].X:=_Width_*Random(1000)/1000;
   Cir[C].P_[0].Y:=_Height_*Random(1000)/1000;

   Cir[C].P_[1].X:=_Width_*Random(1000)/1000;
   Cir[C].P_[1].Y:=_Height_*Random(1000)/1000;

   Cir[C].P_[2].X:=_Width_*Random(1000)/1000;
   Cir[C].P_[2].Y:=_Height_*Random(1000)/1000;

   Cir[C].P_[3].X:=_Width_*Random(1000)/1000;
   Cir[C].P_[3].Y:=_Height_*Random(1000)/1000;

   Cir[C].Size:=0.5+Random(500)/1000;
  end;
end;

procedure initbuttonsMenu(_Width_,_Height_: GLint);
begin
 Btn[0].Caption:='NEW GAME'; Btn[0].Shape:=[BT_NORMAL];
 Btn[1].Caption:='INTRO';    Btn[1].Shape:=[BT_NORMAL];
 Btn[2].Caption:='OPTIONS';  Btn[2].Shape:=[BT_NORMAL];
 Btn[3].Caption:='CREDITS';  Btn[3].Shape:=[BT_NORMAL];
 Btn[4].Caption:='QUIT';     Btn[4].Shape:=[BT_NORMAL];
 stuffinit(_Width_,_Height_);
end;
procedure initbuttonsOpti(_Width_,_Height_: GLint);
begin
 Btn[0].Caption:='ROUND LENGTH';  Btn[0].Shape:=[BT_OPTION];     Btn[0].Units:='SECONDS';     Btn[0].Value:=150;
 Btn[1].Caption:='PLAYER LIFE';   Btn[1].Shape:=[BT_OPTION];     Btn[1].Units:='MILISECONDS'; Btn[1].Value:=1800;
 Btn[2].Caption:='POINTS TO WIN'; Btn[2].Shape:=[BT_OPTION];     Btn[2].Units:='';            Btn[2].Value:=10;
 Btn[3].Caption:='Katka <3';      Btn[3].Shape:=[BT_INVISIBLE];  Btn[3].Units:='I Love You';  Btn[3].Value:=2;
 Btn[4].Caption:='BACK';          Btn[4].Shape:=[BT_NORMAL];     Btn[4].Units:='';            Btn[4].Value:=0;

 stuffinit(_Width_,_Height_);
end;

function ifinwindow(x,y,x1,y1,x2,y2: glfloat): boolean;
begin
 if (x>=x1) and (x<=x2) and (y>=y1) and (y<=y2) then result:=true else result:=false;
end;




procedure drawcircles(T: LongWord; _Width_,_Height_: GLint; HaloID: GLuint);
var C: GLint;
begin
  glLoadIdentity();
  glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,HaloID);

  glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA,GL_ONE{_MINUS_SRC_ALPHA});
  glBegin(GL_QUADS);
  glColor4f(0.04,0.1,0.23,0.45);
  for C:=0 to CirCnt-1 do begin
   Cir[C].P.X:=CubicIPol(Cir[C].P_[0].X,Cir[C].P_[1].X,Cir[C].P_[2].X,Cir[C].P_[3].X,I_);
   Cir[C].P.Y:=CubicIPol(Cir[C].P_[0].Y,Cir[C].P_[1].Y,Cir[C].P_[2].Y,Cir[C].P_[3].Y,I_);

   {Cir[C].P.X:=CosIPol( Cir[C].P_[1].X, Cir[C].P_[2].X, (T mod 1000)/1000 );
   Cir[C].P.Y:=CosIPol( Cir[C].P_[1].Y, Cir[C].P_[2].Y, (T mod 1500)/1500 );}

   glTexCoord2f(0,0);glVertex2f( Cir[C].P.X-(280*Cir[C].Size) , Cir[C].P.Y-(280*Cir[C].Size) );
   glTexCoord2f(1,0);glVertex2f( Cir[C].P.X+(280*Cir[C].Size) , Cir[C].P.Y-(280*Cir[C].Size) );
   glTexCoord2f(1,1);glVertex2f( Cir[C].P.X+(280*Cir[C].Size) , Cir[C].P.Y+(280*Cir[C].Size) );
   glTexCoord2f(0,1);glVertex2f( Cir[C].P.X-(280*Cir[C].Size) , Cir[C].P.Y+(280*Cir[C].Size) );
  end;
  glEnd();

  I_:=(T mod 2200)/2200;
   if I_<I_Last then begin
     for C:=0 to CirCnt-1 do begin
      Cir[C].P_[0]:=Cir[C].P_[1];
      Cir[C].P_[1]:=Cir[C].P_[2];
      Cir[C].P_[2]:=Cir[C].P_[3];

      Cir[C].P_[3].X:=_Width_*Random(1000)/1000;
      Cir[C].P_[3].Y:=_Height_*Random(1000)/1000;
     end;
   end;
  I_Last:=I_;
end;

procedure drawscanlines(T: LongWord; _Width_,_Height_: GLint);
var C: GLint;
begin
  glLoadIdentity();
  glDisable(GL_TEXTURE_2D);

  glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA,GL_ONE);
  glBegin(GL_QUAD_STRIP);
  for C:=0 to LinCnt-1 do begin

  Lin[C].Now:=(T mod Lin[C].Spd)/Lin[C].Spd*_Height_; if Lin[C].Up then Lin[C].Now:=Lin[C].Now*-1;
  Lin[C].Now:=Lin[C].Now+Lin[C].Pos;
  if Lin[C].Now<0 then Lin[C].Now:=_Height_+Lin[C].Now;
  if Lin[C].Now>_Height_ then Lin[C].Now:=Lin[C].Now-_Height_;


  glColor4f(1,1,1,0.0);
   glVertex2f(0       , Lin[C].Now-Lin[C].Siz);
   glVertex2f(_Width_ , Lin[C].Now-Lin[C].Siz);
  glColor4f(1,1,1,0.081);
   glVertex2f(0       , Lin[C].Now);
   glVertex2f(_Width_ , Lin[C].Now);
  glColor4f(1,1,1,0.0);
   glVertex2f(0       , Lin[C].Now+Lin[C].Siz);
   glVertex2f(_Width_ , Lin[C].Now+Lin[C].Siz);

  end;
  glEnd();

  glEnable(GL_TEXTURE_2D);
end;





procedure menuanim(T: LongWord; TexCursor,TexBackground,TexCircle,TexButton,TexHalo,TexFont, _Width_,_Height_,_X_,_Y_, When,Btns: GLint);

var Size,A,Tmp: GLfloat;
    C,E: GLint;
    TmpS,TmpS1: String;
begin

  if KeyMenu=[MoveDown] then begin
   Inc(KeyButton); KeyButton:=KeyButton mod BtnCnt;
  end;
  if KeyMenu=[MoveUp] then begin
   Dec(KeyButton); if KeyButton<0 then Inc(KeyButton,BtnCnt);
  end;
  if KeyMenu<>[] then begin
   TmpX:=_Width_ shr 1+100;
   TmpY:=_Height_/2 - BtnCnt/2*80+KeyButton*80+40;
  end;


  glClearColor(0,0,0,0.5);
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,TexBackground);

//POZADIE
  if T<3000 then glColor4f(1,1,1,T/3000) else glColor4f(1,1,1,1);
    glBegin(GL_QUADS);
      glTexCoord2f(0,0);glVertex2f(0,0);
      glTexCoord2f(1,0);glVertex2f(_Width_,0);
      glTexCoord2f(1,1);glVertex2f(_Width_,_Height_);
      glTexCoord2f(0,1);glVertex2f(0,_Height_);
    glEnd();


  drawcircles(T,_Width_,_Height_,TexHalo);
  //drawscanlines(T,_Width_,_Height_);



  glTranslatef(_Width_ shr 1,_Height_ shr 1,0);
  if (T>1000) and (T<5000) then glRotatef(CosIPol(0,90,(T-1000)/4000),0,0,1) else if (T>=5000) then glRotatef(90,0,0,1);

//OTVARAJUCE SA KRUHY
glBlendFunc(GL_SRC_ALPHA,GL_ONE);

  glBindTexture(GL_TEXTURE_2D,TexCircle);
  A:=-1;
  if (T>6000) then if (T<10000) then A:=CosIPol(0,140,(T-6000)/4000) else if (T>=10000) then A:=140;

  Size:=_Width_/2;
  if (T<10000) then Size:=Size+300-CosIPol(0,300,T/10000);

    glBegin(GL_QUADS);
  glColor4f(1,1,1,1);
      glTexCoord2f(0,0);glVertex2f(-Size,-Size-A);
      glTexCoord2f(1,0);glVertex2f(+Size,-Size-A);
  if (T>6000) and (T<9000) then glColor4f(1,1,1,1-(T-6000)/3000/2) else if (T<=6000) then glColor4f(1,1,1,1) else glColor4f(1,1,1,0.5);
      glTexCoord2f(1,1);glVertex2f(+Size,-A);
      glTexCoord2f(0,1);glVertex2f(-Size,-A);
    glEnd();
    glBegin(GL_QUADS);
  if (T>6000) and (T<9000) then glColor4f(1,1,1,1-(T-6000)/3000/2) else if (T<=6000) then glColor4f(1,1,1,1) else glColor4f(1,1,1,0.5);
      glTexCoord2f(0,1);glVertex2f(-Size,+A);
      glTexCoord2f(1,1);glVertex2f(+Size,+A);
  glColor4f(1,1,1,1);
      glTexCoord2f(1,0);glVertex2f(+Size,Size+A);
      glTexCoord2f(0,0);glVertex2f(-Size,Size+A);
    glEnd();


//GOMBIKY
glBlendFunc(GL_SRC_ALPHA,GL_ONE);

  for C:=0 to BtnCnt-1 do begin
     Btn[C].A:=0;
     if (T>4000+C*420) and (T<6000+C*420) then Btn[C].A:=(T-(4000+C*420))/2000 else if (T>=6000+C*420) then Btn[C].A:=1;

     Btn[C].W:=CosIPol(550,170,Btn[C].A);

     if (Btn[C].MouseIn) then begin
       if (GetTickCount-Btn[C].MoveTime<210) then Btn[C].W:=CosIPol(170,250,(GetTickCount-Btn[C].MoveTime)/210) else Btn[C].W:=250;
     end else begin
       if (GetTickCount-Btn[C].LeaveTime<600) then Btn[C].W:=CosIPol(Btn[C].MaxW,170,(GetTickCount-Btn[C].LeaveTime)/600);
     end;
  end;


  if (T>4000) then begin
   glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D,TexButton);
   glLoadIdentity();

   glBegin(GL_QUADS);
    for C:=0 to BtnCnt-1 do begin

//VYSVECOVANIE GOMBIKOV
     if ifinwindow(_X_,_Y_,
                   _Width_/2-Btn[C].W,_Height_/2-32 - BtnCnt/2*80+C*80+40,
                   _Width_/2+Btn[C].W,_Height_/2+32 - BtnCnt/2*80+C*80+40) then begin

        if not Btn[C].MouseIn then begin Btn[C].MoveTime:=GetTickCount; Btn[C].MouseIn:=TRUE; Btn[C].MouseInFirst:=TRUE; end;

     end else begin
        if Btn[C].MouseIn then begin Btn[C].MaxW:=Btn[C].W; Btn[C].MouseIn:=1=0; Btn[C].LeaveTime:=GetTickCount; end;
     end;


//FADE-OUT GOMBIKA
     if Btn[C].MouseIn=TRUE then glColor4f(1,0.2,0,Btn[C].A)
     else begin
      if GetTickCount-Btn[C].LeaveTime<500 then glColor4f(1,
                                                           CosIPol(0.2,1,(GetTickCount-Btn[C].LeaveTime)/500),
                                                           LinIPol(0,1,(GetTickCount-Btn[C].LeaveTime)/500),Btn[C].A)
      else glColor4f(1,1,1,Btn[C].A);
     end;


//rozsirenie gombikov pri kliknuti
  if (Btns>0) then begin
    if (T-When)<2000 then
    Btn[C].W:=CosIPol(Btn[C].W, 100+100*(Abs(BtnCnt)-Abs(C-(Btns-1))) ,(T-When)/2000);
  end;


//VYKRESLENIE GOMBIKOV
     if Btn[C].Shape=[BT_NORMAL] then begin
     glTexCoord2f(0,0);glVertex2f(_Width_/2-Btn[C].W,_Height_/2-32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(1,0);glVertex2f(_Width_/2+Btn[C].W,_Height_/2-32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(1,1);glVertex2f(_Width_/2+Btn[C].W,_Height_/2+32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(0,1);glVertex2f(_Width_/2-Btn[C].W,_Height_/2+32 - BtnCnt/2*80+C*80+40);
     end;

    end;
   glEnd();

   WantWriteNow(TexFont);
   for C:=0 to BtnCnt-1 do begin


     if Btn[C].MouseIn=TRUE then glColor4f(1,1,1,Btn[C].A)
     else begin
      if GetTickCount-Btn[C].LeaveTime<500 then glColor4f(LinIPol(1.00,0.75,(GetTickCount-Btn[C].LeaveTime)/500),
                                                          LinIPol(1.00,0.15,(GetTickCount-Btn[C].LeaveTime)/500),
                                                          LinIPol(1.00,0.00,(GetTickCount-Btn[C].LeaveTime)/500),Btn[C].A)
      else glColor4f(0.75,0.15,0,Btn[C].A);
     end;

     if Btn[C].Shape<>[BT_INVISIBLE] then begin
      TmpS:=Btn[C].Caption;
      Str(Btn[C].Value,TmpS1);
      if Btn[C].Shape=[BT_OPTION] then begin

      TmpS:=TmpS+': '+TmpS1;
                          for e:=0 to 2 do
                           Txt(TmpS,
                               _Width_/2-Length(TmpS)*(     30+((Btn[C].W-170)/(230-170)*10)   )/2,
                               _Height_/2-32 - BtnCnt/2*80+C*80+40+32-20+4,
                               30+((Btn[C].W-170)/(230-170)*10),30);
      end else
                           Txt(TmpS,
                               _Width_/2-Length(TmpS)*(     40+((Btn[C].W-170)/(230-170)*10)   )/2,
                               _Height_/2-32 - BtnCnt/2*80+C*80+40+32-20+4,
                               40+((Btn[C].W-170)/(230-170)*10),40);
     end;

//text cez celu obrazovku pri kliknuti
                      if (Btns=C+1) and (T-When<2000) then begin
                      if Btn[C].Shape=[BT_NORMAL] then begin
                         glColor4f(1,1-(T-When)/2000,1-(T-When)/2000,1);
                           Txt(Btn[C].Caption,
                               CosIPol(_Width_/2-Length(Btn[C].Caption)*(     40+((Btn[C].W-170)/(230-170)*10)   )/2,        _Width_/2-Length(Btn[C].Caption)*100,  (T-When)/2000),
                               CosIPol(_Height_/2-32 - BtnCnt/2*80+C*80+40+32-20+4,              _Height_/2-250,                                                    (T-When)/2000),
                               CosIPol(40+((Btn[C].W-170)/(230-170)*10),            200,                                                                            (T-When)/2000),
                               CosIPol(40,500,                                                                                                                      (T-When)/2000));
                      end else begin



                      end;
                      end;
   end;



//blikave eketky nad gombikmi (najazd kurzora+zobrazenie)
   glBindTexture(GL_TEXTURE_2D,TexHalo);
     glBegin(GL_QUADS);

   for C:=0 to BtnCnt-1 do
    if (Btn[C].A>0) and (Btn[C].A<0.5) and (Btn[C].Shape<>[BT_INVISIBLE]) then begin

     glColor4f(1,1,0.9,1-Btn[C].A*2);

     glTexCoord2f(0,0);glVertex2f(0      ,_Height_/2-32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(1,0);glVertex2f(_Width_,_Height_/2-32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(1,1);glVertex2f(_Width_,_Height_/2+32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(0,1);glVertex2f(0      ,_Height_/2+32 - BtnCnt/2*80+C*80+40);

    end;
     glEnd();


     glBegin(GL_QUADS);
   for C:=0 to BtnCnt-1 do
    if (GetTickCount-Btn[C].MoveTime<500) and (Btn[C].Shape<>[BT_INVISIBLE])  then begin

     glColor4f(1,1,0.9,1-(GetTickCount-Btn[C].MoveTime)/500);

     glTexCoord2f(0,0);glVertex2f(0      ,_Height_/2-32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(1,0);glVertex2f(_Width_,_Height_/2-32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(1,1);glVertex2f(_Width_,_Height_/2+32 - BtnCnt/2*80+C*80+40);
     glTexCoord2f(0,1);glVertex2f(0      ,_Height_/2+32 - BtnCnt/2*80+C*80+40);

    end;
     glEnd();

  end;

//HALO
  if (T<5000) then begin
  glCOlor4f(1,1,1,1-T/5000);
  glLoadIdentity();
  glBindTexture(GL_TEXTURE_2D,TexHalo);
  glBegin(GL_QUADS);
   glTexCoord2f(0,0);glVertex2f(_Width_/2-_Height_/2,0);
   glTexCoord2f(1,0);glVertex2f(_Width_/2+_Height_/2,0);
   glTexCoord2f(1,1);glVertex2f(_Width_/2+_Height_/2,_Height_);
   glTexCoord2f(0,1);glVertex2f(_Width_/2-_Height_/2,_Height_);
  glEnd();
  end;

//MYS
  glLoadIdentity();
  glTranslatef(_X_,_Y_,0);

  Tmp:=(_X_-_Width_/2);
  if (Tmp)=0 then Tmp:=1;//zabranime deleniu nulou
  if (Tmp)<0 then glRotatef(180,0,0,1);

  glRotatef(ArcTan((_Y_-_Height_/2)/Tmp)/2/PI*360-45,0,0,1);

  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  if (T>5000) and (T<6000) then glColor4f(0,0,0,(T-5000)/1000) else if (T>=6000) then glColor4f(0,0,0,1) else glColor4f(0,0,0,0);
  glBindTexture(GL_TEXTURE_2D,TexCursor);
  glBegin(GL_QUADS);
   glTexCoord2f(0,0);glVertex2f(-3       ,-3       );
   glTexCoord2f(1,0);glVertex2f(+3    +50,-3       );
   glTexCoord2f(1,1);glVertex2f(+3    +50,+3    +50);
   glTexCoord2f(0,1);glVertex2f(-3       ,+3    +50);
  glEnd();

  glBlendFunc(GL_SRC_ALPHA,GL_ONE);
  if (T>5000) and (T<6000) then glColor4f(1,1,1,(T-5000)/1000) else if (T>=6000) then glColor4f(1,1,1,1) else glColor4f(1,1,1,0);
  glBindTexture(GL_TEXTURE_2D,TexCursor);
  glBegin(GL_QUADS);
   glTexCoord2f(0,0);glVertex2f(  0   ,  0   );
   glTexCoord2f(1,0);glVertex2f(   +50,  0   );
   glTexCoord2f(1,1);glVertex2f(   +50,   +50);
   glTexCoord2f(0,1);glVertex2f(  0   ,   +50);
  glEnd();

  if (T>5000) and (T<6000) then glColor4f(1,1,1,(T-5000)/1000*0.45) else if (T>=6000) then glColor4f(1,1,1,0.45) else glColor4f(1,1,1,0);
  glBindTexture(GL_TEXTURE_2D,TexHalo);
  glBegin(GL_QUADS);
   glTexCoord2f(0,0);glVertex2f(   -90 +25,   -90 +25);
   glTexCoord2f(1,0);glVertex2f(   +90 +25,   -90 +25);
   glTexCoord2f(1,1);glVertex2f(   +90 +25,   +90 +25);
   glTexCoord2f(0,1);glVertex2f(   -90 +25,   +90 +25);
  glEnd();


  glLoadIdentity();
  WantWriteNow(TexFont);
  glColor4f(0.5,0,0,1);
  txt('v0.8.1 spongia',10,10,12,12);

//fadeout pri kliknuti
  if ((Btns>0) and (T-When>1000) and (T-When<=2000)) then begin
   glDisable(GL_TEXTURE_2D);
   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

   glBegin(GL_QUADS);
    for C:=0 to 100-1 do begin

     if C mod 2=0 then begin
      glColor4f( 0,0,0,  (1+C/100)       *  (T-When-1000)/1000 );
     end else begin
      glColor4f( 0,0,0,  (1+(100-C)/100) *  (T-When-1000)/1000 );
     end;

     glVertex2f(0      ,(C+0)/100*_Height_);
     glVertex2f(_Width_,(C+0)/100*_Height_);
     glVertex2f(_Width_,(C+1)/100*_Height_);
     glVertex2f(0      ,(C+1)/100*_Height_);
    end;
   glEnd();
  end;

//FADE IN
  if (T<1000) then begin
  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  glColor4f(1,1,1,1-T/1000);
  glLoadIdentity();
  glDisable(GL_TEXTURE_2D);
  glBegin(GL_QUADS);
   glVertex2f(0,0);
   glVertex2f(_Width_,0);
   glVertex2f(_Width_,_Height_);
   glVertex2f(0,_Height_);
  glEnd();
  end;

end;

end.

