//
// Copyright (c) 1997,1998 Colosseum Builders, Inc.
// All rights reserved.
//
// Colosseum Builders, Inc. makes no warranty, expressed or implied
// with regards to this software. It is provided as is.
//
// See the README.TXT file that came with this software for restrictions
// on the use and redistribution of this file or send E-mail to
// info@colosseumbuilders.com
//

//
// Title: Simple Windows BMP Viewer
//
// Author:  John M. Miano miano@colosseumbuilders.com
//
// Description:
//
//  This application is a simple BMP file viewer for Windows.

#include <windows.h>
#include "imagetype.h"
#include "bitmapimage.h"

using namespace Colosseum ;
using namespace std ;

BitmapImage image ;

LRESULT CALLBACK WindowProc(
                  HWND  window,
                  UINT  message,
                  WPARAM  wparam,
                  LPARAM  lparam)
{
  switch (message)
  {
  case WM_PAINT:
    {
      PAINTSTRUCT paintstruct ;
      HDC devicecontext = BeginPaint (window, &paintstruct) ;
      if (image.getWidth () > 0 && image.getHeight () > 0)
      {
        // The largest possible Bitmap Info Header
        BITMAPV4HEADER imageheader ;
        imageheader.bV4Size = sizeof (BITMAPV4HEADER) ;
        imageheader.bV4Width = image.getWidth () ;
        imageheader.bV4Height = - image.getHeight () ;
        imageheader.bV4Planes = 1 ;
        imageheader.bV4BitCount = 32 ;
        imageheader.bV4V4Compression = BI_BITFIELDS ;
        imageheader.bV4SizeImage = 0 ;
        imageheader.bV4XPelsPerMeter = 0 ;
        imageheader.bV4YPelsPerMeter = 0 ;
        imageheader.bV4ClrUsed = 0 ;
        imageheader.bV4ClrImportant = 0 ;
        imageheader.bV4BlueMask = 0xFFU ;
        imageheader.bV4GreenMask = 0xFF00U ;
        imageheader.bV4RedMask = 0xFF0000U ;
        imageheader.bV4AlphaMask = 0xFF000000U ;

        SetDIBitsToDevice (devicecontext,
                           0,
                           0,
                           image.getWidth (),
                           image.getHeight (),
                           0,
                           0,
                           0,
                           image.getHeight (),
                           &image [0],
                           reinterpret_cast<const BITMAPINFO*>(&imageheader),
                           DIB_RGB_COLORS) ;
      }
      EndPaint (window, &paintstruct) ;
    }
    return 0 ;

  case WM_DROPFILES:
    {
      HDROP hdrop = reinterpret_cast<HDROP>(wparam) ;
      char buffer [FILENAME_MAX] ;
      DragQueryFile (hdrop, 0, buffer, sizeof (buffer)) ;
      DragFinish (hdrop) ;
      try
      {
        ImageType type = ReadImage (buffer, image, 0, 0) ;
        if (type == UnknownImage)
        {
          string msg = "Unknown Image Type' " ;
          msg += buffer ;
          msg += "'" ;
          MessageBox (0, msg.c_str (), "Image Viewer", 0) ;
          return 1 ;
        }
      }
      catch (std::exception &ee)
      {
        MessageBox (0, ee.what (), "Image Viewer", MB_OK|MB_ICONERROR) ;
        return 0 ;
      }
      InvalidateRect (window, 0, true) ;
    }
    return 0 ;

  case WM_DESTROY:
    PostQuitMessage (0) ;
    return 0 ;
  }
  return DefWindowProc (window, message, wparam, lparam) ;
}

int WINAPI WinMain(
              HINSTANCE  Instance,
              HINSTANCE  PrevInstance,
              LPSTR  CommandLine,
              int  ShowState)
{
  static const char windowclassname [] = "ImageViewer" ;

  try
  {
    ImageType type = ReadImage (CommandLine, image, 0, 0) ;
    if (type == UnknownImage)
    {
      string msg = "Unknown Image Type' " ;
      msg += CommandLine ;
      msg += "'" ;
      MessageBox (0, msg.c_str (), "Image Viewer", 0) ;
      return 1 ;
    }
  }
  catch (std::exception &ee)
  {
    MessageBox (0, ee.what (), "Image Viewer", MB_OK|MB_ICONERROR) ;
    throw ;
  }

  if (PrevInstance == 0)
  {
    WNDCLASS windowclass ;
    windowclass.style = CS_HREDRAW | CS_VREDRAW ;
    windowclass.lpfnWndProc = WindowProc ;
    windowclass.cbClsExtra = 0 ;
    windowclass.cbWndExtra = 0 ;
    windowclass.hInstance = Instance ;
    windowclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
    windowclass.hCursor = LoadCursor (NULL, IDC_CROSS) ;
    windowclass.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject (WHITE_BRUSH)) ;
    windowclass.lpszMenuName = 0 ;
    windowclass.lpszClassName = windowclassname ;
    RegisterClass (&windowclass) ;
  }

  HWND window ;
  window = CreateWindow (
              windowclassname,
              "Image Viewer",
              WS_OVERLAPPEDWINDOW,
              CW_USEDEFAULT,
              CW_USEDEFAULT,
              CW_USEDEFAULT,
              CW_USEDEFAULT,
              NULL,
              NULL,
              Instance,
              NULL) ;
  
  ShowWindow (window, ShowState) ;
  DragAcceptFiles (window, true) ;
  MSG msg ;
  while (GetMessage (&msg, NULL, 0, 0))
  {
    TranslateMessage (&msg) ;
    DispatchMessage (&msg) ;
  }

  return msg.wParam ;
}

