Index » Empathy Jukebox : Blob f05307 / opengl / glJuke.pas
unit glJuke;

interface

uses
  gl,glu,glUtils,glUi,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls,math,jpeg,main,global;

const
ROTATION_TIMER_INTERVAL = 30;
BORDER_TOPHEIGHT=17;
BORDER_BOTTOMHEIGHT=10;

type
  TGLPanel = class(TCustomControl)
    GLTimer: TTimer;
    procedure GLTimerTimer(Sender: TObject);
    procedure MouseUp(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);  override;
    procedure MouseDown(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);override;
    procedure MouseMove( Shift: TShiftState; X, Y: Integer);override;
    procedure Draw;
    Procedure MoveLeft;
    Procedure MoveRight;
    procedure Resize;override;
    procedure SetLbEnabled(var l : tglListbox);
    procedure Paint;override;
    //procedure FormClose(Sender: TObject; var Action: TCloseAction);
    constructor Create(AOwner: TComponent);override;
    procedure init();
    procedure NoAlbums;

  private
    { Private declarations }

    ControlSet : TglControlSet;
    Background: array [0..0] of TglBitmap;
    moveinprogress : boolean;
    flastrotation : integer;
    bnd : integer;
    prev_dir : integer;
    procedure createControls;
    procedure doautorotation(stop : integer;rot : integer;enable : TGLListbox);


  public
    { Public declarations }
    Artwork : array[0..3] of TglBitmap;
    Titles : array[0..3] of TglListbox;
    AddAll : array[0..3] of TglLabel;
    //Arrows : array[0..1] of TglColourQuad;
    property lastrotation : integer read flastrotation write flastrotation;
  end;

  type
  TColorRec = packed record
    b,g,r,a: Byte;
    end;


var
  angle : single;

  DC:HDC;
  RC:HGLRC;




  rotation : integer = 0;
  //lastrotation : integer =0;
  velocity : integer;
  starttime : dword =0;
  endtime : dword =0;
  startpoint : integer;
  endpoint : integer;



implementation
uses jukeboxform;


procedure TGLPanel.MoveLeft;
begin
if moveinprogress=true then exit;
MouseDown(mbLeft,[],width div 2,300);
application.processmessages;
MouseMove([],0,300);
application.processmessages;
MouseUp(mbLeft,[],0,300);
moveinprogress:=false;
end;

procedure TGLPanel.MoveRight;
begin
if moveinprogress=true then exit;
MouseDown(mbLeft,[],width div 2,300);
application.processmessages;
MouseMove([],width,300);
application.processmessages;
MouseUp(mbLeft,[],width,300);
moveinprogress:=false;
end;



procedure TGLPanel.createControls;
var
n : integer;
obmp : Tbitmap;
tr : Trect;
dr : Trect;
a : tgl3DCoord;
b : tgl3DCoord;

const
addallx1=1.3;
addallx2=1.5;
addally1=-0.75;
addally2=-0.7;
addallz=1.5001;

begin
bnd:=0;
ControlSet:=TglControlSet.Create(self);
ControlSet.RedrawProcedure:=draw;

obmp:=tbitmap.create;
tr.top:=1;
tr.left:=0;
tr.right:=jukebox.ThreeDPanel.width;
tr.bottom:=jukebox.ThreeDPanel.height;

dr.Left:=0;
dr.Top:=0;
dr.Right:=tr.Right;
dr.Bottom:=tr.Bottom;
obmp.width:=Width;
obmp.height:=tr.Bottom;
obmp.Canvas.CopyRect(dr,jukebox.midpanel.Canvas,tr);
//obmp.SaveToFile('c:\temp.bmp');
Background[0]:=TglBitmap.Create(ControlSet);
with Background[0] do begin
name:='Background';
nodraw:=true;
bitmap:=obmp;
Normal:=gl3D(0,0,1);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  a:=getGLPos(0,0);
  b:=getGLPos(width,height);
  with Vertices do begin
    v1:=gl3d(-2.1,-2.5,-5);
    v2:=gl3d(2.1,-2.5,-5);
    v3:=gl3d(2.1,0.5,-5);
    v4:=gl3d(-2.1,0.5,-5);
  end;
