(******************************************************************************
 *          This unit is part of the Rantanplan Graphics Library              *
 *                            http://rgl.uw.hu                                *
 *                                                                            *
 * author:      Girhiny Róbert                                                *
 * web:         http://robcaa.uw.hu                                           *
 * mail:        robcaa@gmail.com                                              *
 *                                                                            *
 * decription:  Interactive Graphical User Interface.                         *
 *                                                                            *
 * history:     about 2008    - created the first version                     *
 *              2009.09.28    - added some comments                           *
 *                                                                            *
 *_____________________________________________________VERSION 0.2 REACHED____*
 *                                                                            *
 *              2009.12.17    - new panel and button texture, and many        *
 *                              bug correction in panel and button objects,   *
 *                              new (shadowed, and cleartype) fonts,          *
 *                              and some new methods                          *
 *              2009.12.18    - added transparency, and shadow to the panel   *
 *                              bug correcting in panel body graphic          *
 *              2009.12.25    - button, panel header offset problem solved    *
 *                              TGUILabel component rewrited                  *
 *              2010.01.01    - TGUITrackBar component added                  *
 *                              and a lot of vodka :D                         *
 *              2010.01.06    - my bithday :) added TGUIProgressBar component *
 *                                                                            *
 *_____________________________________________________VERSION 0.3 REACHED____*
 *                                                                            *
 *              2011.02.07    - bug correction: closing and showing animation *
 *                                                                            *
 ******************************************************************************)
unit RGLGUI;

interface
uses OpenGL,RGLTextures,RGLGlobal,
     RGLEastwood256Font,
     //RGLEastwood512Font,
     //RGLTimesNewRoman256Font,
     dialogs,SysUtils,classes,windows;


var Panel_texture : GLUint;

    GUI_WIDE: boolean = false; // wide GUI (1280x800) or normal (1024x768)
    GUI_WIDTH,GUI_HEIGHT : integer; // wide (1280x800) or normal (1024x768) GUI resolution

    GUI_OBJ_COUNT: integer = 0;

    GUI_ANIM_SPEED : real = 0.003; //0.003

    gmf: array[0..255] of GLYPHMETRICSFLOAT;

    lastClicked : integer = 0;

const
    GUI_PANEL_BORDER_WIDTH = 4;








//##########################################################################################
// STANDARD TYPES ##########################################################################
//##########################################################################################
// -----------------------------------------------------------------------------
// STANDARD GUI OBJECT ---------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUIobject = class
 OID : integer;
 left,top,right,bottom,width,height,cx,cy: integer;
 r,g,b,a: real; // szinezes
 visible : boolean;
 tag : integer;
 wai: integer; // who am i: 0:screen; 1:panel; 2:label; 3:bmpLabel; 4:button; 5:TrackBar; 6:ProgressBar
 procedure draw; virtual; abstract;
 procedure reSize; virtual; abstract;
 procedure hide; virtual; abstract;
 procedure show; virtual; abstract;
END;

Type PGUIObject = ^TGUIObject;
// -----------------------------------------------------------------------------



// -----------------------------------------------------------------------------
// GUI FONTS -------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUISysFont = object
 Font: GLUint;
 procedure Build(fontName:string; FontWeights:integer; OutLine:Boolean; zWidth:real; window_dc:HDC);
 procedure Kill;
end;

TYPE TGUIBmpFont = object
 Font   : GLUint;
 size   : byte;
 procedure Build(fsize:byte);
 procedure Kill;
end;

TYPE TGUIBFFont = object
 private
  base:byte;
  RowPitch,YOffset,cellx,celly:integer;
  RowFactor,ColFactor: real;
  width : array of byte;
  TexID : GLUint;
 public
  procedure processData(const dat: array of byte);
  procedure LoadFromFile(filename: string);
  procedure Kill;
end;
// -----------------------------------------------------------------------------


// -----------------------------------------------------------------------------
TYPE TGUIProcedure = procedure(Sender : TGUIObject);
// -----------------------------------------------------------------------------












//##########################################################################################
// GUI OBJECTS #############################################################################
//##########################################################################################

// -----------------------------------------------------------------------------
// SCREEN ----------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUIscreen = class(TGUIobject)
 clipping : boolean;
 child    : array of PGUIobject;
 constructor Create; overload;
 procedure   reSize; override;
 procedure   addChild(obj: PGUIObject);
 procedure   draw; override;
END;


// -----------------------------------------------------------------------------
// PANEL -----------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUIpanel = class(TGUIobject)
 x1,y1,x2,y2           : real; // a 3d-s koordinatak / az orokolt left top pedig a 2D-s koordinatak
 moveable              : boolean; // mozgathato e a panel
 focusable             : real; // ha 0 akkor nem tortenik semmi ha >0 akkor a megfelelo ertekkel megszinezi az egerrel mutatott panelt
 custom_border_texture : GLUint; // egyedi keret textura
 custom_texture        : GLUint; // egyedi belso textura
 custom_tile           : single; // 1: eseten a textura nyujtva lesz, >1 eseten csempezve
 drawing_rect          : TRect; // rajzolasi terulet
 statusBar             : Boolean; // a panel aljan legyen egy csik?
 header                : Boolean; // fejléc legyen e
 closebutton           : Boolean; // bezaro gomb legyen e
 parent                : PGUIobject;
 child                 : array of PGUIobject;
 caption               : string;
 font                  : TGUIBFFont; // caption font
 fr,fg,fb              : real; // font color
 transparentBorder     : real; // 0: no transparency; 1: full transparent border
 shadowWidth           : byte;
 shadowStrength        : real;
 onClose               : TGUIProcedure;
 Constructor Create; overload;
 Constructor Create(x1,y1,x2,y2:integer; parent:PGUIobject); overload;
 Constructor Create(x1,y1,x2,y2:integer; r,g,b,a:real; parent:PGUIobject); overload;
 procedure   reSize; override;
 procedure   addChild(obj: PGUIObject);
 procedure   draw; override;
 procedure   hide; override;
 procedure   show; override;
 function getRect : TRect;
protected
 closing_anim: real;
 showing               : boolean;
private
 hc                    : real; // for close button animation
 procedure outtext(alpha : real);
 function onMouse : Boolean;
 function front1 : Boolean;
 function front2 : Boolean;
 function front3 : Boolean;
 function onMouse2 : Boolean;
 function onMouse3 : Boolean;
 procedure bringToFront;
 function gX(x:integer) : single;
 function gy(y:integer) : single;
END;


// -----------------------------------------------------------------------------
// SYSLABEL --------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUISysLabel = class(TGUIobject)
 x,y   : real;
 sx,sy : real;
 font  : TGUISysFont;
 text  : string;
 parent: PGUIobject;
 Constructor Create; overload;
 Constructor Create(left,top:integer; scaleX,scaleY:real; text:string; parent:PGUIobject); overload;
 Constructor Create(left,top:integer; scaleX,scaleY:real; SYSfont:TGUISysFont; text:string; r,g,b,a:real; parent:PGUIobject); overload;
 procedure   reSize; override;
 procedure   draw; override;
END;


// -----------------------------------------------------------------------------
// BMP LABEL -------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUIBmpLabel = class(TGUIobject)
 x,y     : real;
 font    : TGUIBmpFont;
 text    : string;
 texture : GLUint;
 parent  : PGUIobject;
 Constructor Create; overload;
 Constructor Create(left,top:integer; texture:GLUint; text:string; parent:PGUIobject); overload;
 Constructor Create(left,top:integer; font:TGUIBMPFont; texture:GLUint; text:string; r,g,b,a:real; parent:PGUIobject); overload;
 procedure   reSize; override;
 procedure   draw; override;
END;


// -----------------------------------------------------------------------------
// LABEL -----------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUILabel = class(TGUIobject)
 private
  showing           : boolean;
  closing_anim: real;
 public
  clickOnce         : Boolean;
  mouseUpOnce       : Boolean;
  font              : TGUIBFFont;
  text              : string;
  parent            : PGUIobject;
  fr,fg,fb,fa       : real; // font color (default)
  fr2,fg2,fb2,fa2   : real; // font color (on mouse color)
  fsize             : byte; // font size
  useAsButton       : Boolean;
  phase             : byte;
  morphi            : real;
  onClick           : TGUIProcedure;
  MouseUp           : TGUIProcedure;
  MouseDown         : TGUIProcedure;
  function    getWidth : integer;
  function    getHeight : integer;
  Constructor Create; overload;
  Constructor Create(left,top:integer; text:string; parent:PGUIobject); overload;
  Constructor Create(left,top:integer; text:string; r,g,b,a:real; parent:PGUIobject); overload;
  Constructor Create(left,top:integer; font:TGUIBFFont; text:string; r,g,b,a:real; parent:PGUIobject); overload;
  procedure   reSize; override;
  function    gX(x:integer) : single;
  function    gY(y:integer) : single;
  procedure   draw; override;
  procedure   hide; override;
  procedure   show; override;
  function    onMouse : Boolean;
END;


// -----------------------------------------------------------------------------
// BUTTON ----------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUIButton = class(TGUIobject)
 private
  closing_anim    : real;
  showing         : boolean;
  procedure outtext(alpha: real);
 public
  x1,y1,x2,y2     : real;
  morph_speed     : real;
  morphi          : real;
  phase           : byte;
  custom_texture  : GLUint;
  parent          : PGUIobject;
  font            : TGUIBFFont;
  fr,fg,fb,fa     : real; // font color (default)
  fr2,fg2,fb2,fa2 : real; // font color (on mouse color)
  text            : string;
  onClick         : TGUIProcedure;
  MouseUp         : TGUIProcedure;
  MouseDown       : TGUIProcedure;
  clickOnce       : Boolean;
  mouseUpOnce     : Boolean;
  mouseDownOnce   : Boolean;
  heightModifier  : integer; // if you use glowing effect in the button.tga around the buttons, then you can stretch the button height. value = where begin the button real top (not glow effect)
  Constructor Create; overload;
  Constructor Create(x1,y1,x2,y2:integer; r,g,b,a:real; parent:PGUIObject); overload;
  procedure   reSize; override;
  function    onMouse : Boolean;
  procedure   draw; override;
  function    gX(x:integer) : single;
  function    gY(y:integer) : single;
  procedure   hide; override;
  procedure   show; override;
END;


// -----------------------------------------------------------------------------
// TRACKBAR --------------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUITrackBar = class(TGUIobject)
 private
  closing_anim      : real;
  showing           : boolean;
 public
  clickOnce         : Boolean;
  mouseUpOnce       : Boolean;
  parent            : PGUIobject;
  onChange          : TGUIProcedure;
  MouseDown         : TGUIProcedure;
  min,max,position  : integer;
  lr,lg,lb,la       : real; // line color
  br,bg,bb,ba       : real; // button color

  style             : byte; // 0:button+line; 1:only button; 2:only line;
  Constructor create; overload;
  Constructor Create(left,top,width:integer; parent:PGUIobject); overload;
  Constructor Create(left,top,width:integer; min,max,position:integer; parent:PGUIobject); overload;
  Constructor Create(left,top,width:integer; min,max,position:integer; r,g,b,a:real; parent:PGUIobject); overload;
  function    gX(x:integer) : single;
  function    gY(y:integer) : single;
  procedure   draw; override;
  procedure   hide; override;
  procedure   show; override;
  function    onMouse : Boolean;
  procedure   reSize; override;
END;


// -----------------------------------------------------------------------------
// PTOGRESSBAR -----------------------------------------------------------------
// -----------------------------------------------------------------------------
TYPE TGUIProgressBar = class(TGUIobject)
 private
  closing_anim      : real;
  showing           : boolean;
  ta                : real; // for animating
  procedure outtext(alpha: real);
 public
  clickOnce         : Boolean;
  mouseUpOnce       : Boolean;
  parent            : PGUIobject;
  onChange          : TGUIProcedure;
  MouseDown         : TGUIProcedure;
  min,max,position  : integer;
  lr,lg,lb,la       : real; // line color
  l2r,l2g,l2b,l2a   : real; // line 2 color color
  text              : string;
  font              : TGUIBFFont;
  fr,fg,fb,fa       : real; // font color (default)
  style             : byte; // 0:line1+line2;  1:only line1;  2:only line2 (not text and not position); 3: only line 2 and text
  Constructor create; overload;
  Constructor Create(left,top,width:integer; parent:PGUIobject); overload;
  Constructor Create(left,top,width:integer; min,max,position:integer; parent:PGUIobject); overload;
  Constructor Create(left,top,width:integer; min,max,position:integer; r,g,b,a:real; parent:PGUIobject); overload;
  function    gX(x:integer) : single;
  function    gY(y:integer) : single;
  procedure   draw; override;
  procedure   hide; override;
  procedure   show; override;
  function    onMouse : Boolean;
  procedure   reSize; override;
  procedure   inc; overload;
  procedure   inc(x:integer); overload;
END;


// -----------------------------------------------------------------------------
// STANDARD gui FUNCTIONS ------------------------------------------------------
// -----------------------------------------------------------------------------
procedure setGUIaspectRatio;
procedure initGUI(windowHDC: HDC; wide:boolean);
procedure DrawGUIMouse;
procedure outtextXY(left,top:integer; text:string);


procedure que(o: TGUIObject);



//##########################################################################################
// VARIABLES ###############################################################################
//##########################################################################################

var
 defaultGUISYSfont : TGUISysFont; // egy alap betutipus ez letrehozodik a GUI inicalizalasakor
 defaultGUIBMPfont : TGUIBmpFont;
 defaultGUIfont    : TGUIBFFont;

 GUIButtonTexture  : GLUint;
 GUITexture        : GLUint;
 GUImouseTexture   : GLUint; // eger texturaja
 GUImouseTexture2  : GLUint; // eger texturaja amikor le van nyomva
 mtx,mty           : integer; // eger koordinatak atranszformalva 1024*768-ra
 mrx,mry           : real;
 ms:real=0.04; // eger merete

 catchX,catchY     : integer;
 catchB            : boolean =false;
 catchOID          : integer;



