/*
 * Copyright 1998 Douglas Ridgway
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <windows.h>
#include <commdlg.h>
#include "resource.h"

#include <stdio.h>

static HINSTANCE hInst;
static HWND hMainWnd;
static WCHAR szAppName[5] = {'V','i','e','w',0};
static WCHAR szTitle[80];

static HMETAFILE hmf;
static HENHMETAFILE enhmf;
static int deltax = 0, deltay = 0;
static int width = 0, height = 0;
static BOOL isAldus, isEnhanced;

#include "pshpack1.h"
typedef struct
{
	DWORD		key;
	WORD		hmf;
	SMALL_RECT	bbox;
	WORD		inch;
	DWORD		reserved;
	WORD		checksum;
} APMFILEHEADER;
#include "poppack.h"

#define APMHEADER_KEY	0x9AC6CDD7l


static BOOL FileOpen(HWND hWnd, WCHAR *fn, int fnsz)
{
  static const WCHAR filter[] = {'M','e','t','a','f','i','l','e','s','\0','*','.','w','m','f',';','*','.','e','m','f','\0',0};
  OPENFILENAMEW ofn = { sizeof(OPENFILENAMEW),
                        0, 0, NULL, NULL, 0, 0, NULL,
                        fnsz, NULL, 0, NULL, NULL,
                        OFN_SHOWHELP, 0, 0, NULL, 0, NULL };
  ofn.lpstrFilter = filter;
  ofn.hwndOwner = hWnd;
  ofn.lpstrFile = fn;
  if( fnsz < 1 )
    return FALSE;
  *fn = 0;
  return GetOpenFileNameW(&ofn);
}

static BOOL FileIsEnhanced( LPCWSTR szFileName )
{
  ENHMETAHEADER enh;
  HANDLE handle;
  DWORD size;

  handle = CreateFileW( szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
  if (handle == INVALID_HANDLE_VALUE)
    return FALSE;

  if (!ReadFile( handle, &enh, sizeof(ENHMETAHEADER), &size, NULL ) || size != sizeof(ENHMETAHEADER) )
  {
      CloseHandle( handle );
      return FALSE;
  }
  CloseHandle( handle );

  /* Is it enhanced? */
  return (enh.dSignature == ENHMETA_SIGNATURE);
}