end;
obmp.Free;


//Front
Artwork[0]:=TglBitmap.Create(ControlSet);
with ArtWork[0] do begin
name:='Front Cover';
//filename:='\idc\mp3\Florence and the Machine__Lungs\title.jpg';
Normal:=gl3D(0,0,1);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(-1.5, -0.75,  1.5);
    v2:=gl3d(0, -0.75,  1.5);
    v3:=gl3d(0, 0.75,  1.5);
    v4:=gl3d(-1.5, 0.75,  1.5);
  end;
end;

//Right
Artwork[1]:=TglBitmap.Create(ControlSet);
with ArtWork[1] do begin
name:='Right Cover';
//filename:='\idc\mp3\Roxy Music__Avalon\title.jpg';
Normal:=gl3D(1,0,0);
  with Texture do begin
    v1:=gl2D(1,0);
    v2:=gl2d(1,1);
    v3:=gl2d(0,1);
    v4:=gl2d(0,0);
  end;

  with Vertices do begin
    v1:=gl3d(1.5, -0.75,  0);
    v2:=gl3d(1.5,  0.75,  0);
    v3:=gl3d(1.5,  0.75,  1.5);
    v4:=gl3d(1.5, -0.75,  1.5);
  end;
end;

//Back
Artwork[2]:=TglBitmap.Create(ControlSet);
with ArtWork[2] do begin
name:='Back Cover';
//filename:='\idc\mp3\Elvis Presley__The collection vol 4\title.jpg';
Normal:=gl3D(0,0,-1);
  with Texture do begin
    v1:=gl2D(1,0);
    v2:=gl2d(1,1);
    v3:=gl2d(0,1);
    v4:=gl2d(0,0);
  end;

  with Vertices do begin
    v1:=gl3d(0, -0.75,  -1.5);
    v2:=gl3d(0,  0.75,  -1.5);
    v3:=gl3d(1.5,  0.75,  -1.5);
    v4:=gl3d(1.5, -0.75,  -1.5);
  end;
end;

//Left
Artwork[3]:=TglBitmap.Create(ControlSet);
with ArtWork[3] do begin
name:='Left Cover';
//filename:='\idc\mp3\Beatles__Revolver\title.jpg';
Normal:=gl3D(-1,0,0);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(-1.5, -0.75,  -1.5);
    v2:=gl3d(-1.5, -0.75,  0);
    v3:=gl3d(-1.5,  0.75,  0);
    v4:=gl3d(-1.5,  0.75,  -1.5);
  end;
end;

Titles[0]:=tglListbox.Create(ControlSet);
with Titles[0] do begin
onClick:=jukebox.lsbClick;
name:='Front Listbox';
font.name:=jukebox.lsb1.font.name;
font.size:=jukebox.lsb1.font.size;
moretext:=jukebox.lsb1.moretext;
linespacing:=jukebox.lsb1.linespacing;
margin:=aspx(5);
Normal:=gl3D(0,0,1);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(0, -0.75,  1.5);
    v2:=gl3d(1.5, -0.75,  1.5);
    v3:=gl3d(1.5,  0.75,  1.5);
    v4:=gl3d(0,  0.75,  1.5);
  end;
end;

Titles[1]:=tglListbox.Create(ControlSet);
with Titles[1] do begin
onClick:=jukebox.lsbClick;
name:='Right Listbox';
font.name:=Titles[0].font.name;
font.size:=Titles[0].font.size;
moretext:=Titles[0].moretext;
linespacing:=Titles[0].linespacing;
margin:=Titles[0].margin;

Normal:=gl3D(1,0,0);
  with Texture do begin
    v1:=gl2D(1,0);
    v2:=gl2d(1,1);
    v3:=gl2d(0,1);
    v4:=gl2d(0,0);
  end;

  with Vertices do begin
    v1:=gl3d(1.5, -0.75,  -1.5);
    v2:=gl3d(1.5,  0.75,  -1.5);
    v3:=gl3d(1.5,  0.75,  -0);
    v4:=gl3d(1.5, -0.75,  -0);
  end;
