/*
 * 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[MAX_PATH];
static WCHAR szFileTitle[MAX_PATH];

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))) {
    GlobalFree(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 ;
  GlobalFree(lpData);
  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 void UpdateWindowCaption(void)
{
  WCHAR szCaption[MAX_PATH];
  WCHAR szView[MAX_PATH];
  static const WCHAR hyphenW[] = { ' ','-',' ',0 };

  LoadStringW(hInst, IDS_DESCRIPTION, szView, sizeof(szView)/sizeof(WCHAR));

  if (szFileTitle[0] != '\0')
  {
    lstrcpyW(szCaption, szFileTitle);
    LoadStringW(hInst, IDS_DESCRIPTION, szView, sizeof(szView)/sizeof(WCHAR));
    lstrcatW(szCaption, hyphenW);
    lstrcatW(szCaption, szView);
  }
  else
    lstrcpyW(szCaption, szView);

  SetWindowTextW(hMainWnd, szCaption);
}

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)))
              {
                  szFileTitle[0] = 0;
                  GetFileTitleW(filename, szFileTitle, sizeof(szFileTitle)/sizeof(WCHAR));
                  DoOpenFile(filename);
                  UpdateWindowCaption();
              }
	  }
	  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;
        }
        szFileTitle[0] = 0;
        GetFileTitleW(cmdline, szFileTitle, sizeof(szFileTitle)/sizeof(WCHAR));
        DoOpenFile(cmdline);
        UpdateWindowCaption();
    }
}

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;
}
