/*
======================================================================
about.c

Ernie Wright  15 May 05
MSVC 4.0

Display QV's About dialog, including the version and build date.
====================================================================== */

#include "qv.h"


#define AW1 160
#define AW2 184
#define AH  144


/*
======================================================================
draw_text()

Draw text on an HDC at the given position and in the specified font
and color.
====================================================================== */

static void draw_text( HDC hdc, char *text, int x, int y, char *fontname,
   int size, int weight, COLORREF color )
{
   LOGFONT lf = { 0 };
   HFONT hfont;
   RECT r;

   lf.lfHeight = -size;
   lf.lfWeight = weight;
   strcpy( lf.lfFaceName, fontname );
   hfont = CreateFontIndirect( &lf );
   hfont = SelectObject( hdc, hfont );
   SetBkMode( hdc, TRANSPARENT );
   SetTextColor( hdc, color );

   r.left = x;
   r.top = y;
   r.bottom = r.top + DrawText( hdc, text, -1, &r,
      DT_LEFT | DT_TOP | DT_SINGLELINE | DT_CALCRECT );
   DrawText( hdc, text, -1, &r, DT_LEFT | DT_TOP | DT_SINGLELINE );
   DeleteObject( SelectObject( hdc, hfont ));
}


/*
======================================================================
info_bitmap()

The About dialog contains an owner-drawn button that covers the entire
window.  The button is drawn with two bitmaps.  The left bitmap is an
image stored as a resource.  The right bitmap is created here and
contains text describing QV.
====================================================================== */

static HBITMAP info_bitmap( HINSTANCE hinst )
{
   extern HICON hiconlg;
   COLORREF c = RGB( 255, 255, 255 );
   HBITMAP hbm, hbmOld;
   HDC hdc, hdcOld;
   HPEN hpen;

   hdcOld = GetDC( GetDesktopWindow() );
   hdc = CreateCompatibleDC( hdcOld );
   hbm = CreateCompatibleBitmap( hdcOld, AW2, AH );
   ReleaseDC( GetDesktopWindow(), hdcOld );
   hbmOld = SelectObject( hdc, hbm );

   DrawIcon( hdc, 8, 16, hiconlg );

   draw_text( hdc, " F9 Render Display ",    40,  30, "Arial", 12, FW_BOLD, c );
   draw_text( hdc, " by Ernie Wright ",       6,  47, "Arial", 14, FW_BOLD, c );
   draw_text( hdc, " version 4.0 ",           9, 100, "Arial", 12, FW_BOLD, c );
   draw_text( hdc, " build:  " __DATE__ " ",  8, 118, "Arial", 12, FW_BOLD, c );

   hpen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 )));
   MoveToEx( hdc, 0, AH / 2, NULL );
   LineTo( hdc, AW2, AH / 2 );
   DeleteObject( SelectObject( hdc, hpen ));

   SelectObject( hdc, hbmOld );
   DeleteDC( hdc );

   return hbm;
}


/*
======================================================================
center_dlg()

Center the dialog over its parent window, which might be QV's main
window or LightWave's.
====================================================================== */

static void center_dlg( HWND hwnd, HWND hctl )
{
   RECT r, rc, rp;
   int x, y, w, h;

   GetWindowRect( hwnd, &r );
   GetClientRect( hwnd, &rc );
   w = r.right - r.left;
   w += AW1 + AW2 - rc.right;
   h = r.bottom - r.top;
   h += AH - rc.bottom;

   GetWindowRect( GetParent( hwnd ), &rp );
   x = ( rp.right - rp.left - w ) / 2;
   y = ( rp.bottom - rp.top - h ) / 2;

   GetWindowRect( GetDesktopWindow(), &r );
   if ( y + h > r.bottom ) y = r.bottom - h;
   if ( x + w > r.right ) x = r.right - w;
   if ( y < 0 ) y = 0;
   if ( x < 0 ) x = 0;
   SetWindowPos( hwnd, NULL, x, y, w, h, 0 );
   SetWindowPos( hctl, NULL, 0, 0, AW1 + AW2, AH, 0 );
}


/*
======================================================================
init()

Initialize the dialog.  Creates handles for the two bitmaps used to
draw the dialog.  One is loaded from QV's resources and the other is
created by info_bitmap().  The bitmap handles are stored in the user
data of the dialog.
====================================================================== */

static void init( HWND hwnd, LPARAM lparam )
{
   static HBITMAP hbm[ 2 ];
   HINSTANCE hinst;
   HWND hctl;

   if ( lparam > 0 )
      SetTimer( hwnd, 1, lparam, NULL );

   hctl = GetDlgItem( hwnd, IDOK );
   SetWindowLongPtr( hctl, GWLP_USERDATA, ( LONG_PTR ) hbm );

   hinst = ( HINSTANCE ) GetWindowLongPtr( hwnd, GWLP_HINSTANCE );
   hbm[ 0 ] = LoadBitmap( hinst, "qvabout1" );
   hbm[ 1 ] = info_bitmap( hinst );
   center_dlg( hwnd, hctl );
}


/*
======================================================================
draw()

Called in response to the WM_DRAWITEM for the owner-drawn button that
covers the dialog.
====================================================================== */

static void draw( DRAWITEMSTRUCT *dis )
{
   HBITMAP *hbm, hbmdc;
   HDC hdc;

   hbm = ( HBITMAP * ) GetWindowLongPtr( dis->hwndItem, GWLP_USERDATA );
   hdc = CreateCompatibleDC( dis->hDC );

   hbmdc = SelectObject( hdc, hbm[ 0 ] );
   BitBlt( dis->hDC, 0, 0, AW1, AH, hdc, 0, 0, SRCCOPY );
   SelectObject( hdc, hbm[ 1 ] );
   BitBlt( dis->hDC, AW1, 0, AW2, AH, hdc, 0, 0, SRCCOPY );

   SelectObject( hdc, hbmdc );
   DeleteDC( hdc );
}


/*
======================================================================
free_bitmaps()

Free the two bitmaps used to draw the dialog.  Called in response to
WM_DESTROY.
====================================================================== */

static void free_bitmaps( HWND hwnd )
{
   HBITMAP *hbm;
   hbm = ( HBITMAP * ) GetWindowLongPtr( GetDlgItem( hwnd, IDOK ), GWLP_USERDATA );
   DeleteObject( hbm[ 0 ] );
   DeleteObject( hbm[ 1 ] );
}


/*
======================================================================
AboutDlgProc()

Dialog box procedure for QV's logo display.
====================================================================== */

static INT_PTR WINAPI
AboutDlgProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
   switch ( msg )
   {
      case WM_INITDIALOG:
         init( hwnd, lparam );
         return TRUE;

      case WM_DRAWITEM:
         draw(( LPDRAWITEMSTRUCT ) lparam );
         return TRUE;

      case WM_TIMER:
      case WM_COMMAND:
         KillTimer( hwnd, 1 );
         EndDialog( hwnd, TRUE );
         return TRUE;

      case WM_DESTROY:
         free_bitmaps( hwnd );
         break;

      default:
         break;
   }

   return FALSE;
}


/*
======================================================================
aboutDialog()

Display QV's logo.
====================================================================== */

void aboutDialog( HINSTANCE hinst, HWND hwnd, int timeout )
{
   if ( timeout > 0 )
      CreateDialogParam( hinst, "qvabout", hwnd, AboutDlgProc, ( LPARAM ) timeout );
   else
      DialogBox( hinst, "qvabout", hwnd, AboutDlgProc );
}