end;

Titles[2]:=tglListBox.Create(ControlSet);
with Titles[2] do begin
onClick:=jukebox.lsbClick;
name:='Back Listbox';
font.name:=Titles[0].font.name;
font.size:=Titles[0].font.size;
moretext:=Titles[0].moretext;
linespacing:=Titles[0].linespacing;
margin:=Titles[0].margin;
Normal:=gl3D(0,0,-1);
  with Texture do begin
    v1:=gl2D(1,0);
    v2:=gl2d(1,1);
    v3:=gl2d(0,1);
    v4:=gl2d(0,0);
  end;

  with Vertices do begin
    v1:=gl3d(-1.5, -0.75,  -1.5);
    v2:=gl3d(-1.5,  0.75,  -1.5);
    v3:=gl3d(0,  0.75,  -1.5);
    v4:=gl3d(0, -0.75,  -1.5);
  end;
end;

Titles[3]:=tglListBox.Create(ControlSet);
with Titles[3] do begin
onClick:=jukebox.lsbClick;
name:='Left Listbox';
font.name:=Titles[0].font.name;
font.size:=Titles[0].font.size;
moretext:=Titles[0].moretext;
linespacing:=Titles[0].linespacing;
margin:=Titles[0].margin;
Normal:=gl3D(-1,0,0);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(-1.5, -0.75,  0);
    v2:=gl3d(-1.5, -0.75,  1.5);
    v3:=gl3d(-1.5,  0.75,  1.5);
    v4:=gl3d(-1.5,  0.75,  0);
  end;
end;


AddAll[0]:=TglLabel.Create(ControlSet);
with AddAll[0] do begin
name:='AddAll_Front';
caption:='Add All';
font.name:=jukebox.lsb1.font.name;
font.size:=jukebox.lsb1.font.size;
onclick:=jukebox.playall3d;
Normal:=gl3D(0,0,1);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(addallx1, addally1,  addallz);
    v2:=gl3d(addallx2, addally1,  addallz);
    v3:=gl3d(addallx2,  addally2,  addallz);
    v4:=gl3d(addallx1,   addally2,  addallz);
  end;
end;



AddAll[1]:=TglLabel.Create(ControlSet);
with AddAll[1] do begin
name:='AddAll_Right';
caption:='Add All';
font.name:=jukebox.lsb1.font.name;
font.size:=jukebox.lsb1.font.size;
onclick:=jukebox.playall3d;
Normal:=gl3D(1,0,0);
  with Texture do begin
    v1:=gl2D(1,0);
    v2:=gl2d(1,1);
    v3:=gl2d(0,1);
    v4:=gl2d(0,0);
  end;

  with Vertices do begin
    v1:=gl3d(addallz, addally1,  0-addallx2);
    v2:=gl3d(addallz,  addally2, 0-addallx2);
    v3:=gl3d(addallz,  addally2,  0-addallx1);
    v4:=gl3d(addallz, addally1,  0-addallx1);
  end;
end;

AddAll[2]:=TglLabel.Create(ControlSet);
with AddAll[2] do begin
name:='AddAll_Back';
caption:='Add All';
font.name:=jukebox.lsb1.font.name;
font.size:=jukebox.lsb1.font.size;
onclick:=jukebox.playall3d;
Normal:=gl3D(0,0,-1);
  with Texture do begin
    v1:=gl2D(1,0);
    v2:=gl2d(1,1);
    v3:=gl2d(0,1);
    v4:=gl2d(0,0);
  end;

  with Vertices do begin
    v1:=gl3d(0-addallx2, addally1,  0-addallz);
    v2:=gl3d(0-addallx2,  addally2,  0-addallz);
    v3:=gl3d(0-addallx1,  addally2,  0-addallz);
    v4:=gl3d(0-addallx1, addally1,  0-addallz);
  end;
end;

