//---------------------------------------------------------------------------
#ifndef TOpenGLAPPanelH
#define TOpenGLAPPanelH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>

#include "gl.h"  /* Include local "gl.h". Don't include borland <GL/gl.h>. */
#include "glu.h"
#include "BMPTexture.hpp"
#include "OpenGLAPFont3D.hpp"
#include "OpenGLAPFont2D.hpp"
//---------------------------------------------------------------------------
class TOpenGLAPPanel : public TCustomPanel
{
private:
 // ---- Enumerations
 enum TPFDPixelTypes     {f_PFD_TYPE_RGBA,f_PFD_TYPE_COLORINDEX};
 enum TPFDFlags          {f_PFD_DRAW_TO_WINDOW, f_PFD_DRAW_TO_BITMAP,
                         f_PFD_SUPPORT_GDI, f_PFD_SUPPORT_OPENGL,
                         f_PFD_GENERIC_ACCELERATED, f_PFD_GENERIC_FORMAT,
                         f_PFD_NEED_PALETTE, f_PFD_NEED_SYSTEM_PALETTE,
                         f_PFD_DOUBLEBUFFER,f_PFD_STEREO, f_PFD_SUPPORT_COMPOSITION,
                         f_PFD_SWAP_LAYER_BUFFERS};
 enum TOpenGLSwapBuffers {Auto,Manual};
 enum TOpenGLPrintScale  {pglNone,pglPrintToFit,pglProportional};
 enum TFont3DFormat      {f_WGL_FONT_LINES,f_WGL_FONT_POLYGONS};

 // ---- Types
 typedef Set <TPFDFlags, f_PFD_DRAW_TO_WINDOW, f_PFD_SWAP_LAYER_BUFFERS>
                                                                 TPFDFlagsSet;
 // ---- Variables
   HDC                   DisplayDeviceContext;
   HGLRC                 GLRenderingContext;
   HPALETTE              Palette;

   TPFDFlagsSet          FdwFlags;

   bool                  DoubleBuffer;
   bool                  AutoSwapbuffers;
   TPFDPixelTypes        FiPixelType;
   BYTE                  SavedPixelType;
   BYTE                  FcColorBits;
   BYTE                  FcDepthBits;
   BYTE                  FcAccBits;
   TOpenGLSwapBuffers    FSwapBuffers;

   TOpenGLPrintScale     FOpenGLPrintScale;
   int                   FOpenGLPixelsPerInch;

   bool                  Font3DEnabled;
   TFont               * Font3DType;
   int                   Font3DFirstGylph;
   int                   Font3DNumGylph;
   float                 Font3DMaxDeviation;
   float                 Font3DExtrusion;
   TFont3DFormat         Font3DFormat;
   int                   SavedFont3DFormat;
   OpenGLAPFont3D      * Font3DDefault;

   bool                  Font2DEnabled;
   TFont               * Font2DType;
   int                   Font2DFirstGylph;
   int                   Font2DNumGylph;
   OpenGLAPFont2D      * Font2DDefault;
   char                  SystemMessage[255];


   // ---- Performance variables for frame calculation
   LARGE_INTEGER        Frequency;
   bool                 Ffps_Enabled;
   bool                 FToolWindow;
   bool                 FBorder;
   bool                 FAllowResize;
   bool                 FAllowMoving;
   bool                 AllowCreateParms;
   // ---- Multi Sample	Support
   bool					FMultiSample;
   bool					arbMultisampleSupported;

   // ---- Methods
				int  MultiSamplePixelFormat (void);
			  bool   CreateGLContext(void);
              void   DestroyGLContext(void);
              bool   ConstructPalette(PIXELFORMATDESCRIPTOR &pfd);
              void   Create3DFont(void);
              void   Create2DFont(void);

   // ---- Property Medthods
              void   __fastcall SetToolWindow (const bool Value);
              void   __fastcall SetBorder (const bool Value);
              void   __fastcall SetAllowResize (const bool Value);
              void   __fastcall SetPFDPixelType(const TPFDPixelTypes Value);
              void   __fastcall SetPFDFlags (const TPFDFlagsSet Value);

              void   __fastcall SetPFDNumColorBits(const BYTE Value);
              void   __fastcall SetPFDNumDepthBits(const BYTE Value);
              void   __fastcall SetPFDNumAccBits(const BYTE Value);