//#########################################################################################################################################################################################################
implementation
//#########################################################################################################################################################################################################





// -----------------------------------------------------------------------------
// STANDARD gui FUNCTIONS ------------------------------------------------------
// -----------------------------------------------------------------------------
procedure GUIProcedureNothing(Sender:TGUIObject);
begin
end;


procedure setGUIaspectRatio;
 var a:real;
begin
 a := APPLICATION_HEIGHT / APPLICATION_WIDTH;
 GUI_WIDTH  := 1024; // default GUI screen size
 GUI_HEIGHT := 768;
 //if a = 0.75 then begin GUI_WIDTH  := 1024; GUI_HEIGHT := 768; end; This is the default so don't need chechk it. 4:3
 if a = 0.625 then begin GUI_WIDTH  := 1280; GUI_HEIGHT := 800; end; // wide 16:10
end;

procedure initGUI(windowHDC: HDC; wide:boolean);
begin
 setGUIaspectRatio;
 GUI_WIDE   := wide;
 GUI_OBJ_COUNT := 0;

 //defaultGUISYSfont.Build('Small Font',fw_Bold,true,0,windowHDC);
 //defaultGUIBMPfont.Build(12);

 defaultGUIfont.processData(EastwoodVector256);
 //defaultGUIfont.processData(EastwoodVector512);
 //defaultGUIfont.processData(TimesNewRomanVector256);


 LoadTexture('GUI.tga',GUITexture,true);

 LoadTexture('panel.tga',Panel_texture,true);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 LoadTexture('button.tga',GUIButtonTexture,true);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

 // eger textura betoltese (szuro beallitasa levagasra)
 LoadTexture('cursor_normal.tga',GUImouseTexture,true);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 LoadTexture('cursor2_normal.tga',GUImouseTexture2,true);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

 glBindTexture( GL_TEXTURE_2D, 0 );
end;

function screenToGLx(x: integer) : GLFloat;
begin
 result := (x - GUI_WIDTH/2   +25)*0.001078125;
end;

function screenToGLy(y: integer) : GLFloat;
begin
 result := -(y - GUI_HEIGHT/2 +17)*0.001078125;
end;

procedure DrawGUIMouse;
begin
 if (ml or mm or mr) then
  glBindTexture( GL_TEXTURE_2D, GUImouseTexture2 )
 else
  glBindTexture( GL_TEXTURE_2D, GUImouseTexture );


 mtx:=  round(mx *GUI_WIDTH/APPLICATION_WIDTH);
 mty:=  round(my *GUI_HEIGHT/APPLICATION_HEIGHT);

// mrx:=-0.551+(1.102/APPLICATION_WIDTH*mx);
 mrx :=  (mx - GUI_WIDTH/2  +25)*0.001078125;
 mry := -(my - GUI_HEIGHT/2 +17)*0.001078125;

 glColor4f(1,1,1,1);
 glBegin(GL_QUADS);
   glTexCoord2f(0, 0); glVertex2f(mrx   , mry-ms);
   glTexCoord2f(1, 0); glVertex2f(mrx+ms, mry-ms);
  	glTexCoord2f(1, 1); glVertex2f(mrx+ms, mry   );
   glTexCoord2f(0, 1); glVertex2f(mrx   , mry   );
 glend;

end;

procedure outtextxy(left,top:integer; text:string);
 var i:integer;
     row,col:integer;
     u,v,u1,v1,size,xx,yy:real;
     CurX:integer;
begin
  CurX := 0;
  size := 1000;

  xx :=  ((left)   - 512)*0.001078125;
  yy := -((top+defaultGUIfont.YOffset)    - 384)*0.001078125;
//  xx:=(left-522)*-(-0.552)/522;
//  yy:=(350-top)*(0.395)/358;

  glPushMatrix;
  glDepthFunc(GL_ALWAYS);
  glDisable(GL_DEPTH_TEST);

  glLoadIdentity();
  gluLookAt(0,0,1,0,0,0,0,1,0);

  glBindTexture( GL_TEXTURE_2D, defaultGUIfont.texid );
   glBegin(GL_QUADS);

    for i:=1 to length(text) do begin
      row:=(ord(text[i])-defaultGUIfont.Base) div defaultGUIfont.RowPitch;
      col:=(ord(text[i])-defaultGUIfont.Base)-Row*defaultGUIfont.RowPitch;

      U:=Col*defaultGUIfont.ColFactor;
      V:=Row*defaultGUIfont.RowFactor;
      U1:=U+defaultGUIfont.ColFactor;
      V1:=V+defaultGUIfont.RowFactor;

      glTexCoord2f(U, V1); glVertex2f((CurX)/size+xx,      yy);
      glTexCoord2f(U1,V1); glVertex2f((CurX+defaultGUIfont.CellX)/size+xx,yy);
      glTexCoord2f(U1,V ); glVertex2f((CurX+defaultGUIfont.CellX)/size+xx,yy+defaultGUIfont.YOffset/size);
      glTexCoord2f(U, V ); glVertex2f((CurX)/size+xx,      yy+defaultGUIfont.YOffset/size);

      CurX := CurX + defaultGUIfont.Width[ord(text[i])];
    end;

   glEnd();

  glDepthFunc(GL_LEQUAL);
  glEnable(GL_DEPTH_TEST);
  glPopMatrix;
end;



// -----------------------------------------------------------------------------
// FONTS  ----------------------------------------------------------------------
// -----------------------------------------------------------------------------

// TGUISysFont ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TGUISysFont.Build(fontName:string; FontWeights:integer; OutLine:Boolean; zWidth:real; window_dc:HDC);
var Font_: HFONT;
    i:integer;
begin
  font  := glGenLists(256);
  font_ := CreateFont(-14,
                      0,
                      0,
                      0,
                      FontWeights,
                      0,
                      0,
                      0,
                      ANSI_CHARSET,

                      OUT_TT_PRECIS,
                      CLIP_DEFAULT_PRECIS,
                      ANTIALIASED_QUALITY,

                      FF_DONTCARE or DEFAULT_PITCH,
                      PChar(fontName));

  SelectObject(window_dc,font_);

  if outLine then i:=0 else i:=1;
  wglUseFontOutlines(window_dc,
                      0,
                      255,
                      font,
                      0,
                      zWidth,
                      i,
                      @gmf);
end;

procedure TGUISysFont.Kill;
begin
 glDeleteLists(font,256);
end;


// TGUIBmpFont ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TGUIBmpFont.Build(fsize:byte);
 var cx, cy: GLfloat;
     loop  : GLUint;
begin
  self.size := fsize;
  font := glGenLists(256);
  for loop:=0 to 255 do
    begin
    cx := (loop mod 16) / 16;
    cy := (loop div 16) /16;
    glNewList(font + loop,GL_COMPILE);
      glBegin(GL_QUADS);
        glTexCoord2f(cx,1-cy-0.0625);         glVertex3f(0,0,               0);
        glTexCoord2f(cx+0.0625,1-cy-0.0625);  glVertex3f(fsize/500,0,        0);
        glTexCoord2f(cx+0.0625,1-cy);         glVertex3f(fsize/500,fsize/500, 0);
        glTexCoord2f(cx,1-cy);                glVertex3f(0,fsize/500,        0);
      glEnd;
      glTranslate(fsize / 380/2,0,0);
    glEndList;
    end;
end;

procedure TGUIBmpFont.Kill;
begin
 glDeleteLists(font,256);
end;


// TGUIBFFFont ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TGUIBFFont.processData(const dat: array of byte);
 const
  MAP_DATA_OFFSET = 276; // Offset to texture image data with BFF file
  WIDTH_DATA_OFFSET = 20;
  BFG_RS_NONE  =0;      // Blend flags
  BFG_RS_ALPHA =1;
  BFG_RS_RGB   =2;
  BFG_RS_RGBA  =4;

 var
  i:integer;
  img : array of byte;
  bpp:byte;
  imgx,imgy:integer;
  RenderStyle:integer;
begin
  // Grab the rest of the header
  CopyMemory( @imgX,@dat[2],SizeOf(Integer));
  CopyMemory( @imgY,@dat[6],SizeOf(Integer));
  CopyMemory( @cellX,@dat[10],SizeOf(Integer));
  CopyMemory( @cellY,@dat[14],SizeOf(Integer));

  bpp:=dat[18];
  Base:=dat[19];


  // Calculate font params
  RowPitch:=ImgX div CellX;
  ColFactor:=CellX/ImgX;
  RowFactor:=CellY/ImgY;
  YOffset:=CellY;

  // Determine blending options based on BPP
  case bpp of
   8:  RenderStyle := BFG_RS_ALPHA; // Greyscale
   24: RenderStyle := BFG_RS_RGB; // RGB
   32: RenderStyle := BFG_RS_RGBA;// RGBA
   else begin // Unsupported BPP
    exit;
   end;
  end;

  //showmessage(inttostr(imgx));
  // Allocate space for image
  setlength(img,(ImgX*ImgY)*(bpp div 8));
 //showmessage(inttostr(high(img)));

  // Grab char widths
  setlength(width,256);
  for i:=0 to 255 do
   width[i]:=dat[i+WIDTH_DATA_OFFSET];
  //CopyMemory( @width, @dat[WIDTH_DATA_OFFSET],2);


  // Grab image data
  for i:=0 to (ImgX*ImgY)*(bpp div 8)-1 do
   img[i] := dat[i+MAP_DATA_OFFSET];
//  CopyMemory( @img, @dat[MAP_DATA_OFFSET], (ImgX*ImgY)*(bpp div 8)-2);


  // Create Texture
  glGenTextures(1,TexID);

  glBindTexture(GL_TEXTURE_2D,TexID);
  // Fonts should be rendered at native resolution so no need for texture filtering
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  // Stop chararcters from bleeding over edges
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

  // Tex creation params are dependent on BPP
  case RenderStyle of
   BFG_RS_ALPHA : glTexImage2D( GL_TEXTURE_2D,0,GL_LUMINANCE,ImgX,ImgY,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,img);
   BFG_RS_RGB   : glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,ImgX,ImgY,0,GL_RGB,GL_UNSIGNED_BYTE,img);
   BFG_RS_RGBA  : glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ImgX,ImgY,0,GL_RGBA,GL_UNSIGNED_BYTE,img);
  end;

  //gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, ImgX, ImgY, GL_RGBA, GL_UNSIGNED_BYTE, img);

  // Clean up
  setlength(img,0);
end;


procedure TGUIBFFont.LoadFromFile(filename: string);
 var
  f:file;
  fsize : LongWord;
  NumRead: Integer;
  dat: array of byte;
begin
  AssignFile(f,filename);
  reset(f,1);

  // Get Filesize
  fsize := filesize(f);

  // allocate space for file data
  setlength(dat,fsize);

  // Read filedata
  BlockRead(f, PChar(dat)^, fsize, NumRead);

  closefile(f);


  // Check ID is 'BFF2'
  if (dat[0]<>191) or (dat[1]<>242) then begin
   setlength(dat,0);
   exit;
  end;


  processData(dat);

  setlength(dat,0);
end;

procedure TGUIBFFont.Kill;
begin
 setLength(width,0);
end;









//##########################################################################################
// GUI OBJECTS #############################################################################
//##########################################################################################

// -----------------------------------------------------------------------------
// SCREEN ----------------------------------------------------------------------
// -----------------------------------------------------------------------------
constructor TGUIscreen.Create;
begin
 wai      := 0;
 OID      := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);
 left     := 0;
 top      := 0;
 width    := APPLICATION_WIDTH;
 height   := APPLICATION_HEIGHT;
 right    := width;
 bottom   := height;
 cx       := width div 2;
 cy       := height div 2;
 r        := 0;
 g        := 0;
 b        := 0;
 a        := 1;
 visible  := true;
 clipping := false;
end;

procedure TGUIscreen.reSize;
begin
end;

procedure TGUIscreen.addChild(obj: PGUIObject);
begin
 if obj=nil then exit;
 setLength(child,high(child)+2);
 child[high(child)] := obj;
end;

procedure TGUIscreen.draw;
 var i:integer;
 const clip_plane1: array [0..3] of gldouble = (0,1,0,0.414);
 const clip_plane2: array [0..3] of gldouble = (1,0,0,0.552);
 const clip_plane3: array [0..3] of gldouble = (-1,0,0,0.552);
 const clip_plane4: array [0..3] of gldouble = (0,-1,0,0.414);
begin
 if not visible then exit;

 if clipping then begin
  glClipPlane( GL_CLIP_PLANE1,@clip_plane1);
  glClipPlane( GL_CLIP_PLANE2,@clip_plane2);
  glClipPlane( GL_CLIP_PLANE3,@clip_plane3);
  glClipPlane( GL_CLIP_PLANE4,@clip_plane4);
 end;

 glPushMatrix;

 if clipping then begin
  glEnable(GL_CLIP_PLANE1);
  glEnable(GL_CLIP_PLANE2);
  glEnable(GL_CLIP_PLANE3);
  glEnable(GL_CLIP_PLANE4);
 end;

 for i:=0 to high(child) do
  if child[i]<>nil then
   child[i].draw;

 if clipping then begin
  glDisable(GL_CLIP_PLANE1);
  glDisable(GL_CLIP_PLANE2);
  glDisable(GL_CLIP_PLANE3);
  glDisable(GL_CLIP_PLANE4);
 end;

 glPopMatrix;
end;



// -----------------------------------------------------------------------------
// PANEL -----------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUIpanel.Create;
begin
 create(0,0,80,80, 0,0,0,0.8, nil);
end;

Constructor TGUIpanel.Create(x1,y1,x2,y2:integer; parent:PGUIobject);
begin
 create(x1,y1,x2,y2, 0,0,0,0.8, nil);