AddAll[3]:=TglLabel.Create(ControlSet);
with AddAll[3] do begin
name:='AddAll_Left';
caption:='Add All';
font.name:=jukebox.lsb1.font.name;
font.size:=jukebox.lsb1.font.size;
onclick:=jukebox.playall3D;
Normal:=gl3D(-1,0,0);
  with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(0-addallz, addally1,  addallx1);
    v2:=gl3d(0-addallz, addally1,  addallx2);
    v3:=gl3d(0-addallz,  addally2,  addallx2);
    v4:=gl3d(0-addallz,  addally2,  addallx1);
  end;
end;

                                       {
Arrows[0]:=TglColourQuad.Create(ControlSet);
with Arrows[0] do begin
name:='Left to Right arrow';
Normal:=gl3D(0,0,1);
//nodraw:=true;
with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(-2.3, -1.65,  0);
    v2:=gl3d(2.3, -1.72,  0);
    v3:=gl3d(2.3, -1.75,  0);
    v4:=gl3d(-2.3, -1.85, 0);
  end;
end;

Arrows[1]:=TglColourQuad.Create(ControlSet);
with Arrows[1] do begin
name:='Right to Left arrow';
Normal:=gl3D(1,0,0);
//nodraw:=true;
with Texture do begin
    v1:=gl2D(0,0);
    v2:=gl2d(1,0);
    v3:=gl2d(1,1);
    v4:=gl2d(0,1);
  end;

  with Vertices do begin
    v1:=gl3d(-2.3, -1.72+0.2,  0);
    v2:=gl3d(2.3, -1.65+0.2,  0);
    v3:=gl3d(2.3, -1.85+0.2,  0);
    v4:=gl3d(-2.3, -1.75+0.2,  0);
  end;
end;
                                      }

 draw;
 titles[0].clear;
 titles[0].drawmode:=true;
 titles[0].realworldwidth:=round(getRealWorldPos(titles[0].Vertices.v3).x-getRealWorldPos(titles[0].Vertices.v1).x);
 titles[0].realworldheight:=round(getRealWorldPos(titles[0].Vertices.v1).y-getRealWorldPos(titles[0].Vertices.v3).y);
 titles[0].Resize;
 titles[1].clear;
 titles[1].drawmode:=true;
 titles[1].realworldwidth:=titles[0].realworldwidth;
 titles[1].realworldheight:=titles[0].realworldheight;
 titles[1].Resize;
 titles[2].clear;
 titles[2].drawmode:=true;
 titles[2].realworldwidth:=titles[0].realworldwidth;
 titles[2].realworldheight:=titles[0].realworldheight;
 titles[2].Resize;
 titles[3].clear;
 titles[3].drawmode:=true;
 titles[3].realworldwidth:=titles[0].realworldwidth;
 titles[3].realworldheight:=titles[0].realworldheight;
 titles[3].Resize;
 draw;

 setlbenabled(titles[0]);

 randomize;

end;

procedure setupPixelFormat(DC:HDC);
const
 pfd:TPIXELFORMATDESCRIPTOR = (
	nSize:sizeof(TPIXELFORMATDESCRIPTOR);	// size
	nVersion:1;								// version
	dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or
                PFD_DOUBLEBUFFER;	// support double-buffering
	iPixelType:PFD_TYPE_RGBA;		// color type
	cColorBits:24;					// prefered color depth
	cRedBits:0; cRedShift:0;		// color bits (ignored)
        cGreenBits:0;  cGreenShift:0;
        cBlueBits:0; cBlueShift:0;
        cAlphaBits:0;  cAlphaShift:0;   // no alpha buffer
        cAccumBits: 0;
        cAccumRedBits: 0;  		// no accumulation buffer,
        cAccumGreenBits: 0;     // accum bits (ignored)
        cAccumBlueBits: 0;
        cAccumAlphaBits: 0;
	cDepthBits:16;				// depth buffer
	cStencilBits:0;				// no stencil buffer
	cAuxBuffers:0;				// no auxiliary buffers
	iLayerType:PFD_MAIN_PLANE;  // main layer
    bReserved: 0;
    dwLayerMask: 0;
    dwVisibleMask: 0;
    dwDamageMask: 0;                    // no layer, visible, damage masks
    );