              void   __fastcall SetOpenGLPrintScale(const TOpenGLPrintScale Value);
              void   __fastcall SetOpenGLPixelsPerInch(const int Value);

              void   __fastcall SetFont3DType(TFont* Value);
              void   __fastcall SetFont3DFormat(const TFont3DFormat Value);
              void   __fastcall SetFont(TFont* Value);

protected:
   // ---- Variables
   TNotifyEvent FOnPaint,FOnResize,FOnInit,FOnPreInit, FOnError;

   // ---- Inherited or Overidden Methods
   virtual    void   __fastcall CreateParams(TCreateParams &Params);
   virtual    void   __fastcall Paint();
              void   __fastcall Error(void);
   DYNAMIC    void   __fastcall Resize();
              void   __fastcall WMCreate(TWMCreate &Message);
              void   __fastcall WMPaletteChanged(TWMPaletteChanged &Message);
              void   __fastcall WMQueryNewPalette(TWMQueryNewPalette &Message);
              void   __fastcall WMDestroy(TWMDestroy &Message);
              void   __fastcall WMMove (TWMMove &Message);
              void   __fastcall WMEraseBkgnd(TWMEraseBkgnd &Message);

public:
    // ----
	AnsiString    			ErrorMsg;
	int      			  	Fps;
	PIXELFORMATDESCRIPTOR 	dpf;  // described pixel format for public use

           __fastcall TOpenGLAPPanel(TComponent* Owner);
           __fastcall ~TOpenGLAPPanel();

    bool   __fastcall MakeOpenGLPanelCurrent(void);
    void   __fastcall MakeOpenGLPanelNotCurrent(void);
    void   __fastcall SwapBuffers(void);
    bool   __fastcall PanelShareLists(TOpenGLAPPanel *WithOpenGLPanel);
    OpenGLAPFont3D *
           __fastcall Create3DFont(TFont *Font, int FirstGylph,
                                   int NumGylph,float Deviation,
                                   float Extrusion, int Format);
    void   __fastcall Get3DTextSize(AnsiString Text,GLdouble *XYZ);
    void   __fastcall Get3DTextSize(OpenGLAPFont3D *Font,
                                    AnsiString Text,GLdouble *XYZ);
    void   __fastcall Draw3DText(AnsiString Text);
    void   __fastcall Draw3DText(OpenGLAPFont3D * Font,AnsiString Text);
    OpenGLAPFont2D *
           __fastcall Create2DFont(TFont *Font, int FirstGylph,
                                   int NumGylph);
    void   __fastcall Draw2DText(AnsiString Text);
    void   __fastcall Draw2DText(OpenGLAPFont2D * Font,AnsiString Text);

    BMPTexture *
           __fastcall LoadBMPTexture(AnsiString FileName,
                                     Boolean WithAlpha);
    int    __fastcall LoadTGA (AnsiString FileName,       // ---- Filename
                               byte **pixels,
                               unsigned int *width,
                               unsigned int *height,
                               unsigned int *format);
    void   __fastcall PrinTOpenGLAPPanel(void);
    void   __fastcall SaveOpenGLPanelToFile(const String &FileName);
    bool   __fastcall QueryOpenGLExtention(AnsiString ExtentionName);
    int    __fastcall GetDisplayBPP(void);
    bool   __fastcall SetDisplayBPP(int);


__published:
   // ---- Inherited Properties
   __property Caption;
   __property Alignment;
   __property Align;
   __property DragCursor;
   __property DragMode;
   __property Enabled;
   __property ParentFont;
   __property ParentShowHint;
   __property PopupMenu;
   __property ShowHint;
   __property TabOrder;
   __property TabStop;
   __property Visible;

   //...Added Properites
   __property TPFDPixelTypes     PixelType = {read= FiPixelType,
                                 write= SetPFDPixelType,
                                 default=f_PFD_TYPE_RGBA};

   __property TPFDFlagsSet       PFDFlags = {read=FdwFlags,
                                             write=SetPFDFlags,nodefault};


   __property BYTE               cColorBits = {read= FcColorBits,
                                 write=SetPFDNumColorBits, default=32};

   __property BYTE               cDepthBits = {read= FcDepthBits,
                                 write=SetPFDNumDepthBits, default=32};

   __property BYTE               cAccBits = {read= FcAccBits,
                                 write=SetPFDNumAccBits, default=8};

   __property bool MultiSample	 ={read=FMultiSample, write=FMultiSample, default=Auto};