end;

Constructor TGUIpanel.Create(x1,y1,x2,y2:integer; r,g,b,a:real; parent:PGUIobject);
 var c:integer;
begin
 wai     := 1;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 visible:=true;
 self.r:=r;
 self.g:=g;
 self.b:=b;
 self.a:=a;
 self.parent := parent;
 fr    := 1;
 fg    := 1;
 fb    := 1;
 custom_tile := 1;
 focusable := 0;
 header := false;
 closebutton := false;
 statusBar := false;
 onClose   := GUIProcedureNothing;

 showing := false;
 closing_anim := 0;
 transparentBorder := 0.2;

 shadowWidth := 5;
 shadowStrength := 0.9;

 if parent.wai = 0 then //ha screen szulte, akkor mozgathato, kulonben nem
  moveable:=true
 else
  moveable:=false;

 //meret beallitasok
 left:=x1;
 right:=x2;
 if left>right then begin
  c:=left; left:=right; right:=c;
 end;

 top:=y1;
 bottom:=y2;
 if top>bottom then begin
  c:=top; top:=bottom; bottom:=c;
 end;

 width:=right-left;
 height:=bottom-top;
 cx:=left+ width  div 2;
 cy:=top + height div 2;

 reSize;

 // TGUIScreen(parent^).addChild(addr(self));
end;

procedure TGUIpanel.reSize;
 var i:integer;
begin
 if GUI_WIDE then begin
  // 0.736 es 0.413 a 1280x720 as ablakbol szamitott ertek
  x1:=((left+parent.left)   - 512)*(1/512)*0.736;
  y1:=-((top+parent.top)    - 384)*(1/384)*0.414;
  x2:=((right+parent.left)  - 512)*(1/512)*0.736;
  y2:=-((bottom+parent.top) - 384)*(1/384)*0.414;
 end else begin
  // 0.551 es 0.413 a 640x480 as ablakbol szamitott ertek
  x1:=((left+parent.left)   - 512)*(1/512)*0.552;
  y1:=-((top+parent.top)    - 384)*(1/384)*0.414;
  x2:=((right+parent.left)  - 512)*(1/512)*0.552;
  y2:=-((bottom+parent.top) - 384)*(1/384)*0.414;
 end;

 //showmessage(inttostr(high(child)));
 for i:=0 to high(child) do
  if child[i]<>nil then
   child[i].reSize;
end;

function TGUIpanel.onMouse : Boolean;
// var i,px,py:integer;
  //   p:PGUIObject;
begin
 if (parent.wai = 1) then begin
  if TGUIPanel(parent^).header then begin
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+27)and(mty<top+height+parent.top+27) then
    result := true
   else
    result := false;
  end else
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+GUI_PANEL_BORDER_WIDTH)and(mty<top+height+parent.top+GUI_PANEL_BORDER_WIDTH) then
    result := true
   else
    result := false;
 end else begin
  if (mtx>left+parent.left)and(mtx<left+width+parent.left)and(mty>top+parent.top)and(mty<top+height+parent.top) then
   result := true
  else
   result := false;
 end;
end;


function TGUIpanel.front1 : Boolean; // az objektummal egy szinten levo objektumok kozul o van legfelul?
 var i,o,a:integer;
begin
 o:=0;
 result:=false;
 if parent.wai = 0 then begin
  for a:=0 to high(TGUIScreen(parent^).child) do // aktualis objektum megkeresese a szulo gyermekei kozott
    if TGUIScreen(parent^).child[a].OID = OID then break;
  for i:=0 to high(TGUIScreen(parent^).child) do // annak vizsgalata hogy van e folott masik objektum
   if (TGUIScreen(parent^).child[i].wai = 1)and(TGUIPanel(TGUIScreen(parent^).child[i]^).onMouse)
    then o:=i;
  if o<=a then result:=true else result:=false;
 end else if parent.wai = 1 then begin
  for a:=0 to high(TGUIPanel(parent^).child) do // aktualis objektum megkeresese a szulo gyermekei kozott
    if TGUIPanel(parent^).child[a].OID = OID then break;
  for i:=0 to high(TGUIPanel(parent^).child) do
   if (TGUIPanel(parent^).child[i].wai = 1)and(TGUIPanel(TGUIPanel(parent^).child[i]^).onMouse)
    then o:=i;
  if o<=a then result:=true else result:=false;
 end;
end;

function TGUIpanel.front2 : Boolean; // az objektum gyermek objektumai esetleg nem takarjak a kijelolest? ha nem takarjak akkor igaz
 var i:integer;
begin
 // mivel panel gyereke nem lehet screen ezert nem is vizsgaljuk!!!!!
 result:=true;

 for i:=0 to high(child) do begin
   if (child[i].wai = 1)and(TGUIPanel(child[i]^).visible)and((TGUIPanel(child[i]^).onMouse)or(not TGUIPanel(child[i]^).front2))
    then begin
     lastClicked := 1;
     result:=false;
     exit;
    end;
   if (child[i].wai = 2)and(TGUILabel(child[i]^).visible)and(TGUILabel(child[i]^).onMouse)and(TGUILabel(child[i]^).useAsButton)
    then begin
     lastClicked := 2;
     result:=false;
     exit;
    end;
   if (child[i].wai = 4)and(TGUIButton(child[i]^).visible)and((TGUIButton(child[i]^).onMouse))
    then begin
     lastClicked := 4;
     result:=false;
     exit;
    end;
   if (child[i].wai = 5)and(TGUITrackBar(child[i]^).visible)and((TGUITrackBar(child[i]^).onMouse))
    then begin
     lastClicked := 5;
     result:=false;
     exit;
    end;
 end;
end;

function TGUIpanel.front3 : Boolean; // az objektum gyermek objektumai esetleg nem takarjak a kijelolest? ha nem takarjak akkor igaz (itt csak a panel gyermekek lesznek megvizsgálva)
 var i:integer;
begin
 // mivel panel gyereke nem lehet screen ezert nem is vizsgaljuk!!!!!
 result:=true;

 for i:=0 to high(child) do begin
   if (child[i].wai = 1)and(TGUIPanel(child[i]^).visible)and((TGUIPanel(child[i]^).onMouse)or(not TGUIPanel(child[i]^).front2))
    then begin
     result:=false;
     exit;
    end;
 end;
end;

function TGUIpanel.onMouse2 : Boolean; // ha az egermutato alltal mutatott panel van felul akkor igaz
begin
 result:=false;
 if not onMouse then exit;
 if (front1)and(front2) then result:=true;
end;

function TGUIpanel.onMouse3 : Boolean; // ez a gyermek objektumoknak kell hogy van e fokusz. pl.: a TGUButton is ezt hasznalja annak megnezesere hogy o e az aktiv
begin
 result:=false;
 if not onMouse then exit;
 if (front1)and(front3) then result:=true;
end;

procedure TGUIpanel.bringToFront; // a panelt legfelulre viszi
 var obj:PGUIObject;
     i,o:integer;
begin
 if parent.wai = 0 then begin
  if (high(TGUIScreen(parent^).child)>0) then begin
   for i:=0 to high(TGUIScreen(parent^).child) do // a szulo gyermekei kozott megkeressuk az adott objektumot (az i-edik lesz az)
    if TGUIScreen(parent^).child[i].OID = OID then break;

   obj := TGUIScreen(parent^).child[i]; // rendezes
   for o:=i to high(TGUIScreen(parent^).child) do //-1
    TGUIScreen(parent^).child[o] := TGUIScreen(parent^).child[o+1];
   TGUIScreen(parent^).child[high(TGUIScreen(parent^).child)] := obj;
  end;
 end else if parent.wai = 1 then begin // ugyan az mint a fenti csak mas a tipuskenyszerites mivel itt TGUIpanellal dolgozunk
  if (high(TGUIPanel(parent^).child)>0) then begin
   for i:=0 to high(TGUIPanel(parent^).child) do
    if TGUIPanel(parent^).child[i].OID = OID then break;

   obj := TGUIPanel(parent^).child[i]; // rendezes
   for o:=i to high(TGUIPanel(parent^).child) do //-1
    TGUIPanel(parent^).child[o] := TGUIPanel(parent^).child[o+1];
   TGUIPanel(parent^).child[high(TGUIPanel(parent^).child)] := obj;
  end;
 end;
end;

function TGUIpanel.gX(x:integer) : single;
begin
 if (parent.wai = 1) then
  result := screenToGlx(left+parent.left+GUI_PANEL_BORDER_WIDTH+x)
 else
  result := screenToGlx(left+parent.left+x);
end;

function TGUIpanel.gY(y:integer) : single;
begin
 if (parent.wai = 1) then begin //ha a szulo panel es van header akkor a top lejebb kezdodik ezert a +27
  if TGUIPanel(parent^).header then
   result := screenToGly(top+parent.top+27+y)
  else
   result := screenToGly(top+parent.top+GUI_PANEL_BORDER_WIDTH+y)
 end else
  result := screenToGly(top+parent.top+y);
end;

function TGUIpanel.getRect : TRect;
 const
  borderWidth = 4;
begin
 result.Left := Left + borderWidth;
 if header then
  result.Top := Top -30- borderWidth
 else
  result.Top := Top- borderWidth;
end;

procedure TGUIpanel.outtext(alpha : real);
 var i:integer;
     row,col:integer;
     u,v,u1,v1,xx,yy:real;
     CurX:integer;
 const size = 900;
begin
  if caption='' then exit;
  if font.TexID=0 then font := defaultGUIfont;

  CurX := 0;


  xx:=gx(15);
  yy:=gy(24);


  glcolor4f(fr,fg,fb,alpha);
  glBindTexture( GL_TEXTURE_2D, font.texid );
   glBegin(GL_QUADS);

    for i:=1 to length(caption) do begin
      row:=(ord(caption[i])-font.Base) div font.RowPitch;
      col:=(ord(caption[i])-font.Base)-Row*font.RowPitch;

      U:=Col*font.ColFactor;
      V:=Row*font.RowFactor;
      U1:=U+font.ColFactor;
      V1:=V+font.RowFactor;

      glTexCoord2f(U, V1); glVertex2f((CurX)/size+xx,      yy);
      glTexCoord2f(U1,V1); glVertex2f((CurX+font.CellX)/size+xx,yy);
      glTexCoord2f(U1,V ); glVertex2f((CurX+font.CellX)/size+xx,yy+font.YOffset/size);
      glTexCoord2f(U, V ); glVertex2f((CurX)/size+xx,      yy+font.YOffset/size);

      CurX := CurX + font.Width[ord(caption[i])];
    end;

   glEnd();
end;

procedure TGUIPanel.hide;
 var i:integer;
begin
 if closing_anim=1 then begin
  closing_anim := 1;
  showing := false;
  for i:=0 to high(child) do
   child[i].hide;
 end;
end;

procedure TGUIPanel.show;
 var i:integer;
begin
 showing := true;
 closing_anim := 0;
 visible := true;
 for i:=0 to high(child) do
  child[i].show;
end;


procedure TGUIpanel.draw;
 var i:integer;
     alpha:real;
     activePanel : Boolean; // this variable help for you need to call onMouse2 method only once
     clip_plane1: array [0..3] of gldouble;
     shadowAlpha:real;