var pixelFormat:integer;
begin
  pixelFormat := ChoosePixelFormat(DC, @pfd);
  if (pixelFormat = 0) then
	exit;
  if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then
	exit;
end;






procedure TGLPanel.init();
begin
  glClearDepth(1.0);
  glDepthFunc(GL_LESS);
  glEnable(GL_DEPTH_TEST);
  glShadeModel(GL_SMOOTH);
  glViewport(0,0,self.width,self.height);
  glMatrixMode(GL_PROJECTION);
  glEnable(GL_TEXTURE_2D);  //and very important, ENABLE TEXTURES!!! (new)
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  glEnable(GL_BLEND);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  //glEnable(GL_LIGHT1);


 glLoadIdentity;
 gluPerspective( 45, self.width/self.height,1, 10);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity;

end;

constructor TGLPanel.Create(AOwner: TComponent);
begin
 inherited;
 Parent := (AOwner AS TWinControl);
 width:=parent.width;
 height:=parent.height;
 GLTimer:=TTimer.Create(parent);
 GLTimer.Interval:=ROTATION_TIMER_INTERVAL;;
end;

procedure TGLPanel.Resize;
var
  lastrotation : integer;
  a,b,c,d : TGL3DCoord;
  vp : array [0..3] of GLint;
begin
 DC:=GetDC(Handle);
 //if not assigned(ControlSet) then ControlSet.Free;
 inherited;
 SetupPixelFormat(DC);
 RC:=wglCreateContext(DC); //makes OpenGL window out of DC
 wglMakeCurrent(DC, RC);   //makes OpenGL window active
 init;

 if not assigned(ControlSet) then createControls;
 lastrotation:=currentrotation;
 currentrotation:=0;
 draw;
 titles[0].realworldwidth:=round(getRealWorldPos(titles[0].Vertices.v3).x-getRealWorldPos(titles[0].Vertices.v1).x);
 titles[0].realworldheight:=round(getRealWorldPos(titles[0].Vertices.v1).y-getRealWorldPos(titles[0].Vertices.v3).y);
 titles[1].realworldwidth:=titles[0].realworldwidth;
 titles[1].realworldheight:=titles[0].realworldheight;
 titles[2].realworldwidth:=titles[0].realworldwidth;
 titles[2].realworldheight:=titles[0].realworldheight;
 titles[3].realworldwidth:=titles[0].realworldwidth;
 titles[3].realworldheight:=titles[0].realworldheight;
 currentrotation:=lastrotation;
 ControlSet.processcontrols(EVENT_RESIZE);
 InvalidateRgn(self.handle,0,true);



glGetIntegerv(GL_VIEWPORT, @vp[0]);

with Background[0] do begin

  with Vertices do begin
    c.x:=0;
    c.y:=0;
    c.z:=-2;
    d:=getRealWorldPos(c);

    a:=getGLPosZ(0,0,d.z);
    b:=getGLPosZ(width,height,d.z);
      v1:=gl3d(a.x,b.y,c.z);
      v2:=gl3d(b.x,b.y,c.z);
      v3:=gl3d(b.x,a.y,c.z);
      v4:=gl3d(a.x,a.y,c.z);
  end;
end;



end;


procedure TGLPanel.Draw;
var
dir : integer;
key : word;
const
light_diffuse : array[0..3] of GLFloat =  ( 1.5, 1.5, 1.5, 0.9 );
light_position : array[0..3] of GLFloat = ( 1.5, 1.5, 1.5, 1 );
//light_ambient : array[0..3] of GLFloat =  ( 1, 1, 1,1 );
//light_position2 : array[0..3] of GLFloat = ( 0, 0, 20, 1  );