static BOOL FileIsPlaceable( LPCWSTR szFileName )
{
  APMFILEHEADER	apmh;
  HANDLE handle;
  DWORD size;

  handle = CreateFileW( szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
  if (handle == INVALID_HANDLE_VALUE)
    return FALSE;

  if (!ReadFile( handle, &apmh, sizeof(APMFILEHEADER), &size, NULL ) || size != sizeof(APMFILEHEADER))
  {
      CloseHandle( handle );
      return FALSE;
  }
  CloseHandle( handle );

  /* Is it placeable? */
  return (apmh.key == APMHEADER_KEY);
}

static HMETAFILE GetPlaceableMetaFile( LPCWSTR szFileName )
{
  LPBYTE lpData;
  METAHEADER mfHeader;
  APMFILEHEADER	APMHeader;
  HANDLE handle;
  DWORD size;
  HMETAFILE hmf;
  WORD checksum, *p;
  HDC hdc;
  int i;

  handle = CreateFileW( szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
  if (handle == INVALID_HANDLE_VALUE)
    return 0;

  if (!ReadFile( handle, &APMHeader, sizeof(APMFILEHEADER), &size, NULL ) || size != sizeof(APMFILEHEADER))
  {
      CloseHandle( handle );
      return 0;
  }
  checksum = 0;
  p = (WORD *) &APMHeader;

  for(i=0; i<10; i++)
    checksum ^= *p++;
  if (checksum != APMHeader.checksum) {
    char msg[128];
    sprintf(msg, "Computed checksum %04x != stored checksum %04x\n",
	   checksum, APMHeader.checksum);
    MessageBoxA(hMainWnd, msg, "Checksum failed", MB_OK);
    CloseHandle( handle );
    return 0;
  }

  if (!ReadFile( handle, &mfHeader, sizeof(METAHEADER), &size, NULL) || size != sizeof(METAHEADER))
  {
      CloseHandle( handle );
      return 0;
  }

  if (!(lpData = GlobalAlloc(GPTR, (mfHeader.mtSize * 2L))))
  {
      CloseHandle( handle );
      return 0;
  }

  SetFilePointer( handle, sizeof(APMFILEHEADER), NULL, FILE_BEGIN );
  if (!ReadFile(handle, lpData, mfHeader.mtSize * 2, &size, NULL ) || size != mfHeader.mtSize * 2)
  {
    GlobalFree(lpData);
    CloseHandle( handle );
    return 0;
  }
  CloseHandle( handle );

  if (!(hmf = SetMetaFileBitsEx(mfHeader.mtSize*2, lpData)))
    return 0;


  width = APMHeader.bbox.Right - APMHeader.bbox.Left;
  height = APMHeader.bbox.Bottom - APMHeader.bbox.Top;

  /*      printf("Ok! width %d height %d inch %d\n", width, height, APMHeader.inch);  */
  hdc = GetDC(hMainWnd);
  width = width * GetDeviceCaps(hdc, LOGPIXELSX)/APMHeader.inch;
  height = height * GetDeviceCaps(hdc,LOGPIXELSY)/APMHeader.inch;
  ReleaseDC(hMainWnd, hdc);

  deltax = 0;
  deltay = 0 ;
  return hmf;
}

static void DoOpenFile(LPCWSTR filename)
{
  if (!filename) return;

  isAldus = FileIsPlaceable(filename);
  if (isAldus) {
    hmf = GetPlaceableMetaFile(filename);
  } else {
    RECT r;
    isEnhanced = FileIsEnhanced(filename);
    if (isEnhanced)
       enhmf = GetEnhMetaFileW(filename);
    else
       hmf = GetMetaFileW(filename);
    GetClientRect(hMainWnd, &r);
    width = r.right - r.left;
    height = r.bottom - r.top;
  }
  InvalidateRect( hMainWnd, NULL, TRUE );
}

static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
{
  switch (uMessage)
    {
    case WM_PAINT:
      {
	PAINTSTRUCT ps;
	BeginPaint(hwnd, &ps);
	SetMapMode(ps.hdc, MM_ANISOTROPIC);
	/* Set the window extent to a sane value in case the metafile doesn't */
	SetWindowExtEx(ps.hdc, width, height, NULL);
	SetViewportExtEx(ps.hdc, width, height, NULL);
	SetViewportOrgEx(ps.hdc, deltax, deltay, NULL);
       if (isEnhanced && enhmf)
       {
           RECT r;
           GetClientRect(hwnd, &r);
           PlayEnhMetaFile(ps.hdc, enhmf, &r);
       }
       else if (hmf)
           PlayMetaFile(ps.hdc, hmf);
	EndPaint(hwnd, &ps);
      }
      break;

    case WM_COMMAND: /* message: command from application menu */
        switch (LOWORD(wparam))
	{
	case IDM_OPEN:
	  {
              WCHAR filename[MAX_PATH];
              if (FileOpen(hwnd, filename, sizeof(filename)/sizeof(WCHAR)))
                  DoOpenFile(filename);
	  }
	  break;

	case IDM_SET_EXT_TO_WIN:
	  {
	    RECT r;
	    GetClientRect(hwnd, &r);
	    width = r.right - r.left;
	    height = r.bottom - r.top;
	    deltax = deltay = 0;
	    InvalidateRect( hwnd, NULL, TRUE );
	  }
	  break;


	case IDM_LEFT:
	  deltax += 100;
	  InvalidateRect( hwnd, NULL, TRUE );
	  break;
	case IDM_RIGHT:
	  deltax -= 100;
	  InvalidateRect( hwnd, NULL, TRUE );
	  break;
	case IDM_UP:
	  deltay += 100;
	  InvalidateRect( hwnd, NULL, TRUE );
	  break;
	case IDM_DOWN:
	  deltay -= 100;
	  InvalidateRect( hwnd, NULL, TRUE );
	  break;

	case IDM_EXIT:
	  DestroyWindow(hwnd);
	  break;

	default:
	  return DefWindowProcW(hwnd, uMessage, wparam, lparam);
	}
      break;

    case WM_DESTROY:  /* message: window being destroyed */
      PostQuitMessage(0);
      break;

    default:          /* Passes it on if unprocessed */
      return DefWindowProcW(hwnd, uMessage, wparam, lparam);
    }
    return 0;
}

static BOOL InitApplication(HINSTANCE hInstance)
{
  WNDCLASSEXW wc;

  /* Load the application description strings */
  LoadStringW(hInstance, IDS_DESCRIPTION, szTitle, sizeof(szTitle)/sizeof(WCHAR));

  /* Fill in window class structure with parameters that describe the
     main window */

  wc.cbSize        = sizeof(WNDCLASSEXW);
  wc.style         = CS_HREDRAW | CS_VREDRAW;             /* Class style(s) */
  wc.lpfnWndProc   = WndProc;                             /* Window Procedure */
  wc.cbClsExtra    = 0;                          /* No per-class extra data */
  wc.cbWndExtra    = 0;                         /* No per-window extra data */
  wc.hInstance     = hInstance;                      /* Owner of this class */
  wc.hIcon         = NULL;
  wc.hIconSm       = NULL;
  wc.hCursor       = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);           /* Default color */
  wc.lpszMenuName  = szAppName;                       /* Menu name from .rc */
  wc.lpszClassName = szAppName;                      /* Name to register as */

  if (!RegisterClassExW(&wc)) return FALSE;

  /* Call module specific initialization functions here */

  return TRUE;
}

static BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    /* Save the instance handle in a global variable for later use */
    hInst = hInstance;

    /* Create main window */
    hMainWnd = CreateWindowW(szAppName,          /* See RegisterClass() call */
                            szTitle,             /* window title */
                            WS_OVERLAPPEDWINDOW, /* Window style */
                            CW_USEDEFAULT, 0,    /* positioning */
                            CW_USEDEFAULT, 0,    /* size */
                            NULL,                /* Overlapped has no parent */
                            NULL,                /* Use the window class menu */
                            hInstance,
                            NULL);

    if (!hMainWnd)
        return FALSE;

    /* Call module specific instance initialization functions here */

    /* show the window, and paint it for the first time */
    ShowWindow(hMainWnd, nCmdShow);
    UpdateWindow(hMainWnd);

    return TRUE;
}

static void HandleCommandLine(LPWSTR cmdline)
{
    /* skip white space */
    while (*cmdline == ' ') cmdline++;

    if (*cmdline)
    {
        /* file name is passed on the command line */
        if (cmdline[0] == '"')
        {
            cmdline++;
            cmdline[lstrlenW(cmdline) - 1] = 0;
        }
        DoOpenFile(cmdline);
    }
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
    MSG msg;

    /* Other instances of app running? */
    if (!hPrevInstance)
    {
      /* stuff to be done once */
      if (!InitApplication(hInstance))
      {
        return FALSE;      /* exit */
      }
    }

    /* stuff to be done every time */
    if (!InitInstance(hInstance, nCmdShow))
    {
      return FALSE;
    }

    HandleCommandLine(lpCmdLine);

    /* Main loop */
    /* Acquire and dispatch messages until a WM_QUIT message is received */
    while (GetMessageW(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return msg.wParam;
}