begin
 if not visible then exit;

 if parent.a<a then  alpha := parent.a else alpha := a;

 glPushMatrix;

 if (closing_anim<1)and(showing) then begin
  closing_anim := closing_anim + GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim >=1 then begin
   showing:=true;
   closing_anim := 1;
  end;
  //gltranslate(0,-0.5,0);
  //glrotate(-(1-closing_anim)*10,1,0,0);
  //gltranslate(0,0.5,0);
  glScale(0.9+closing_anim/10,0.9+closing_anim/10,1);
  alpha := a - (1-closing_anim);
 end;

 if (closing_anim>0)and(not showing) then begin
  closing_anim := closing_anim - GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim <= 0 then begin
   visible := false;
   closing_anim:=0;
   glPopMatrix;
   onClose(self);
   exit;
  end;
  //gltranslate(0,-0.5,0);
  //glrotate(-(1-closing_anim)*10,1,0,0);
  //gltranslate(0,0.5,0);
  glScale(0.9+closing_anim/10,0.9+closing_anim/10,1);
  alpha := a - (1-closing_anim);
 end;


 if (catchB) and (catchOID=OID) and (ml) then begin  //mozgatas lekezelese
     left:=mtx-catchX;
     top:=mty-catchY;
     right:=left+width;
     bottom:=top+height;
     resize;
    end;


 activePanel := onMouse2;
 if activePanel then begin
  if focusable>0 then
   glColor4f(r+focusable,g+focusable,b+focusable,alpha+focusable)
  else
   glColor4f(r,g,b,alpha);

  if ml then begin

   if (moveable)and(lastClicked=0) then begin
    bringToFront;

    if (not catchB) then begin
      catchB:=true;
      catchX:=mtx-left;
      catchY:=mty-top;
      catchOID := OID;
     end;
   end; //moveable

  end else begin
   if catchB then catchB:=false;
   lastClicked := 0;
  end;



 end else
  glColor4f(r,g,b,alpha);

 glBindTexture( GL_TEXTURE_2D, 0 );

 if alpha>0 then begin
 if Panel_texture=0 then begin // ha nincs textura akkor csak egy kocka
  glBegin(GL_QUADS);
   glVertex2f(x1, y1);
   glVertex2f(x1, y2);
   glVertex2f(x2, y2);
   glVertex2f(x2, y1);
  glEnd();
 end else begin // ha van textura akkor szetdarabolva





     // PANEL SHADOW____________________________________________________________
     if (shadowStrength>0)and(shadowWidth>0) then begin
      if closing_anim>0 then // calculate shadow alpha value
       shadowAlpha := shadowStrength*alpha*closing_anim
      else
       shadowAlpha := shadowStrength*alpha;
      glBindTexture( GL_TEXTURE_2D, 0 );
      glBegin(GL_QUADS); //shadow
         //top
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(3),               gy(3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(-shadowWidth),    gy(3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(-shadowWidth +8), gy(-shadowWidth));
         glcolor4f(0,0,0,0);           glVertex2f(gx(3),               gy(-shadowWidth));

         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(3),       gy(3));
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(width-3), gy(3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width-3), gy(-shadowWidth));
         glcolor4f(0,0,0,0);           glVertex2f(gx(3),       gy(-shadowWidth));

         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(width-3),              gy(3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width+shadowWidth),    gy(3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width+shadowWidth-8),  gy(-shadowWidth));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width-3),              gy(-shadowWidth));

         //left
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(3),            gy(3));
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(3),            gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(-shadowWidth), gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(-shadowWidth), gy(3));

         //right
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(width-3),           gy(3));
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(width-3),           gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width+shadowWidth), gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width+shadowWidth), gy(3));

         //bottom
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(3),               gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(-shadowWidth),    gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(-shadowWidth +8), gy(height+shadowWidth));
         glcolor4f(0,0,0,0);           glVertex2f(gx(3),               gy(height+shadowWidth));

         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(3),       gy(height-3));
         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(width-3), gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width-3), gy(height+shadowWidth));
         glcolor4f(0,0,0,0);           glVertex2f(gx(3),       gy(height+shadowWidth));

         glcolor4f(0,0,0,shadowAlpha); glVertex2f(gx(width-3),             gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width+shadowWidth),   gy(height-3));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width+shadowWidth-8), gy(height+shadowWidth));
         glcolor4f(0,0,0,0);           glVertex2f(gx(width-3),             gy(height+shadowWidth));
      glEnd;
     end; //shadow




     // PANEL PARTS_____________________________________________________________
     glcolor4f(r,g,b,alpha-transparentBorder);
     glBindTexture( GL_TEXTURE_2D, Panel_texture );
     glBegin(GL_QUADS);

        // top left corner of window.
        if header then begin
         glTexCoord2f( 0/128, 1);        glVertex2f(gx(0),  gy(0));
         glTexCoord2f( 0/128, 1-27/128); glVertex2f(gx(0),  gy(27));
         glTexCoord2f(64/128, 1-27/128); glVertex2f(gx(63), gy(27));
         glTexCoord2f(64/128, 1);        glVertex2f(gx(63), gy(0));
        end else begin
         glTexCoord2f(28/128, 59/128);   glVertex2f(gx(0),  gy(0));
         glTexCoord2f(28/128, 31/128);   glVertex2f(gx(0),  gy(27));
         glTexCoord2f(48/128, 31/128);   glVertex2f(gx(20), gy(27));
         glTexCoord2f(48/128, 59/128);   glVertex2f(gx(20), gy(0));
        end;

        // top of window.
        if header then begin
         glTexCoord2f(64/128, 1);        glVertex2f(gx(63),       gy(0));
         glTexCoord2f(64/128, 1-27/128); glVertex2f(gx(63),       gy(27));
         glTexCoord2f(96/128, 1-27/128); glVertex2f(gx(Width-32), gy(27));
         glTexCoord2f(96/128, 1);        glVertex2f(gx(Width-32), gy(0));
        end else begin
         glTexCoord2f(22/128, 59/128);   glVertex2f(gx(20),       gy(0));
         glTexCoord2f(22/128, 31/128);   glVertex2f(gx(20),       gy(27));
         glTexCoord2f(26/128, 31/128);   glVertex2f(gx(Width-20), gy(27));
         glTexCoord2f(26/128, 59/128);   glVertex2f(gx(Width-20), gy(0));
        end;

        // top right corner of window.
        if header then begin
         glTexCoord2f(96/128, 1);        glVertex2f(gx(Width-32), gy(0));
         glTexCoord2f(96/128, 1-27/128); glVertex2f(gx(Width-32), gy(27));
         glTexCoord2f(1, 1-27/128);      glVertex2f(gx(Width),    gy(27));
         glTexCoord2f(1, 1);             glVertex2f(gx(Width),    gy(0));
        end else begin
         glTexCoord2f(53/128, 59/128);   glVertex2f(gx(Width-20), gy(0));
         glTexCoord2f(53/128, 31/128);   glVertex2f(gx(Width-20), gy(27));
         glTexCoord2f(73/128, 31/128);   glVertex2f(gx(Width),    gy(27));
         glTexCoord2f(73/128, 59/128);   glVertex2f(gx(Width),    gy(0));
        end;


        // left side of window.
       (* if statusBar and header then begin
         glTexCoord2f(0/128, 1-27/128);  glVertex2f(gx(0), gy(27));
         glTexCoord2f(0/128, 27/128);    glVertex2f(gx(0), gy(Height-27));
         glTexCoord2f(7/128, 27/128);    glVertex2f(gx(7), gy(Height-27));
         glTexCoord2f(7/128, 1-27/128);  glVertex2f(gx(7), gy(27));
        end else begin*)
         glTexCoord2f(10/128, 58/128);   glVertex2f(gx(0), gy(27));
         glTexCoord2f(10/128, 50/128);   glVertex2f(gx(0), gy(Height-27));
         glTexCoord2f(15/128, 50/128);   glVertex2f(gx(5), gy(Height-27));
         glTexCoord2f(15/128, 58/128);   glVertex2f(gx(5), gy(27));
        //end;

        // right side of window.
        (*if statusBar and header then begin
         glTexCoord2f(1-7/128, 1-27/128);glVertex2f(gx(Width-7), gy(+27));
         glTexCoord2f(1-7/128, 27/128);  glVertex2f(gx(Width-7), gy(Height-27));
         glTexCoord2f(1,   27/128);      glVertex2f(gx(Width),   gy(Height-27));
         glTexCoord2f(1, 1-27/128);      glVertex2f(gx(Width),   gy(+27));
        end else begin*)
         glTexCoord2f(15/128, 58/128);   glVertex2f(gx(Width-5), gy(+27));
         glTexCoord2f(15/128, 50/128);   glVertex2f(gx(Width-5), gy(Height-27));
         glTexCoord2f(10/128, 58/128);   glVertex2f(gx(Width),   gy(Height-27));
         glTexCoord2f(10/128, 50/128);   glVertex2f(gx(Width),   gy(+27));
        //end;


        // bottom left corner of window.
        if statusBar then begin
         glTexCoord2f( 0/128, 27/128);   glVertex2f(gx(0),   gy(Height-27));
         glTexCoord2f( 0/128,  0/128);   glVertex2f(gx(0),   gy(+Height));
         glTexCoord2f(64/128,  0/128);   glVertex2f(gx(63),  gy(+Height));
         glTexCoord2f(64/128, 27/128);   glVertex2f(gx(63),  gy(Height-27));
        end else begin
         glTexCoord2f(74/128, 58/128);   glVertex2f(gx(0),   gy(Height-27));
         glTexCoord2f(74/128,  30/128);  glVertex2f(gx(0),   gy(+Height));
         glTexCoord2f(94/128,  30/128);  glVertex2f(gx(20),  gy(+Height));
         glTexCoord2f(94/128, 58/128);   glVertex2f(gx(20),  gy(Height-27));
        end;

        // bottom of window.
        if statusBar then begin
         glTexCoord2f(64/128, 27/128);   glVertex2f(gx(63),       gy(Height-27));
         glTexCoord2f(64/128, 0/128);    glVertex2f(gx(63),       gy(+Height));
         glTexCoord2f(96/128, 0/128);    glVertex2f(gx(Width-32), gy(+Height));
         glTexCoord2f(96/128, 27/128);   glVertex2f(gx(Width-32), gy(Height-27));
        end else begin
         glTexCoord2f(26/128, 31/128);   glVertex2f(gx(20),       gy(Height-27));
         glTexCoord2f(26/128, 59/128);   glVertex2f(gx(20),       gy(+Height));
         glTexCoord2f(22/128, 59/128);   glVertex2f(gx(Width-20), gy(+Height));
         glTexCoord2f(22/128, 31/128);   glVertex2f(gx(Width-20), gy(Height-27));
        end;

        // bottom right corner of window.
        if statusBar then begin
         glTexCoord2f(96/128, 27/128);   glVertex2f(gx(Width-32), gy(Height-27));
         glTexCoord2f(96/128, 0/128);    glVertex2f(gx(Width-32), gy(+Height));
         glTexCoord2f(1, 0/128);         glVertex2f(gx(Width),    gy(+Height));
         glTexCoord2f(1, 27/128);        glVertex2f(gx(Width),    gy(Height-27));
        end else begin
         glTexCoord2f(99/128, 58/128);   glVertex2f(gx(Width-20), gy(Height-27));
         glTexCoord2f(99/128, 30/128);   glVertex2f(gx(Width-20), gy(+Height));
         glTexCoord2f(119/128, 30/128);  glVertex2f(gx(Width),    gy(+Height));
         glTexCoord2f(119/128, 58/128);  glVertex2f(gx(Width),    gy(Height-27));
        end;


      glEnd();


  end; // texturazott kirajzolas vege
  end; // a>0



  // PANEL main body____________________________________________________________
      if custom_texture<>0 then begin // ha egyedi texturat rajzolunk ki
       glcolor4f(r,g,b,alpha);
       glBindTexture( GL_TEXTURE_2D, custom_texture );
       if (statusbar)and(header) then begin
        glBegin(gl_Quads);
         glTexCoord( 0, custom_tile);           glVertex2f(gx(5), gy(25));
         glTexCoord( 0, 0);                     glVertex2f(gx(5), gy(Height-25));
         glTexCoord( custom_tile, 0);           glVertex2f(gx(Width-5),gy(Height-25));
         glTexCoord( custom_tile, custom_tile); glVertex2f(gx(Width-5),gy(25));
        glEnd();
       end;
       if (not statusbar)and(not header) then begin
        glBegin(gl_Quads);
         glTexCoord( 0, custom_tile);           glVertex2f(gx(5), gy(5));
         glTexCoord( 0, 0);                     glVertex2f(gx(5), gy(Height-5));
         glTexCoord( custom_tile, 0);           glVertex2f(gx(Width-5),gy(Height-5));
         glTexCoord( custom_tile, custom_tile); glVertex2f(gx(Width-5),gy(5));
        glEnd();
       end;
       if (statusbar)and(not header) then begin
        glBegin(gl_Quads);
         glTexCoord( 0, custom_tile);           glVertex2f(gx(5), gy(5));
         glTexCoord( 0, 0);                     glVertex2f(gx(5), gy(Height-26));
         glTexCoord( custom_tile, 0);           glVertex2f(gx(Width-5),gy(Height-26));
         glTexCoord( custom_tile, custom_tile); glVertex2f(gx(Width-5),gy(5));
        glEnd();
       end;
       if (not statusbar)and(header) then begin
        glBegin(gl_Quads);
         glTexCoord( 0, custom_tile);           glVertex2f(gx(5), gy(26));
         glTexCoord( 0, 0);                     glVertex2f(gx(5), gy(Height-5));
         glTexCoord( custom_tile, 0);           glVertex2f(gx(Width-5),gy(Height-5));
         glTexCoord( custom_tile, custom_tile); glVertex2f(gx(Width-5),gy(26));
        glEnd();
       end;

      end else begin  // ha sima texturat rajzolunk ki
       glBindTexture( GL_TEXTURE_2D, Panel_texture );

       if (statusbar)and(header) then begin
        glBegin(gl_Quads);
         glTexCoord( 37/128, 41/128);     glVertex2f(gx(5), gy(27));
         glTexCoord( 37/128, 40/128);     glVertex2f(gx(5), gy(Height-26));
         glTexCoord(38/128, 40/128);      glVertex2f(gx(Width-5),gy(Height-26));
         glTexCoord(38/128, 41/128);      glVertex2f(gx(Width-5),gy(27));
        glEnd();
       end;
       if (not statusbar)and(not header) then begin
        glBegin(gl_Quads);
         glTexCoord( 37/128, 41/128);     glVertex2f(gx(5), gy(5));
         glTexCoord( 37/128, 40/128);     glVertex2f(gx(5), gy(Height-5));
         glTexCoord(38/128, 40/128);      glVertex2f(gx(Width-5),gy(Height-5));
         glTexCoord(38/128, 41/128);      glVertex2f(gx(Width-5),gy(5));
        glEnd();
       end;
       if (statusbar)and(not header) then begin
        glBegin(gl_Quads);
         glTexCoord( 37/128, 41/128);     glVertex2f(gx(5), gy(5));
         glTexCoord( 37/128, 40/128);     glVertex2f(gx(5), gy(Height-26));
         glTexCoord(38/128, 40/128);      glVertex2f(gx(Width-5),gy(Height-26));
         glTexCoord(38/128, 41/128);      glVertex2f(gx(Width-5),gy(5));
        glEnd();
       end;
       if (not statusbar)and(header) then begin
        glBegin(gl_Quads);
         glTexCoord(37/128, 41/128);     glVertex2f(gx(5),      gy(26));
         glTexCoord(37/128, 40/128);     glVertex2f(gx(5),      gy(Height-5));
         glTexCoord(38/128, 40/128);     glVertex2f(gx(Width-5),gy(Height-5));
         glTexCoord(38/128, 41/128);     glVertex2f(gx(Width-5),gy(26));
        glEnd();
       end;

      end;


 // CLOSE BUTTON________________________________________________________________
 if (alpha>0)and(Panel_texture<>0) then begin
        glcolor4f(r,g,b,alpha-transparentBorder);
        glBindTexture( GL_TEXTURE_2D, Panel_texture );
        glBegin(GL_QUADS);
        if closebutton then begin
         if ((parent.wai = 1)and(TGUIPanel(parent^).header)and(mtx>=left+parent.left+width-22)and(mtx<=left+parent.left+width-7)and // parent panel header offset
            (mty<=top+parent.top+23+27)and(mty>=top+parent.top+7+27)and(activePanel))
         or ((parent.wai = 1)and(not TGUIPanel(parent^).header)and(mtx>=left+parent.left+width-22)and(mtx<=left+parent.left+width-7)and // parent panel offset
            (mty<=top+parent.top+23+GUI_PANEL_BORDER_WIDTH)and(mty>=top+parent.top+7+GUI_PANEL_BORDER_WIDTH)and(activePanel))
         or ((parent.wai <>1)and(mtx>=left+parent.left+width-22)and(mtx<=left+parent.left+width-7)and
            (mty<=top+parent.top+23)and(mty>=top+parent.top+7)and(activePanel)) then begin
          hc := 0.7;
          //glow
          (* old = smaller glow
          glTexCoord2f(74/128, 95/128);  glVertex2f(gx(Width-38), gy(-8));
          glTexCoord2f(74/128, 67/128);  glVertex2f(gx(Width-38), gy(38));
          glTexCoord2f(103/128, 67/128);  glVertex2f(gx(Width+8),  gy(38));
          glTexCoord2f(103/128, 95/128);  glVertex2f(gx(Width+8),  gy(-8));*)
          glcolor4f(r,g,b,alpha-0.3);
          glTexCoord2f(74/128, 95/128);  glVertex2f(gx(Width-43), gy(-13));
          glTexCoord2f(74/128, 67/128);  glVertex2f(gx(Width-43), gy(43));
          glTexCoord2f(103/128, 67/128);  glVertex2f(gx(Width+13),  gy(43));
          glTexCoord2f(103/128, 95/128);  glVertex2f(gx(Width+13),  gy(-13));

          //button
          glcolor4f(r,g,b,alpha);
          glTexCoord2f(103/128, 80/128);  glVertex2f(gx(Width-22), gy(7));
          glTexCoord2f(103/128, 64/128);  glVertex2f(gx(Width-22), gy(23));
          glTexCoord2f(119/128, 64/128);  glVertex2f(gx(Width-7),  gy(23));
          glTexCoord2f(119/128, 80/128);  glVertex2f(gx(Width-7),  gy(7));

          if ml then hide;
         end else begin
          if hc>0 then begin
           glcolor4f(r,g,b,hc*alpha);
           hc := hc - GUI_ANIM_SPEED * TimeCorrection;
           //glow
           glTexCoord2f(74/128, 95/128);  glVertex2f(gx(Width-38), gy(-8));
           glTexCoord2f(74/128, 67/128);  glVertex2f(gx(Width-38), gy(38));
           glTexCoord2f(103/128, 67/128);  glVertex2f(gx(Width+8),  gy(38));
           glTexCoord2f(103/128, 95/128);  glVertex2f(gx(Width+8),  gy(-8));
          end;
           //button
           glcolor4f(r,g,b,hc*alpha);
           glTexCoord2f(103/128, 80/128);  glVertex2f(gx(Width-22), gy(7));
           glTexCoord2f(103/128, 64/128);  glVertex2f(gx(Width-22), gy(23));
           glTexCoord2f(119/128, 64/128);  glVertex2f(gx(Width-7),  gy(23));
           glTexCoord2f(119/128, 80/128);  glVertex2f(gx(Width-7),  gy(7));
           glcolor4f(r,g,b,(1-hc)*alpha);
           glTexCoord2f(103/128, 96/128);  glVertex2f(gx(Width-22), gy(7));
           glTexCoord2f(103/128, 80/128);  glVertex2f(gx(Width-22), gy(23));
           glTexCoord2f(119/128, 80/128);  glVertex2f(gx(Width-7),  gy(23));
           glTexCoord2f(119/128, 96/128);  glVertex2f(gx(Width-7),  gy(7));
         end;
        end;
        glEnd;
 end;



 outtext(alpha);
 for i:=0 to high(child) do child[i].draw;
 glPopMatrix;