begin
if not assigned(Background[0]) then exit;

  dir:=0;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);


  glloadidentity();

  //if BackGroundImageWidth<>0 then glDrawPixels(BackGroundImageWidth,BackGroundImageHeight,GL_BGRA_EXT, GL_UNSIGNED_BYTE, @BackgroundImage[0]);

  glLightfv(GL_LIGHT0, GL_DIFFUSE, @light_diffuse);
  glLightfv(GL_LIGHT0, GL_POSITION, @light_position);
  //glLightfv(GL_LIGHT1, GL_POSITION, @light_position2);
  //glLightfv(GL_LIGHT1, GL_AMBIENT, @light_ambient);
  glloadidentity();


  gluLookAt(0.0, 0, 5.75,  { eye is at (0,0,5)}
            0.0, 0.0, 0.0,      {center is at (0,0,0)}
            0.0, 1.0, 0);      {up is in positive Y direction}

  glRotatef(0, 0.0, 1.0, 0.0);
  BackGround[0].Paint;
  //Arrows[0].Paint;
  //Arrows[1].Paint;





  currentrotation:=currentrotation+rotation;
  if currentrotation>359 then begin
    currentrotation:=currentrotation-360;
    bnd:=0;
  end;

  if currentrotation<0 then begin
    currentrotation:=360+currentrotation;
    bnd:=360;
  end;


  if (rotation<0) then dir:=-1;
  if (rotation>0) then dir:=1;

  if (((currentrotation-bnd)>0 ) and (dir=1)) or (((currentrotation-bnd)<0 ) and (dir=-1)) then begin

  if dir=1 then jukebox.drawalbum3D(currentalbum,1);

    if dir=1 then bnd:=currentrotation+90 else bnd:=currentrotation-90;
      if dir=-1 then currentalbum:=currentalbum+1;
      if dir=1 then currentalbum:=currentalbum-1;

      if currentalbum>jalbumcount-1 then currentalbum:=1;
      if currentalbum<=0 then currentalbum:=jalbumcount-1;
    if DEBUGON then outputdebugstring(pansichar(inttostr(currentalbum)+' '+inttostr(bnd)+' '+inttostr(currentrotation)));
    if dir=-1 then jukebox.drawalbum3D(currentalbum,-1);

    if config.wraponunderscore=true  then begin
        if (currentalbum<= mainform.albumlist.items.count) then if length(mainform.albumlist.items[currentalbum])>0 then if (mainform.albumlist.items[currentalbum][1]='_') and (dir=-1) then begin
      key:=65;
      jukebox.FormKeydown(self,key,[]);
     end;
      if (currentalbum<= mainform.albumlist.items.count) then if length(mainform.albumlist.items[currentalbum])>0 then if (mainform.albumlist.items[currentalbum][1]='_') and (dir=1) then begin
      key:=90;
      jukebox.FormKeydown(self,key,[]);
     end;

    end;

    prev_dir:=dir;

  end;

//  if ((currentrotation-bnd)=-1) then begin
//    jukebox.drawalbum3D(currentalbum,-1);
//    bnd:=currentrotation;
//    currentalbum:=currentalbum-1;
//   if currentalbum<1 then currentalbum:=jalbumcount-1;
//   outputdebugstring('-90');
//  end;

  lastrotation:=rotation;



  glRotatef(currentrotation, 0, 1.0, 0.0);
//  caption:=inttostr(currentrotation)+' - '+inttostr(rotation)+' ';


  ControlSet.Draw;
  glPushMatrix;

  SwapBuffers(wglGetCurrentDC);
end;

procedure TGLPanel.MouseMove(Shift: TShiftState; X,
  Y: Integer);
begin
if moveinprogress=true then exit;
inherited;


if starttime=0 then if (controlset.processcontrols(EVENT_MOUSEMOVE)=RESULT_TRUE) then begin;rotation:=0;draw;exit;end;
endtime:=gettickcount;
endpoint:=x;
end;