   __property TOpenGLSwapBuffers GLSwapBuffers ={read=FSwapBuffers,
                                 write=FSwapBuffers, default=Auto};

   __property int                PixelsPerInch = {read=FOpenGLPixelsPerInch,
                                 write= SetOpenGLPixelsPerInch,default=96};

   __property TOpenGLPrintScale  PrintScale = {read= FOpenGLPrintScale,
                                 write=SetOpenGLPrintScale,
                                 default=pglProportional};

   __property bool               Font3D_Enabled = {read=Font3DEnabled,
                                 write=Font3DEnabled, default=false};

   __property TFont              * Font3D_Type = {read=Font3DType,
                                 write=SetFont3DType};

   __property int                Font3D_FirstGylph = {read=Font3DFirstGylph,
                                 write=Font3DFirstGylph, default=32};

   __property int                Font3D_NumGylph = {read=Font3DNumGylph,
                                 write=Font3DNumGylph, default=96};

   __property float              Font3D_MaxDeviation = {read=Font3DMaxDeviation,
                                 write=Font3DMaxDeviation};

   __property float              Font3D_Extrustion = {read=Font3DExtrusion,
                                 write=Font3DExtrusion};

   __property TFont3DFormat      Font3D_Format = {read=Font3DFormat,
                                 write=SetFont3DFormat,
                                 default=f_WGL_FONT_POLYGONS};

   __property bool               Font2D_Enabled = {read=Font2DEnabled,
                                 write=Font2DEnabled, default=false};

   __property TFont              * Font2D_Type = {read=Font2DType,
                                 write=SetFont};

   __property int                Font2D_FirstGylph = {read=Font2DFirstGylph,
                                                      write=Font2DFirstGylph,
                                                      default=32};

   __property int                Font2D_NumGylph = {read   = Font2DNumGylph,
                                                    write  = Font2DNumGylph,
                                                    default= 96};
   __property bool               Fps_Enabled = {read =Ffps_Enabled,
                                                write=Ffps_Enabled, default=false};

   __property bool               Border = {read =FBorder,
                                           write=SetBorder, default=false};
   __property bool               ToolWindow = {read =FToolWindow,
                                               write=SetToolWindow, default=false};
   __property bool               AllowResize = {read =FAllowResize,
                                                write=SetAllowResize, default=false};
   __property bool               AllowMoving = {read =FAllowMoving,
                                                write=FAllowMoving, default=false};

   // ---- Inherited Events
   __property OnClick;                                                            
   __property OnDblClick;
   __property OnDragDrop;
   __property OnDragOver;
   __property OnStartDrag;
   __property OnEndDrag;
   __property OnEnter;
   __property OnExit;
   __property OnMouseDown;
   __property OnMouseMove;
   __property OnMouseUp;
   __property OnMouseWheel;
   __property OnMouseWheelUp;
   __property OnMouseWheelDown;
   __property OnMouseActivate;
   __property OnMouseEnter;
   __property OnMouseLeave;

   // ---- Added Events
   __property TNotifyEvent OnInit    = {read=FOnInit,write=FOnInit};
   __property TNotifyEvent OnPreInit = {read=FOnPreInit,write=FOnPreInit};
   __property  TNotifyEvent OnError  = {read=FOnError,write=FOnError};

   // ---- Overidden Events
   __property TNotifyEvent OnResize = {read=FOnResize,write=FOnResize};
   __property TNotifyEvent OnPaint  = {read=FOnPaint,write=FOnPaint};

   // ---- Message Maps
   BEGIN_MESSAGE_MAP
      VCL_MESSAGE_HANDLER(WM_CREATE,TWMCreate,WMCreate)
      VCL_MESSAGE_HANDLER(WM_DESTROY,TWMDestroy,WMDestroy)
      VCL_MESSAGE_HANDLER(WM_MOVING, TWMMove, WMMove)
      VCL_MESSAGE_HANDLER(WM_PALETTECHANGED,TWMPaletteChanged,WMPaletteChanged)
      VCL_MESSAGE_HANDLER(WM_QUERYNEWPALETTE,TWMQueryNewPalette,WMQueryNewPalette)
      VCL_MESSAGE_HANDLER(WM_ERASEBKGND,TWMEraseBkgnd,WMEraseBkgnd)
   END_MESSAGE_MAP(TCustomPanel)
};
//---------------------------------------------------------------------------
#endif

//---------------------------------------------------------------------------