//  const clip_plane1: array [0..3] of gldouble = (0,1,0,0.414);
 //clip_plane1[0]:=-1;
 //clip_plane1[1]:=0;
 //clip_plane1[2]:=0;
 //clip_plane1[3]:=gx(0);


                                 //vagosik nem joóu
 //glClipPlane( GL_CLIP_PLANE1,@clip_plane1);
 //glClipPlane( GL_CLIP_PLANE2,@clip_plane2);
 //glClipPlane( GL_CLIP_PLANE3,@clip_plane3);
 //glClipPlane( GL_CLIP_PLANE4,@clip_plane4);

 glPushMatrix;

 //glEnable(GL_CLIP_PLANE1);
 //glEnable(GL_CLIP_PLANE2);
 //glEnable(GL_CLIP_PLANE3);
 //glEnable(GL_CLIP_PLANE4);

 //outtextxy(0,100,format('%f',[gx(0)]));

 glDisable(GL_CLIP_PLANE1);
 glPopMatrix;

// showmessage(format('%f',[x1]));
end;

procedure TGUIpanel.addChild(obj: PGUIObject);
begin
 setLength(child,high(child)+2);
 child[high(child)] := obj;
end;




// -----------------------------------------------------------------------------
// SYSLABEL --------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUISysLabel.Create;
begin
 Create(0,0, 0.02,0.02, defaultGUISYSfont, text, 1,1,1,1, parent);
end;

Constructor TGUISysLabel.Create(left,top:integer; scaleX,scaleY:real; text:string; parent:PGUIobject);
begin
 Create(left,top, scaleX,scaleY, defaultGUISYSfont, text, 1,1,1,1, parent);
end;

Constructor TGUISysLabel.Create(left,top:integer; scaleX,scaleY:real; SYSfont:TGUISysFont; text:string; r,g,b,a:real; parent:PGUIobject);
begin
 wai     := 2;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 self.left   := left;
 self.top    := top;
 self.sx     := scaleX;
 self.sy     := scaleY;
 font        := defaultGUISYSfont;
 self.font   := SYSfont;
 self.text   := text;
 self.r      := r;
 self.g      := g;
 self.b      := b;
 self.a      := a;
 self.parent := parent;
 visible     := true;


 resize;
end;

procedure TGUISysLabel.resize;
begin
    (*
if GUI_WIDE then begin
  // 0.736 es 0.413 a 1280x720 as ablakbol szamitott ertek
  x1:=((left+parent.left)   - 512)*(1/512)*0.736;
  y1:=-((top+parent.top)    - 384)*(1/384)*0.414;
  x2:=((right+parent.left)  - 512)*(1/512)*0.736;
  y2:=-((bottom+parent.top) - 384)*(1/384)*0.414;
 end else begin
  // 0.551 es 0.413 a 640x480 as ablakbol szamitott ertek
  x1:=((left+parent.left)   - 512)*(1/512)*0.552;
  y1:=-((top+parent.top)    - 384)*(1/384)*0.414;
  x2:=((right+parent.left)  - 512)*(1/512)*0.552;
  y2:=-((bottom+parent.top) - 384)*(1/384)*0.414;
 end;
      *)

 // a szelesseg a 'W' betuhoz a magassag az 'É' betuhoz igazitott
 if GUI_WIDE then begin
  // -0.706 es -0.313 a 1280x720 as ablakbol szamitott ertek
  x:=(left+parent.left-492)*0.0014349593495934959349593495934959;
  y:=-0.313-top*0.0010768229166666666666666666666667;
 end else begin
  x:=(left+parent.left-485)*0.0010762886597938144329896907216495;
  y:=-0.313-(top+parent.top)*0.0010768229166666666666666666666667;
 end;

 // ez ahoz kell hogy a skalazas utan is megmaradjanak a bal felso sarok tenyleges ertekei
 x := x-0.0002857142857142857142857142857142 * (100-sx*100);
 y := y+0.0072653061224489795918367346938776 * (100-sy*100);
end;

procedure TGUISysLabel.draw;
// var
//  delka: glfloat;
//  loop: integer;
begin
  if (not visible)or(not parent.visible) then exit;
  if text = '' then exit;

  glPushMatrix;
  glBindTexture( GL_TEXTURE_2D, 0 );
  glcolor4f(r,g,b,a);
  glTranslatef( x,y,0);
  glscalef(sx,sy,0);
//  delka := 0;
//  for loop:=1 to length(text)-1 do delka := delka + gmf[loop].gmfCellIncX;
//  glTranslatef(-delka/2,0.0,0.0);
  glPushAttrib(GL_LIST_BIT);
  glListBase(font.Font);
  glCallLists(length(text),GL_UNSIGNED_BYTE,Pchar(text));
  glPopAttrib;
  glPopMatrix;
end;






// -----------------------------------------------------------------------------
// BMPLABEL --------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUIBmpLabel.Create;
begin
 create( 0,0,  defaultGUIBMPfont,0,  'label',  1,1,1,0.8,  nil);
end;

Constructor TGUIBmpLabel.Create(left,top:integer; texture:GLUint; text:string; parent:PGUIobject);
begin
 create(left,top,  defaultGUIBMPfont,texture,  text,  1,1,1,0.8,  parent);
end;

Constructor TGUIBmpLabel.Create(left,top:integer; font:TGUIBMPFont; texture:GLUint; text:string; r,g,b,a:real; parent:PGUIobject);
begin
 wai     := 3;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 self.left    := left;
 self.top     := top;
 self.font    := font;
 self.texture := texture;
 self.text    := text;
 self.r       := r;
 self.g       := g;
 self.b       := b;
 self.a       := a;
 visible      := true;
 self.parent  := parent;

 resize;
end;

procedure TGUIBmpLabel.resize;
begin
 if parent=nil then exit;
// left:= 5;
// top := 700;
 if GUI_WIDE then begin
  // 0.736 es 0.413 a 1280x720 as ablakbol szamitott ertek
  //x:=(left   - 512)*(1/512)*0.736;
  //y:=-(top    - 384)*(1/384)*0.414;
 end else begin
 //parent.top+
  x:=(left+parent.left-522)*-(-0.552- (font.size)*0.000288)/522;
  y:=(358-top-parent.top)*(0.395- (font.size)*0.001788)/358;
 end;
end;

procedure TGUIBmpLabel.draw;
begin
  if text = '' then exit;
  if (not visible)or(not parent.visible) then exit;

  glPushMatrix;
  glPushAttrib(GL_LIST_BIT);

  //if sada>1 then sada:=1;
  glBindTexture(GL_TEXTURE_2D,texture);
  glDisable(GL_DEPTH_TEST);

  glcolor4f(r,g,b,a);
  glTranslated(x,y,0);
  glListBase(font.Font-32+(128*0));
  glCallLists(length(text),GL_BYTE,Pchar(text));

  glEnable(GL_DEPTH_TEST);

  glPopAttrib;
  glPopMatrix;
end;





// -----------------------------------------------------------------------------
// BUTTON ----------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUIButton.Create;
begin
 Create(0,0,150,30,1,1,1,1,nil);
end;

Constructor TGUIButton.Create(x1,y1,x2,y2:integer; r,g,b,a:real; parent:PGUIObject);
 var c:integer;
begin
 wai     := 4;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 self.r       := r;
 self.g       := g;
 self.b       := b;
 self.a       := a;
 visible      := true;
 self.parent  := parent;
 text         := 'Button';
 onClick      := GUIProcedureNothing;
 MouseUp      := GUIProcedureNothing;
 MouseDown    := GUIProcedureNothing;
 morphi       := 0.01;
 font         := defaultGUIFont;

 fr           := 1;
 fg           := 1;
 fb           := 1;
 fa           := 1;

 fr2           := 1;
 fg2           := 1;
 fb2           := 0.5;
 fa2           := 1;

 heightModifier := 7;

 phase          :=0;
 morphi         :=1;


 showing := false;
 closing_anim := 0;

 //meret beallitasok
 left:=x1;
 right:=x2;
 if left>right then begin
  c:=left; left:=right; right:=c;
 end;

 top:=y1;
 bottom:=y2;
 if top>bottom then begin
  c:=top; top:=bottom; bottom:=c;
 end;

 width:=right-left;
 height:=bottom-top;
 cx:=left+ width  div 2;
 cy:=top + height div 2;

 reSize;
end;

function TGUIButton.gX(x:integer) : single;
begin
 if (parent.wai = 1) then
  result := screenToGlx(left+parent.left+GUI_PANEL_BORDER_WIDTH+x)
 else
  result := screenToGlx(left+parent.left+x);
end;

function TGUIButton.gY(y:integer) : single;
begin
 if (parent.wai = 1) then begin //ha a szulo panel es van header akkor a top lejebb kezdodik ezert a +27
  if TGUIPanel(parent^).header then
   result :=screenToGly(top+parent.top+27+y)
  else
   result :=screenToGly(top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1+y)
 end else
  result :=screenToGly(top+parent.top+y);
end;

procedure TGUIButton.reSize;
begin

 if parent = nil then exit;

 if GUI_WIDE then begin
  // 0.736 es 0.413 a 1280x720 as ablakbol szamitott ertek
  x1:=((left+parent.left)   - 512)*(1/512)*0.736;
  y1:=-((top+parent.top)    - 384)*(1/384)*0.414;
  x2:=((right+parent.left)  - 512)*(1/512)*0.736;
  y2:=-((bottom+parent.top) - 384)*(1/384)*0.414;
 end else begin
  // 0.551 es 0.413 a 640x480 as ablakbol szamitott ertek
  x1:=((left+parent.left)   - 512)*(1/512)*0.552;
  y1:=-((top+parent.top)    - 384)*(1/384)*0.414;
  x2:=((right+parent.left)  - 512)*(1/512)*0.552;
  y2:=-((bottom+parent.top) - 384)*(1/384)*0.414;
 end;
end;