procedure TGLPanel.MouseUp( Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
res : integer;
begin
if moveinprogress=true then exit;
inherited;
if starttime=0 then begin
  res:=controlset.processcontrols(EVENT_MOUSEUP);
  if res=RESULT_TRUE then begin;rotation:=0;draw;exit;end;
  if res=RESULT_FALSE_BUT_NEEDS_REDRAW then begin
    rotation:=0;
    draw;
  end;

end;

starttime:=0;
//lastrotation:=rotation;
GLTimer.enabled:=false;
GLTimer.Interval:=ROTATION_TIMER_INTERVAL;
GLTimer.OnTimer:=GLTimerTimer;
GLTimerTimer(self);
//GLTimer.enabled:=true;
end;

{procedure TGLPanel.Close(Sender: TObject; var Action: TCloseAction);
begin
 if RC<>0 then begin
  wglMakeCurrent (0,0);
  wglDeleteContext(rc);
 end;
// if DC<>0 then DeleteDC(dc);
end;

 }

procedure TGLPanel.MouseDown(Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
jukebox.closepanels;
if moveinprogress=true then exit;

inherited;
if (controlset.processcontrols(EVENT_MOUSEDOWN)=RESULT_TRUE) then begin;rotation:=0;draw;exit;end;
gltimer.Enabled:=true;
starttime:=gettickcount;
startpoint:=x;
end;


procedure TGLPanel.Paint;
begin
inherited;
draw;
end;

procedure TGLPanel.SetLbEnabled(var l : tglListbox);
begin
Titles[0].enabled:=false;
Titles[1].enabled:=false;
Titles[2].enabled:=false;
Titles[3].enabled:=false;
l.enabled:=true;
end;


procedure TGLPanel.doautorotation(stop : integer;rot : integer;enable : TGLListbox);
var
n : integer;
t : integer;
begin
rotation:=rot;
moveinprogress:=true;
t:=5;
if rotation=1 then begin
  rotation:=t;
  currentrotation:=currentrotation+(t-((currentrotation) mod t));
  n:=currentrotation;
   while n<= stop do begin
    n:=n+t;
    draw;
    application.ProcessMessages;
  end;
end else begin
  t:=-5;
  rotation:=t;
  currentrotation:=currentrotation+(t-((currentrotation) mod t));
  n:=currentrotation;
  while n>= stop do begin
    n:=n+t;
    draw;
    application.ProcessMessages;
   end;
end;

setlbenabled(enable);
moveinprogress:=false;
rotation:=0;
end;

procedure TGLPanel.GLTimerTimer(Sender: TObject);
var
distance : integer;
range : double;
begin
if starttime>0 then begin
  //if GLTimer.Interval>10 then GLTimer.Interval:=GLTimer.Interval-1;
  distance:=(endpoint - startpoint);
  //time:=endtime-starttime;
  range:=10 / width;

  if distance=0 then begin
    rotation:=0;
  //  lastrotation:=0;
    exit;
  end;



  rotation:=round(distance*range);


  if rotation=0 then exit;

  draw;


end;

if ((starttime=0) and (sender=self)) then begin
  if (rotation>0) then begin
        if ((currentrotation>0) and (currentrotation<90)) then  begin doautorotation(89,1,Titles[3]);exit;end;
        if ((currentrotation>90) and (currentrotation<180)) then begin doautorotation(179,1,Titles[2]);exit;end;
        if ((currentrotation>180) and (currentrotation<270)) then begin doautorotation(269,1,Titles[1]);exit;end;
        if ((currentrotation>270) and (currentrotation<360)) then begin doautorotation(359,1,Titles[0]);exit;end;
      end;

  if (rotation<0) then begin
        if ((currentrotation>270) and (currentrotation<360)) then  begin doautorotation(271,-1,Titles[1]);exit;end;
        if ((currentrotation>180) and (currentrotation<270)) then begin doautorotation(181,-1,Titles[2]);exit;end;
        if ((currentrotation>90) and (currentrotation<180)) then begin doautorotation(91,-1,Titles[3]);exit;end;
        if ((currentrotation>0) and (currentrotation<90)) then begin doautorotation(1,-1,Titles[0]);exit;end;
  rotation:=0;
  //lastrotation:=0;
end;

end;

end;


procedure TGLPanel.NoAlbums;
begin
Artwork[0].bitmap:=nil;
Artwork[1].bitmap:=nil;
Artwork[2].bitmap:=nil;
Artwork[3].bitmap:=nil;

Titles[0].items.clear;
Titles[1].items.clear;
Titles[2].items.clear;
Titles[3].items.clear;
end;

end.