function TGUIButton.onMouse : Boolean;
begin
 if (parent.wai = 1) then begin
  if TGUIPanel(parent^).header then begin
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+27)and(mty<top+height+parent.top+27) then
    result := true
   else
    result := false;
  end else
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1)and(mty<top+height+parent.top+GUI_PANEL_BORDER_WIDTH*2-1) then
    result := true
   else
    result := false;
 end else begin
  if (mtx>left+parent.left)and(mtx<left+width+parent.left)and(mty>top+parent.top)and(mty<top+height+parent.top) then
   result := true
  else
   result := false;
 end;
end;

procedure TGUIButton.outtext(alpha: real);
 var i:integer;
     row,col:integer;
     u,v,u1,v1,xx,yy:real;
     CurX:integer;
     w:integer;
 //const size = 1000;
     size : integer;
begin
  if ((phase=2)or(phase=3))and(ml) then
   size := 950
  else
   size := 1000;

  if text='' then exit;
  if font.TexID=0 then font := defaultGUIfont;

  CurX := 0;

  w:=0; // align to center
  for i:=1 to length(text) do
   w := w + font.Width[ord(text[i])];


  xx:=gx(abs(width div 2 - w div 2));//((left+parent.left-522  +(right-left)/2 )*(0.552)-w/2.7)/522;
  yy:=gy(height div 2 + 7);//((350-top-parent.top    -(bottom-top)/2)*(0.385))/353;


  if phase=4 then
      glcolor4f(fr*(1-morphi) + fr2*morphi,
                fg*(1-morphi) + fg2*morphi,
                fb*(1-morphi) + fb2*morphi,
               (fa*(1-morphi) + fa2*morphi)*alpha
               );
  if (phase=1)or(phase=0) then
      glcolor4f(fr*morphi + fr2*(1-morphi),
                fg*morphi + fg2*(1-morphi),
                fb*morphi + fb2*(1-morphi),
               (fa*morphi + fa2*(1-morphi))*alpha
               );
  if (phase=2)or(phase=3) then
   glcolor4f(fr2,fg2,fb2,fa2*alpha);


  glBindTexture( GL_TEXTURE_2D, font.texid );
   glBegin(GL_QUADS);

    for i:=1 to length(text) do begin
      row:=(ord(text[i])-font.Base) div font.RowPitch;
      col:=(ord(text[i])-font.Base)-Row*font.RowPitch;

      U:=Col*font.ColFactor;
      V:=Row*font.RowFactor;
      U1:=U+font.ColFactor;
      V1:=V+font.RowFactor;

      glTexCoord2f(U, V1); glVertex2f((CurX)/size+xx,      yy);
      glTexCoord2f(U1,V1); glVertex2f((CurX+font.CellX)/size+xx,yy);
      glTexCoord2f(U1,V ); glVertex2f((CurX+font.CellX)/size+xx,yy+font.YOffset/size);
      glTexCoord2f(U, V ); glVertex2f((CurX)/size+xx,      yy+font.YOffset/size);

      CurX := CurX + font.Width[ord(text[i])];
    end;

   glEnd();
end;

procedure TGUIButton.hide;
begin
 if closing_anim>=0 then begin
  closing_anim := 1;
  showing := false;
 end;
end;

procedure TGUIButton.show;
begin
 showing := true;
 closing_anim := 0;
 visible := true;
end;

procedure TGUIButton.draw;
 var
  alpha : real;
begin
 if not visible then exit;

 if parent.a<a then  alpha := parent.a else alpha := a;

 glPushMatrix;

 if (closing_anim<1)and(showing) then begin
  closing_anim := closing_anim + GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim>=1 then begin
   showing:=true;
   closing_anim := 1;
  end;
  alpha := a - (1-closing_anim);
 end;

 if (closing_anim>0)and(not showing) then begin
  closing_anim := closing_anim - GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim <= 0 then begin
   visible := false;
   closing_anim:=0;
   glPopMatrix;
   exit;
  end;
  alpha := a - (1-closing_anim);
 end;


 if parent.wai = 1 then  // fazisok kiosztasa pl.: eger rajta van gbal gomb lenyomva stb.
  if (TGUIPanel(parent^).onMouse3)and(onmouse) then begin
   if ml then begin
    phase:=2;
    clickOnce:=true;
    MouseDown(self);
   end else if (phase=2)or(phase=3) then begin
     phase:=3;
     if clickOnce then begin clickOnce:=false; onClick(self); end;
    end else begin
     phase:=1;
    end;
  end else begin // onmouse
   if (phase=2)or(phase=3) then phase:=4;
   if (phase=1)and(morphi<=0) then phase:=0;
   clickOnce:=true;
  end;


 if parent.wai = 0 then  // fazisok kiosztasa pl.: eger rajta van gbal gomb lenyomva stb.
  if (onmouse) then begin
   mouseDownOnce:=true;
   if mouseUpOnce then begin MouseUp(self); mouseUpOnce:=false; end;
   if ml then begin
    phase:=2;
    clickOnce:=true;
   end else if (phase=2)or(phase=3) then begin
     phase:=3;
     if clickOnce then begin clickOnce:=false; onClick(self); end;
    end else begin
     phase:=1;
    end;
  end else begin // onmouse
   if (phase=2)or(phase=3) then phase:=4;
   if (phase=1)and(morphi<=0) then phase:=0;
   mouseUpOnce:=true;
   if mouseDownOnce then begin MouseDown(self); mouseDownOnce:=false; end;
  end;


 glBindTexture( GL_TEXTURE_2D, GUIButtonTexture );

// if (phase=0)and(morphi>0) then morphi:=morphi- GUI_ANIM_SPEED*TimeCorrection;

 if (phase=0)and(morphi<1) then morphi:=morphi+ GUI_ANIM_SPEED*TimeCorrection;
 if (phase=1)and(morphi>0) then morphi:=morphi- GUI_ANIM_SPEED*4*TimeCorrection;
 if (phase=2)and(morphi<1) then morphi:=morphi+ GUI_ANIM_SPEED*5*TimeCorrection;
 if (phase=3)and(morphi>0) then morphi:=morphi- GUI_ANIM_SPEED*TimeCorrection;
 if (phase=4)and(morphi>0) then morphi:=morphi- GUI_ANIM_SPEED*0.5*TimeCorrection;


 if phase<2 then begin
  // normal allapot
  //if morphi>0 then begin
   glColor4f(r,g,b,1*alpha);
   glBegin(gl_Quads);
    glTexCoord( 0/128,  128/128);     glVertex2f(gx(0), gy(-heightModifier));
    glTexCoord( 0/128,  86/128 );     glVertex2f(gx(0), gy(Height+heightModifier));
    glTexCoord( 20/128, 86/128 );     glVertex2f(gx(20),gy(Height+heightModifier));
    glTexCoord( 20/128, 128/128);     glVertex2f(gx(20),gy(-heightModifier));


    glTexCoord( 20/128,  128/128);    glVertex2f(gx(20), gy(-heightModifier));
    glTexCoord( 20/128,  86/128 );    glVertex2f(gx(20), gy(Height+heightModifier));
    glTexCoord( 108/128, 86/128 );    glVertex2f(gx(width-20),gy(Height+heightModifier));
    glTexCoord( 108/128, 128/128);    glVertex2f(gx(width-20),gy(-heightModifier));

    glTexCoord( 108/128, 128/128);    glVertex2f(gx(width-20), gy(-heightModifier));
    glTexCoord( 108/128, 86/128 );    glVertex2f(gx(width-20), gy(Height+heightModifier));
    glTexCoord( 128/128, 86/128 );    glVertex2f(gx(width),gy(Height+heightModifier));
    glTexCoord( 128/128, 128/128);    glVertex2f(gx(width),gy(-heightModifier));
   glEnd();
  //end;

  glColor4f(r,g,b,(1-morphi)*alpha);
  // on mouse
  glBegin(gl_Quads);
   glTexCoord( 0/128,  86/128);     glVertex2f(gx(0), gy(-heightModifier));
   glTexCoord( 0/128,  44/128);     glVertex2f(gx(0), gy(Height+heightModifier));
   glTexCoord( 20/128, 44/128);     glVertex2f(gx(20),gy(Height+heightModifier));
   glTexCoord( 20/128, 86/128);     glVertex2f(gx(20),gy(-heightModifier));

   glTexCoord( 20/128,  86/128);    glVertex2f(gx(20), gy(-heightModifier));
   glTexCoord( 20/128,  44/128);    glVertex2f(gx(20), gy(Height+heightModifier));
   glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20),gy(Height+heightModifier));
   glTexCoord( 108/128, 86/128);    glVertex2f(gx(width-20),gy(-heightModifier));

   glTexCoord( 108/128, 86/128);    glVertex2f(gx(width-20), gy(-heightModifier));
   glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20), gy(Height+heightModifier));
   glTexCoord( 128/128, 44/128);    glVertex2f(gx(width),gy(Height+heightModifier));
   glTexCoord( 128/128, 86/128);    glVertex2f(gx(width),gy(-heightModifier));
  glEnd();
 end else begin
 if phase = 4 then begin
  // click
  if morphi>0 then begin
   glColor4f(r,g,b,1*alpha);
   glBegin(gl_Quads);
    glTexCoord( 0/128,  44/128);     glVertex2f(gx(0), gy(-heightModifier));
    glTexCoord( 0/128,  0/128);     glVertex2f(gx(0), gy(Height+heightModifier));
    glTexCoord( 20/128, 0/128);     glVertex2f(gx(20),gy(Height+heightModifier));
    glTexCoord( 20/128, 44/128);     glVertex2f(gx(20),gy(-heightModifier));

    glTexCoord( 20/128,  44/128);    glVertex2f(gx(20), gy(-heightModifier));
    glTexCoord( 20/128,  0/128);    glVertex2f(gx(20), gy(Height+heightModifier));
    glTexCoord( 108/128, 0/128);    glVertex2f(gx(width-20),gy(Height+heightModifier));
    glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20),gy(-heightModifier));

    glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20), gy(-heightModifier));
    glTexCoord( 108/128, 0/128);    glVertex2f(gx(width-20), gy(Height+heightModifier));
    glTexCoord( 128/128, 0/128);    glVertex2f(gx(width),gy(Height+heightModifier));
    glTexCoord( 128/128, 44/128);    glVertex2f(gx(width),gy(-heightModifier));
   glEnd();
  end;

  glColor4f(r,g,b,(1-morphi)*alpha);
  glBegin(gl_Quads);
   glTexCoord( 0/128,  128/128);     glVertex2f(gx(0), gy(-heightModifier));
   glTexCoord( 0/128,  86/128 );     glVertex2f(gx(0), gy(Height+heightModifier));
   glTexCoord( 20/128, 86/128 );     glVertex2f(gx(20),gy(Height+heightModifier));
   glTexCoord( 20/128, 128/128);     glVertex2f(gx(20),gy(-heightModifier));


   glTexCoord( 20/128,  128/128);    glVertex2f(gx(20), gy(-heightModifier));
   glTexCoord( 20/128,  86/128 );    glVertex2f(gx(20), gy(Height+heightModifier));
   glTexCoord( 108/128, 86/128 );    glVertex2f(gx(width-20),gy(Height+heightModifier));
   glTexCoord( 108/128, 128/128);    glVertex2f(gx(width-20),gy(-heightModifier));

   glTexCoord( 108/128, 128/128);    glVertex2f(gx(width-20), gy(-heightModifier));
   glTexCoord( 108/128, 86/128 );    glVertex2f(gx(width-20), gy(Height+heightModifier));
   glTexCoord( 128/128, 86/128 );    glVertex2f(gx(width),gy(Height+heightModifier));
   glTexCoord( 128/128, 128/128);    glVertex2f(gx(width),gy(-heightModifier));
  glEnd();
 end else begin
  // click
  glColor4f(r,g,b,1*alpha);
  glBegin(gl_Quads);
   glTexCoord( 0/128,  44/128);     glVertex2f(gx(0), gy(-heightModifier));
   glTexCoord( 0/128,  0/128);     glVertex2f(gx(0), gy(Height+heightModifier));
   glTexCoord( 20/128, 0/128);     glVertex2f(gx(20),gy(Height+heightModifier));
   glTexCoord( 20/128, 44/128);     glVertex2f(gx(20),gy(-heightModifier));

   glTexCoord( 20/128,  44/128);    glVertex2f(gx(20), gy(-heightModifier));
   glTexCoord( 20/128,  0/128);    glVertex2f(gx(20), gy(Height+heightModifier));
   glTexCoord( 108/128, 0/128);    glVertex2f(gx(width-20),gy(Height+heightModifier));
   glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20),gy(-heightModifier));

   glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20), gy(-heightModifier));
   glTexCoord( 108/128, 0/128);    glVertex2f(gx(width-20), gy(Height+heightModifier));
   glTexCoord( 128/128, 0/128);    glVertex2f(gx(width),gy(Height+heightModifier));
   glTexCoord( 128/128, 44/128);    glVertex2f(gx(width),gy(-heightModifier));
  glEnd();

  glColor4f(r,g,b,(1-morphi)*alpha);
  glBegin(gl_Quads);
   glTexCoord( 0/128,  86/128);     glVertex2f(gx(0), gy(-heightModifier));
   glTexCoord( 0/128,  44/128);     glVertex2f(gx(0), gy(Height+heightModifier));
   glTexCoord( 20/128, 44/128);     glVertex2f(gx(20),gy(Height+heightModifier));
   glTexCoord( 20/128, 86/128);     glVertex2f(gx(20),gy(-heightModifier));

   glTexCoord( 20/128,  86/128);    glVertex2f(gx(20), gy(-heightModifier));
   glTexCoord( 20/128,  44/128);    glVertex2f(gx(20), gy(Height+heightModifier));
   glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20),gy(Height+heightModifier));
   glTexCoord( 108/128, 86/128);    glVertex2f(gx(width-20),gy(-heightModifier));

   glTexCoord( 108/128, 86/128);    glVertex2f(gx(width-20), gy(-heightModifier));
   glTexCoord( 108/128, 44/128);    glVertex2f(gx(width-20), gy(Height+heightModifier));
   glTexCoord( 128/128, 44/128);    glVertex2f(gx(width),gy(Height+heightModifier));
   glTexCoord( 128/128, 86/128);    glVertex2f(gx(width),gy(-heightModifier));
  glEnd();
 end;
 end;

 outtext(alpha); // szoveg kiiratas
 glPopMatrix;
end;


// -----------------------------------------------------------------------------
// LABEL -----------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUILabel.create;
begin
 Create(0,0,defaultGUIfont,'GUILABEL',1,1,1,1,parent);
end;

Constructor TGUILabel.Create(left,top:integer; text:string; parent:PGUIobject);
begin
 Create(left,top,defaultGUIfont,text,1,1,1,1,parent);
end;

Constructor TGUILabel.Create(left,top:integer; text:string; r,g,b,a:real; parent:PGUIobject);
begin
 Create(left,top,defaultGUIfont,text,r,g,b,a,parent);
end;

Constructor TGUILabel.Create(left,top:integer; font:TGUIBFFont; text:string; r,g,b,a:real; parent:PGUIobject);
begin
 wai     := 2;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 self.left   := left;
 self.top    := top;
 self.font   := font;
 self.text   := text;
 self.r      := r;
 self.g      := g;
 self.b      := b;
 self.a      := a;
 self.parent := parent;
 visible     := true;

 fr          := 1;
 fg          := 1;
 fb          := 1;
 fa          := 1;

 fr2         := 1;
 fg2         := 1;
 fb2         := 0.5;
 fa2         := 1;

 fsize       := 23;

 width       := getWidth;
 height      := getHeight;

 morphi      := 1;

 showing := false;
 closing_anim := 0;

 onClick      := GUIProcedureNothing;
 MouseUp      := GUIProcedureNothing;
 MouseDown    := GUIProcedureNothing;

 resize;

 //que;
end;

procedure TGUILabel.hide;
begin
 if closing_anim>=0 then begin
  closing_anim := 1;
  showing := false;
 end;
end;

procedure TGUILabel.show;
begin
 showing := true;
 closing_anim := 0;
 visible := true;
end;

procedure TGUILabel.reSize;
// var s:real;
begin
(*
  //x:=(left+parent.left-522)*-(-0.552- (font.size)*0.000288)/522;
  //y:=(358-top-parent.top)*(0.395- (font.size)*0.001788)/358;

  size:=120;
//  s:=(1300-size*5);

  x:=(left+parent.left-522)*-(-0.552- 0.000288)/522;
  y:=(345-top-parent.top)*(0.395- 0.001788)/358;


  x:=(left+parent.left-522)*-(-0.552- 0.000288)/522;


  width  := getWidth;
  (*
  width := round(tr*-(-0.552- 0.000288)/522+getwidth);
  showmessage(format('%f',[tr /-(-0.552- 0.000288)/522]));
  height := round(font.YOffset div 2 +size / 5 );*)
                                   (*
  right  := left + width;
  bottom := top + height;

  cx     := left + width div 2;
  cy     := top  + height div 2;  *)
end;


function TGUILabel.gX(x:integer) : single;
begin
 if (parent.wai = 1) then
  result := screenToGlx(left+parent.left+GUI_PANEL_BORDER_WIDTH+x)
 else
  result := screenToGlx(left+parent.left+x);
end;

function TGUILabel.gY(y:integer) : single;
begin
 if (parent.wai = 1) then begin //ha a szulo panel es van header akkor a top lejebb kezdodik ezert a +27
  if TGUIPanel(parent^).header then
   result := screenToGly(top+parent.top+22+y)
  else
   result := screenToGly(top+parent.top+y)
 end else
  result := screenToGly(top+parent.top+y);
end;


procedure TGUILabel.draw;
 var i:integer;
     row,col:integer;
     u,v,u1,v1,xx,yy:real;
     CurX:integer;
     w:integer;
     alpha:real;
     size : byte;
begin
  if text='' then exit;
  if not visible then exit;
  if font.TexID=0 then font := defaultGUIfont;

  if parent.a<a then  alpha := parent.a else alpha := a;

 glPushMatrix;

 if (closing_anim<1)and(showing) then begin
  closing_anim := closing_anim + GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim>=1 then begin
   showing:=true;
   closing_anim := 1;
  end;
  alpha := a - (1-closing_anim);
 end;

 if (closing_anim>0)and(not showing) then begin
  closing_anim := closing_anim - GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim <= 0 then begin
   visible := false;
   closing_anim:=0;
   glPopMatrix;
   exit;
  end;
  alpha := a - (1-closing_anim);
 end;





  size:=fsize;
  if useAsButton then begin
   if (onmouse) then begin
      phase:=1;
      if mouseUpOnce then begin MouseUp(self); mouseUpOnce:=false; end;
      if ml then begin
       size := size+1;
       MouseDown(self);
       clickOnce:=true;
      end else
       if clickOnce then begin clickOnce:=false; onClick(self); end;
   end else begin
      phase:=2;
      clickOnce:=false;
      mouseUpOnce:=true;
   end;

   if (phase=1)and(morphi>0) then morphi:=morphi- GUI_ANIM_SPEED*20*TimeCorrection;
   if (phase=2)and(morphi<1) then morphi:=morphi+ GUI_ANIM_SPEED*5*TimeCorrection;
  end;



  if (useAsButton)and(morphi<1) then begin
    CurX := 0;
    glcolor4f(fr,fg,fb,alpha-morphi);
    glcolor4f(1,1,1,1);
    glcolor4f(0,0,0,1-morphi);
    glBegin(GL_QUADS);
    for i:=1 to length(text) do begin
      row:=(ord(text[i])-font.Base) div font.RowPitch;
      col:=(ord(text[i])-font.Base)-Row*font.RowPitch;

      U:=Col*font.ColFactor;
      V:=Row*font.RowFactor;
      U1:=U+font.ColFactor;
      V1:=V+font.RowFactor;

      glTexCoord2f(U, V1); glVertex2f(gx(round(CurX * size/25)+1-3),              gy(size-5+3));
      glTexCoord2f(U1,V1); glVertex2f(gx(round((CurX+font.CellX) * size/25)+1+3), gy(size-5+3));
      glTexCoord2f(U1,V ); glVertex2f(gx(round((CurX+font.CellX) * size/25)+1+3), gy(1-3));
      glTexCoord2f(U, V ); glVertex2f(gx(round(CurX * size/25)+1-3),              gy(1-3));

      CurX := CurX + font.Width[ord(text[i])];
    end;
    glEnd();
  end;


            (*
  CurX := 0;
    glcolor4f(fr,fg,fb,alpha-morphi);
    glBegin(GL_QUADS);
    for i:=1 to length(text) do begin
      row:=(ord(text[i])-font.Base) div font.RowPitch;
      col:=(ord(text[i])-font.Base)-Row*font.RowPitch;

      U:=Col*font.ColFactor;
      V:=Row*font.RowFactor;
      U1:=U+font.ColFactor;
      V1:=V+font.RowFactor;

      glTexCoord2f(U, V1); glVertex2f(gx(round(CurX * size/25)-8),              gy(size+2));
      glTexCoord2f(U1,V1); glVertex2f(gx(round((CurX+font.CellX) * size/25)+25), gy(size+2));
      glTexCoord2f(U1,V ); glVertex2f(gx(round((CurX+font.CellX) * size/25)+25), gy(-8));
      glTexCoord2f(U, V ); glVertex2f(gx(round(CurX * size/25)-8),              gy(-8));

      CurX := CurX + font.Width[ord(text[i])];
    end;
    glEnd();     *)




  if useAsButton then
     glcolor4f(fr*morphi + fr2*(1-morphi),
                fg*morphi + fg2*(1-morphi),
                fb*morphi + fb2*(1-morphi),
               (fa*morphi + fa2*(1-morphi))*alpha
               )
  else
   glcolor4f(fr,fg,fb,alpha);

  CurX := 0;
  glBindTexture( GL_TEXTURE_2D, font.texid );
   glBegin(GL_QUADS);
    for i:=1 to length(text) do begin
      row:=(ord(text[i])-font.Base) div font.RowPitch;
      col:=(ord(text[i])-font.Base)-Row*font.RowPitch;

      U:=Col*font.ColFactor;
      V:=Row*font.RowFactor;
      U1:=U+font.ColFactor;
      V1:=V+font.RowFactor;

      glTexCoord2f(U, V1); glVertex2f(gx(round(CurX * size/25)+1),              gy(size-5));
      glTexCoord2f(U1,V1); glVertex2f(gx(round((CurX+font.CellX) * size/25)+1), gy(size-5));
      glTexCoord2f(U1,V ); glVertex2f(gx(round((CurX+font.CellX) * size/25)+1), gy(1));
      glTexCoord2f(U, V ); glVertex2f(gx(round(CurX * size/25)+1),              gy(1));

      CurX := CurX + font.Width[ord(text[i])];
    end;
    glEnd();






  glPopMatrix;
end;



function TGUILabel.getWidth : integer;
 var i:integer;
begin
 result := 0;
 for i:=1 to length(text) do
  result := result + font.Width[ord(text[i])];
 result := Round(result * fsize/25);
end;

function TGUILabel.getHeight : integer;
begin
 result := fsize-10;
end;

function TGUILabel.onMouse : Boolean;
 var height,width:integer;
begin
 width := getWidth;
 height := getHeight;
 if (parent.wai = 1) then begin
  if TGUIPanel(parent^).header then begin
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+27)and(mty<top+height+parent.top+27) then
    result := true
   else
    result := false;
  end else
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1)and(mty<top+height+parent.top+GUI_PANEL_BORDER_WIDTH*2-1) then
    result := true
   else
    result := false;
 end else begin
  if (mtx>left+parent.left)and(mtx<left+width+parent.left)and(mty>top+parent.top)and(mty<top+height+parent.top) then
   result := true
  else
   result := false;
 end;
end;








procedure que(o: TGUIObject);
 var t:TGUILabel;
begin
 if o.wai=2 then if TGUILabel(o).parent.wai=1 then begin
  showmessage(TGUIPanel(TGUILabel(o).parent^).caption );
  t:=TGUILabel(o);
  TGUIPanel(TGUILabel(o).parent^).addChild(@t);
 end;
 //showmessage(inttostr(p.wai));
// case TGUIObject(p).wai of
//  1: showmessage('fs');//TGUIPanel(p^).addChild(p);
// end;
end;









// -----------------------------------------------------------------------------
// TrackBar --------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUITrackBar.create;
begin
 Create(0,0,150,0,100,0,1,1,1,1,nil);
end;

Constructor TGUITrackBar.Create(left,top,width:integer; parent:PGUIobject);
begin
 Create(left,top,width,0,100,0,1,1,1,1,parent);
end;

Constructor TGUITrackBar.Create(left,top,width:integer; min,max,position:integer; parent:PGUIobject);
begin
 Create(left,top,width,min,max,position,1,1,1,1,parent);
end;

Constructor TGUITrackBar.Create(left,top,width:integer; min,max,position:integer; r,g,b,a:real; parent:PGUIobject);
begin
 wai     := 5;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 self.r       := r;
 self.g       := g;
 self.b       := b;
 self.a       := a;
 visible      := true;
 self.parent  := parent;
 onChange     := GUIProcedureNothing;
 MouseDown    := GUIProcedureNothing;

 lr           := 1;
 lg           := 1;
 lb           := 0;
 la           := 1;

 br           := 1;
 bg           := 1;
 bb           := 1;
 ba           := 1;

 self.min      := min;
 self.max      := max;
 self.position := position;

 style         := 0;

 showing := false;
 closing_anim := 0;

 //meret beallitasok
 self.left   := left;
 self.width  := width;
 self.right  := left+width;

 self.top    := top;
 height      := 10;
 self.bottom := top+height;


 width:=right-left;
 height:=bottom-top;
 cx:=left+ width  div 2;
 cy:=top + height div 2;
end;


function TGUITrackBar.gX(x:integer) : single;
begin
 if (parent.wai = 1) then
  result := screenToGlx(left+parent.left+GUI_PANEL_BORDER_WIDTH+x)
 else
  result := screenToGlx(left+parent.left+x)
end;

function TGUITrackBar.gY(y:integer) : single;
begin
 if (parent.wai = 1) then begin //ha a szulo panel es van header akkor a top lejebb kezdodik ezert a +27
  if TGUIPanel(parent^).header then
   result := screenToGly(top+parent.top+27+y)
  else
   result := screenToGly(top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1+y)
 end else
  result := screenToGly(top+parent.top+y);
end;

function TGUITrackBar.onMouse : Boolean;
begin
 if (parent.wai = 1) then begin
  if TGUIPanel(parent^).header then begin
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+27-5)and(mty<top+height+parent.top+27+5) then
    result := true
   else
    result := false;
  end else
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1-5)and(mty<top+height+parent.top+GUI_PANEL_BORDER_WIDTH*2-1+5) then
    result := true
   else
    result := false;
 end else begin
  if (mtx>left+parent.left)and(mtx<left+width+parent.left)and(mty>top+parent.top-5)and(mty<top+height+parent.top+5) then
   result := true
  else
   result := false;
 end;
end;

procedure TGUITrackBar.hide;
begin
 if closing_anim>=0 then begin
  closing_anim := 1;
  showing := false;
 end;
end;

procedure TGUITrackBar.show;
begin
 showing := true;
 closing_anim := 0;
 visible := true;
end;

procedure TGUITrackBar.draw;
var
  alpha : real;
  w : integer;
begin
 if not visible then exit;

 if parent.a<a then  alpha := parent.a else alpha := a;

 glPushMatrix;

 if (closing_anim<1)and(showing) then begin
  closing_anim := closing_anim + GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim>=1 then begin
   showing:=true;
   closing_anim := 1;
  end;
  alpha := a - (1-closing_anim);
 end;

 if (closing_anim>0)and(not showing) then begin
  closing_anim := closing_anim - GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim <= 0 then begin
   visible := false;
   closing_anim:=0;
   glPopMatrix;
   exit;
  end;
  alpha := a - (1-closing_anim);
 end;


 glBindTexture( GL_TEXTURE_2D, GUITexture );
 glColor4f(r,g,b,1*alpha);
 glBegin(gl_Quads);
  glTexCoord( 1/256, 109/256);     glVertex2f(gx(0),       gy(0));
  glTexCoord( 1/256, 101/256);     glVertex2f(gx(0),       gy(Height));
  glTexCoord( 5/256, 101/256);     glVertex2f(gx(5),       gy(Height));
  glTexCoord( 5/256, 109/256);     glVertex2f(gx(5),       gy(0));

  glTexCoord( 6/256,  109/256);    glVertex2f(gx(5),       gy(0));
  glTexCoord( 6/256,  101/256);    glVertex2f(gx(5),       gy(Height));
  glTexCoord( 90/256, 101/256);    glVertex2f(gx(width-5), gy(Height));
  glTexCoord( 90/256, 109/256);    glVertex2f(gx(width-5), gy(0));

  glTexCoord( 91/256, 109/256);    glVertex2f(gx(width-5), gy(0));
  glTexCoord( 91/256, 101/256);    glVertex2f(gx(width-5), gy(Height));
  glTexCoord( 95/256, 101/256);    glVertex2f(gx(width),   gy(Height));
  glTexCoord( 95/256, 109/256);    glVertex2f(gx(width),   gy(0));
 glEnd();


 if position >  max then position := max;
 if position <  min then position := min;
 if position >= min then begin
  w := round( width/(max-min)*(position-min));
  if w>width-2 then w := width-2;
  if w<3       then w := 3;

  //LINE
  if (style=0)or(style=2) then begin
   glColor4f(lr,lg,lb,1*alpha);
   glBegin(gl_Quads);
    glTexCoord( 6/256,  100/256);    glVertex2f(gx(3), gy(0));
    glTexCoord( 6/256,  92/256);     glVertex2f(gx(3), gy(Height));
    glTexCoord( 90/256, 92/256);     glVertex2f(gx(w), gy(Height));
    glTexCoord( 90/256, 100/256);    glVertex2f(gx(w), gy(0));
   glEnd();
  end;

  //BUTTON
  if (style=0)or(style=1) then begin
   glColor4f(br,bg,bb,1*alpha);
   glBegin(gl_Quads);
    glTexCoord( 96/256,  136/256);   glVertex2f(gx(w-5), gy(-5));
    glTexCoord( 96/256,  113/256);   glVertex2f(gx(w-5), gy(18));
    glTexCoord( 107/256, 113/256);   glVertex2f(gx(w+6), gy(18));
    glTexCoord( 107/256, 136/256);   glVertex2f(gx(w+6), gy(-5));
   glEnd();
  end;
 end;

 if ((clickOnce)and(lastClicked=5*100+OID)and(ml))or((onmouse)and(ml)) then begin
  position := round((max-min)/width* (mtx-left-parent.left-2)+min);
  if position >  max then position := max;
  if position <  min then position := min;
  lastClicked := 5*100+OID;
  clickOnce := true;
  MouseDown(Self);
 end;
 if not ml then begin
  if clickOnce then
   onChange(Self);
  clickOnce := false;
 end;

 glPopMatrix;
end;

procedure   TGUITrackBar.reSize;
begin
end;










// -----------------------------------------------------------------------------
// TrackBar --------------------------------------------------------------------
// -----------------------------------------------------------------------------
Constructor TGUIProgressBar.create;
begin
 Create(0,0,150,0,100,0,1,1,1,1,nil);
end;

Constructor TGUIProgressBar.Create(left,top,width:integer; parent:PGUIobject);
begin
 Create(left,top,width,0,100,0,1,1,1,1,parent);
end;

Constructor TGUIProgressBar.Create(left,top,width:integer; min,max,position:integer; parent:PGUIobject);
begin
 Create(left,top,width,min,max,position,1,1,1,1,parent);
end;

Constructor TGUIProgressBar.Create(left,top,width:integer; min,max,position:integer; r,g,b,a:real; parent:PGUIobject);
begin
 wai     := 6;
 OID     := GUI_OBJ_COUNT;
 inc(GUI_OBJ_COUNT);

 self.r       := r;
 self.g       := g;
 self.b       := b;
 self.a       := a;
 visible      := true;
 self.parent  := parent;
 onChange     := GUIProcedureNothing;
 MouseDown    := GUIProcedureNothing;

 lr           := 1;
 lg           := 1;
 lb           := 1;
 la           := 1;

 l2r          := 0;
 l2g          := 0;
 l2b          := 0;
 l2a          := 1;

 self.min      := min;
 self.max      := max;
 self.position := position;

 style         := 0;

 showing := false;
 closing_anim := 0;

 //meret beallitasok
 self.left   := left;
 self.width  := width;
 self.right  := left+width;

 self.top    := top;
 height      := 40;
 self.bottom := top+height;


 fr          := 1;
 fg          := 1;
 fb          := 1;
 fa          := 1;
 text := 'loading...';


 width:=right-left;
 height:=bottom-top;
 cx:=left+ width  div 2;
 cy:=top + height div 2;
end;


function TGUIProgressBar.gX(x:integer) : single;
begin
 if (parent.wai = 1) then
  result := screenToGlx(left+parent.left+GUI_PANEL_BORDER_WIDTH+x)
 else
  result := screenToGlx(left+parent.left+x);
end;

function TGUIProgressBar.gY(y:integer) : single;
begin
 if (parent.wai = 1) then begin //ha a szulo panel es van header akkor a top lejebb kezdodik ezert a +27
  if TGUIPanel(parent^).header then
   result := screenToGly(top+parent.top+27+y)
  else
   result := screenToGly(top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1+y)
 end else
  result := screenToGly(top+parent.top+y);
end;

function TGUIProgressBar.onMouse : Boolean;
begin
 if (parent.wai = 1) then begin
  if TGUIPanel(parent^).header then begin
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+27-5)and(mty<top+height+parent.top+27+5) then
    result := true
   else
    result := false;
  end else
   if (mtx>left+parent.left+GUI_PANEL_BORDER_WIDTH)and(mtx<left+width+parent.left+GUI_PANEL_BORDER_WIDTH)and(mty>top+parent.top+GUI_PANEL_BORDER_WIDTH*2-1-5)and(mty<top+height+parent.top+GUI_PANEL_BORDER_WIDTH*2-1+5) then
    result := true
   else
    result := false;
 end else begin
  if (mtx>left+parent.left)and(mtx<left+width+parent.left)and(mty>top+parent.top-5)and(mty<top+height+parent.top+5) then
   result := true
  else
   result := false;
 end;
end;

procedure TGUIProgressBar.hide;
begin
 if closing_anim>=0 then begin
  closing_anim := 1;
  showing := false;
 end;
end;

procedure TGUIProgressBar.show;
begin
 showing := true;
 closing_anim := 0;
 visible := true;
end;

procedure TGUIProgressBar.draw;
var
  alpha : real;
  w,rw : integer;
  tw: real;
begin
 if not visible then exit;

 if parent.a<a then  alpha := parent.a else alpha := a;

 glPushMatrix;

 if (closing_anim<1)and(showing) then begin
  closing_anim := closing_anim + GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim>=1 then begin
   showing:=true;
   closing_anim := 1;
  end;
  alpha := a - (1-closing_anim);
 end;

 if (closing_anim>0)and(not showing) then begin
  closing_anim := closing_anim - GUI_ANIM_SPEED*2 * TimeCorrection;
  if closing_anim <= 0 then begin
   visible := false;
   closing_anim:=0;
   glPopMatrix;
   exit;
  end;
  alpha := a - (1-closing_anim);
 end;


 glBindTexture( GL_TEXTURE_2D, GUITexture );
 glColor4f(r,g,b,1*alpha);
 glBegin(gl_Quads);
  glTexCoord( 1/256, 177/256);     glVertex2f(gx(0),       gy(0));
  glTexCoord( 1/256, 137/256);     glVertex2f(gx(0),       gy(Height));
  glTexCoord( 5/256, 137/256);     glVertex2f(gx(5),       gy(Height));
  glTexCoord( 5/256, 177/256);     glVertex2f(gx(5),       gy(0));

  glTexCoord( 6/256,  177/256);    glVertex2f(gx(5),       gy(0));
  glTexCoord( 6/256,  137/256);    glVertex2f(gx(5),       gy(Height));
  glTexCoord( 155/256, 137/256);    glVertex2f(gx(width-5), gy(Height));
  glTexCoord( 155/256, 177/256);    glVertex2f(gx(width-5), gy(0));

  glTexCoord( 156/256, 177/256);    glVertex2f(gx(width-5), gy(0));
  glTexCoord( 156/256, 137/256);    glVertex2f(gx(width-5), gy(Height));
  glTexCoord( 161/256, 137/256);    glVertex2f(gx(width),   gy(Height));
  glTexCoord( 161/256, 177/256);    glVertex2f(gx(width),   gy(0));
 glEnd();


 if position >  max then position := max;
 if position <  min then position := min;
 if position >= min then begin
  w := round( width/(max-min)*(position-min));
  rw := w;
  if w>width-2 then w := width-2;
  if w<3       then w := 3;
  if (style = 2)or(style = 3) then w:=width-3;

  //LINE
  if (position>min)and(style=0)or(style=1) then begin
   glColor4f(lr,lg,lb,1*alpha);
   glBegin(gl_Quads);
    tw:=w/width*154;
    glTexCoord( 6/256,  216/256);     glVertex2f(gx(2), gy(2));
    glTexCoord( 6/256,  179/256);     glVertex2f(gx(2), gy(Height-2));
    glTexCoord( (6+tw)/256, 179/256); glVertex2f(gx(w), gy(Height-2));
    glTexCoord( (6+tw)/256, 216/256); glVertex2f(gx(w), gy(2));
   glEnd();
  end;


  //LINE 2
  if (position>min)and(style=0)or(style=2)or(style=3) then begin
   if (position<max)or(style=3)or(style=2) then
    ta := ta + GUI_ANIM_SPEED*0.15 * TimeCorrection;
   glMatrixMode(GL_TEXTURE);
    glPushMatrix();
    glLoadIdentity;
    glTranslatef( -ta , 0 , 0 );
   glMatrixMode(GL_MODELVIEW);

   glColor4f(l2r,l2g,l2b,0.4*alpha);
   glBegin(gl_Quads);
    tw:=height-5;
    if tw>35 then tw:=35;
    glTexCoord( 1/256,  (219+tw)/256); glVertex2f(gx(3), gy(2));
    glTexCoord( 1/256,  219/256);      glVertex2f(gx(3), gy(Height-2));
    glTexCoord( w/256, 219/256);       glVertex2f(gx(w), gy(Height-2));
    glTexCoord( w/256, (219+tw)/256);  glVertex2f(gx(w), gy(2));
   glEnd();

   glMatrixMode(GL_TEXTURE);
    glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
  end;

 end;

 if style<2 then begin
  text := inttostr(round(rw/width*100))+'%';
  outtext(alpha);
 end else if style = 3 then begin
  outtext(alpha);
 end;

 if ((clickOnce)and(lastClicked=6*100+OID)and(ml))or((onmouse)and(ml)) then begin
  lastClicked := 6*100+OID;
  clickOnce := true;
  MouseDown(Self);
 end;
 if not ml then begin
  if clickOnce then
   onChange(Self);
  clickOnce := false;
 end;

 glPopMatrix;
end;

procedure   TGUIProgressBar.reSize;
begin
end;

procedure TGUIProgressBar.outtext(alpha: real);
 var i:integer;
     row,col:integer;
     u,v,u1,v1,xx,yy:real;
     CurX:integer;
     w:integer;
 //const size = 1000;
     size : integer;
begin
  if height<20 then
   size := 1200
  else
   size := 750;

  if text='' then exit;
  if font.TexID=0 then font := defaultGUIfont;

  CurX := 0;

  w:=0; // align to center
  for i:=1 to length(text) do
   w := w + font.Width[ord(text[i])];


  xx:=gx(abs(width div 2 - w div 2));//((left+parent.left-522  +(right-left)/2 )*(0.552)-w/2.7)/522;
  if height<20 then
   yy:=gy(height div 2 + 6)
  else
   yy:=gy(height div 2 + 9);//((350-top-parent.top    -(bottom-top)/2)*(0.385))/353;

  glcolor4f(fr,fg,fb,fa*alpha);

  glBindTexture( GL_TEXTURE_2D, font.texid );
   glBegin(GL_QUADS);

    for i:=1 to length(text) do begin
      row:=(ord(text[i])-font.Base) div font.RowPitch;
      col:=(ord(text[i])-font.Base)-Row*font.RowPitch;

      U:=Col*font.ColFactor;
      V:=Row*font.RowFactor;
      U1:=U+font.ColFactor;
      V1:=V+font.RowFactor;

      glTexCoord2f(U, V1); glVertex2f((CurX)/size+xx,      yy);
      glTexCoord2f(U1,V1); glVertex2f((CurX+font.CellX)/size+xx,yy);
      glTexCoord2f(U1,V ); glVertex2f((CurX+font.CellX)/size+xx,yy+font.YOffset/size);
      glTexCoord2f(U, V ); glVertex2f((CurX)/size+xx,      yy+font.YOffset/size);

      CurX := CurX + font.Width[ord(text[i])];
    end;

   glEnd();
end;

procedure TGUIProgressBar.inc;
begin
 position := position + 1;
 if position > max then position := max;
end;

procedure TGUIProgressBar.inc(x:integer);
begin
 position := position + x;
 if position > max then position := max;
end;






end.




