/*
 * Help Viewer
 *
 * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
 * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <string.h>
#include "winbase.h"
#include "windowsx.h"
#include "winhelp.h"
#include "winhelp_res.h"

static BOOL    WINHELP_RegisterWinClasses();
static LRESULT CALLBACK WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WINHELP_TextWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND, UINT, WPARAM, LPARAM);
static VOID    WINHELP_CheckPopup(UINT);
static BOOL    WINHELP_SplitLines(HWND hWnd, LPSIZE);
static VOID    WINHELP_InitFonts(HWND hWnd);
static VOID    WINHELP_DeleteLines(WINHELP_WINDOW*);
static VOID    WINHELP_DeleteWindow(WINHELP_WINDOW*);
static VOID    WINHELP_SetupText(HWND hWnd);
static BOOL    WINHELP_AppendText(WINHELP_LINE***, WINHELP_LINE_PART***,
				  LPSIZE, LPSIZE, INT*, INT, LPCSTR, UINT,
				  HFONT, COLORREF, HLPFILE_LINK*);
static WINHELP_LINE_PART* WINHELP_IsOverLink(HWND hWnd, WPARAM wParam, LPARAM lParam);

WINHELP_GLOBALS Globals = {3, 0, 0, 0, 0, 0};

static BOOL MacroTest = FALSE;

/***********************************************************************
 *
 *           WinMain
 */

int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
{
  MSG    msg;
  LONG   lHash = 0;

  Globals.hInstance = hInstance;

  /* Get options */
  while (*cmdline && (*cmdline == ' ' || *cmdline == '-'))
    {
      CHAR   option;
      LPCSTR topic_id;
      if (*cmdline++ == ' ') continue;

      option = *cmdline;
      if (option) cmdline++;
      while (*cmdline && *cmdline == ' ') cmdline++;
      switch(option)
	{
	case 'i':
	case 'I':
	  topic_id = cmdline;
	  while (*cmdline && *cmdline != ' ') cmdline++;
	  if (*cmdline) *cmdline++ = '\0';
	  lHash = HLPFILE_Hash(topic_id);
	  break;

	case '3':
	case '4':
	  Globals.wVersion = option - '0';
	  break;

	case 't':
	  MacroTest = TRUE;
	  break;
	}
    }

  /* Create primary window */
  WINHELP_RegisterWinClasses();
  WINHELP_CreateHelpWindow(cmdline, lHash, "main", FALSE, NULL, NULL, show);

  /* Message loop */
  while (GetMessage (&msg, 0, 0, 0))
    {
      TranslateMessage (&msg);
      DispatchMessage (&msg);
    }
  return 0;
}

/***********************************************************************
 *
 *           RegisterWinClasses
 */

static BOOL WINHELP_RegisterWinClasses()
{
  WNDCLASS class_main, class_button_box, class_text, class_shadow;

  class_main.style               = CS_HREDRAW | CS_VREDRAW;
  class_main.lpfnWndProc         = WINHELP_MainWndProc;
  class_main.cbClsExtra          = 0;
  class_main.cbWndExtra          = sizeof(LONG);
  class_main.hInstance           = Globals.hInstance;
  class_main.hIcon               = LoadIcon (0, IDI_APPLICATION);
  class_main.hCursor             = LoadCursor (0, IDC_ARROW);
  class_main.hbrBackground       = GetStockObject (WHITE_BRUSH);
  class_main.lpszMenuName        = 0;
  class_main.lpszClassName       = MAIN_WIN_CLASS_NAME;

  class_button_box               = class_main;
  class_button_box.lpfnWndProc   = WINHELP_ButtonBoxWndProc;
  class_button_box.hbrBackground = GetStockObject(GRAY_BRUSH);
  class_button_box.lpszClassName = BUTTON_BOX_WIN_CLASS_NAME;

  class_text = class_main;
  class_text.lpfnWndProc         = WINHELP_TextWndProc;
  class_text.lpszClassName       = TEXT_WIN_CLASS_NAME;

  class_shadow = class_main;
  class_shadow.lpfnWndProc       = DefWindowProc;
  class_shadow.hbrBackground     = GetStockObject(GRAY_BRUSH);
  class_shadow.lpszClassName     = SHADOW_WIN_CLASS_NAME;

  return (RegisterClass(&class_main) &&
	  RegisterClass(&class_button_box) &&
	  RegisterClass(&class_text) &&
	  RegisterClass(&class_shadow));
}

/***********************************************************************
 *
 *           WINHELP_CreateHelpWindow
 */

VOID WINHELP_CreateHelpWindow(LPCSTR lpszFile, LONG lHash, LPCSTR lpszWindow,
			      BOOL bPopup, HWND hParentWnd, LPPOINT mouse, INT nCmdShow)
{
  CHAR    szCaption[MAX_STRING_LEN];
  CHAR    szContents[MAX_STRING_LEN];
  CHAR    szSearch[MAX_STRING_LEN];
  CHAR    szBack[MAX_STRING_LEN];
  CHAR    szHistory[MAX_STRING_LEN];
  SIZE    size   = {CW_USEDEFAULT, CW_USEDEFAULT};
  POINT   origin = {240, 0};
  LPSTR   ptr;
  HGLOBAL handle;
  WINHELP_WINDOW *win, *oldwin;
  HLPFILE_PAGE   *page;
  HLPFILE_MACRO  *macro;
  HWND hWnd;
  BOOL bPrimary;

  if (bPopup)
    lpszWindow = NULL;
  else if (!lpszWindow || !lpszWindow[0])
    lpszWindow = Globals.active_win->lpszName;
  bPrimary = lpszWindow && !lstrcmpi(lpszWindow, "main");

  /* Read help file */
  if (lpszFile[0])
    {
      page = lHash ? HLPFILE_PageByHash(lpszFile, lHash) : HLPFILE_Contents(lpszFile);

      /* Add Suffix `.hlp' */
      if (!page && lstrcmpi(lpszFile + strlen(lpszFile) - 4, ".hlp"))
	{
	  CHAR      szFile_hlp[MAX_PATHNAME_LEN];

	  lstrcpyn(szFile_hlp, lpszFile, sizeof(szFile_hlp) - 4);
	  szFile_hlp[sizeof(szFile_hlp) - 5] = '\0';
	  lstrcat(szFile_hlp, ".hlp");

	  page = lHash ? HLPFILE_PageByHash(szFile_hlp, lHash) : HLPFILE_Contents(szFile_hlp);
	  if (!page)
	    {
	      WINHELP_MessageBoxIDS_s(HLPFILE_ERROR_s, lpszFile, WHERROR, MB_OK);
	      if (Globals.win_list) return;
	    }
	}
    }
  else page = 0;

  /* Calculate horizontal size and position of a popup window */
  if (bPopup)
    {
      RECT parent_rect;
      GetWindowRect(hParentWnd, &parent_rect);
      size.cx = (parent_rect.right  - parent_rect.left) / 2;

      origin = *mouse;
      ClientToScreen(hParentWnd, &origin);
      origin.x -= size.cx / 2;
      origin.x  = min(origin.x, GetSystemMetrics(SM_CXSCREEN) - size.cx);
      origin.x  = max(origin.x, 0);
    }

  /* Initialize WINHELP_WINDOW struct */
  handle = GlobalAlloc(GMEM_FIXED, sizeof(WINHELP_WINDOW) +
		       (lpszWindow ? strlen(lpszWindow) + 1 : 0));
  if (!handle) return;
  win = GlobalLock(handle);
  win->hSelf = handle;
  win->next  = Globals.win_list;
  Globals.win_list = win;
  if (lpszWindow)
    {
      ptr = GlobalLock(handle);
      ptr += sizeof(WINHELP_WINDOW);
      lstrcpy(ptr, (LPSTR) lpszWindow);
      win->lpszName = ptr;
    }
  else win->lpszName = NULL;

  win->page = page;
  win->first_button = 0;
  win->first_line = 0;
  win->hMainWnd = 0;
  win->hButtonBoxWnd = 0;
  win->hTextWnd = 0;
  win->hShadowWnd = 0;

  win->hArrowCur = LoadCursorA(0, IDC_ARROWA);
  win->hHandCur = LoadCursorA(0, IDC_HANDA);

  Globals.active_win = win;

  /* Initialize default pushbuttons */
  if (MacroTest && !bPopup)
    MACRO_CreateButton("BTN_TEST", "&Test", "MacroTest");
  if (bPrimary && page)
    {
      LoadString(Globals.hInstance, 0x126, szContents, sizeof(szContents));
      LoadString(Globals.hInstance, 0x127,   szSearch,   sizeof(szSearch));
      LoadString(Globals.hInstance, 0x128,     szBack,     sizeof(szBack));
      LoadString(Globals.hInstance, 0x129,  szHistory,  sizeof(szHistory));
      MACRO_CreateButton("BTN_CONTENTS", szContents, "Contents()");
      MACRO_CreateButton("BTN_SEARCH",   szSearch,   "Search()");
      MACRO_CreateButton("BTN_BACK",     szBack,     "Back()");
      MACRO_CreateButton("BTN_HISTORY",  szHistory,  "History()");
    }

  /* Initialize file specific pushbuttons */
  if (!bPopup && page)
    for (macro = page->file->first_macro; macro; macro = macro->next)
      MACRO_ExecuteMacro(macro->lpszMacro);

  /* Reuse existing window */
  if (lpszWindow)
    for (oldwin = win->next; oldwin; oldwin = oldwin->next)
      if (oldwin->lpszName && !lstrcmpi(oldwin->lpszName, lpszWindow))
	{
	  WINHELP_BUTTON *button;

	  win->hMainWnd      = oldwin->hMainWnd;
	  win->hButtonBoxWnd = oldwin->hButtonBoxWnd;
	  win->hTextWnd      = oldwin->hTextWnd;
	  oldwin->hMainWnd = oldwin->hButtonBoxWnd = oldwin->hTextWnd = 0;

	  SetWindowLong(win->hMainWnd,      0, (LONG) win);
	  SetWindowLong(win->hButtonBoxWnd, 0, (LONG) win);
	  SetWindowLong(win->hTextWnd,      0, (LONG) win);

	  WINHELP_InitFonts(win->hMainWnd);

	  if (page) {
	    SetWindowText(win->hMainWnd, page->file->lpszTitle);
          }

	  WINHELP_SetupText(win->hTextWnd);
	  InvalidateRect(win->hTextWnd, NULL, TRUE);
	  SendMessage(win->hMainWnd, WM_USER, 0, 0);
	  UpdateWindow(win->hTextWnd);


	  for (button = oldwin->first_button; button; button = button->next)
	    DestroyWindow(button->hWnd);

	  WINHELP_DeleteWindow(oldwin);
	  return;
	}

  /* Create main Window */
  if (!page) LoadString(Globals.hInstance, 0x120, szCaption, sizeof(szCaption));
  hWnd = CreateWindow (bPopup ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME,
		       page ? page->file->lpszTitle : szCaption,
		       bPopup ? WS_POPUPWINDOW | WS_BORDER : WS_OVERLAPPEDWINDOW,
		       origin.x, origin.y, size.cx, size.cy,
		       0, bPrimary ? LoadMenu(Globals.hInstance, MAIN_MENU) : 0,
		       Globals.hInstance, win);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);
}

/***********************************************************************
 *
 *           WINHELP_MainWndProc
 */

static LRESULT CALLBACK WINHELP_MainWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  WINHELP_WINDOW *win;
  WINHELP_BUTTON *button;
  RECT rect, button_box_rect;
  INT  text_top;

  WINHELP_CheckPopup(msg);

  switch (msg)
    {
    case WM_NCCREATE:
      win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams;
      SetWindowLong(hWnd, 0, (LONG) win);
      win->hMainWnd = hWnd;
      break;

    case WM_CREATE:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);

      /* Create button box and text Window */
      CreateWindow(BUTTON_BOX_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE,
		   0, 0, 0, 0, hWnd, 0, Globals.hInstance, win);

      CreateWindow(TEXT_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE,
		   0, 0, 0, 0, hWnd, 0, Globals.hInstance, win);

      /* Fall through */
    case WM_USER:
    case WM_WINDOWPOSCHANGED:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
      GetClientRect(hWnd, &rect);

      /* Update button box and text Window */
      SetWindowPos(win->hButtonBoxWnd, HWND_TOP,
		   rect.left, rect.top,
		   rect.right - rect.left,
		   rect.bottom - rect.top, 0);

      GetWindowRect(win->hButtonBoxWnd, &button_box_rect);
      text_top = rect.top + button_box_rect.bottom - button_box_rect.top;

      SetWindowPos(win->hTextWnd, HWND_TOP,
		   rect.left, text_top,
		   rect.right - rect.left,
		   rect.bottom - text_top, 0);

      break;

    case WM_COMMAND:
      Globals.active_win = win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
      switch (wParam)
	{
	  /* Menu FILE */
	case 0x101:			MACRO_FileOpen();       break;
	case 0x104:			MACRO_Print();          break;
	case 0x106:			MACRO_PrinterSetup();   break;
	case 0x108:			MACRO_Exit();           break;

	  /* Menu EDIT */
	case 0x10A:     	MACRO_CopyDialog();     break;
	case 0x10C:        	MACRO_Annotate();       break;

	  /* Menu Bookmark */
	case 0x10E:			MACRO_BookmarkDefine(); break;

	  /* Menu Help */
	case 0x110:			MACRO_HelpOn();         break;
	case 0x111:			MACRO_HelpOnTop();      break;

	  /* Menu Info */
	case 0x113:			MACRO_About();          break;

	case 0x114:
	  ShellAbout(hWnd, "WINE", "Help", 0);
	  break;

	default:
	  /* Buttons */
	  for (button = win->first_button; button; button = button->next)
	    if (wParam == button->wParam) break;
	  if (button)
	    MACRO_ExecuteMacro(button->lpszMacro);
	  else
	    WINHELP_MessageBoxIDS(0x124, 0x121, MB_OK);
	  break;
	}
      break;
    }

  return DefWindowProc (hWnd, msg, wParam, lParam);
}

/***********************************************************************
 *
 *           WINHELP_ButtonBoxWndProc
 */

static LRESULT CALLBACK WINHELP_ButtonBoxWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  WINDOWPOS      *winpos;
  WINHELP_WINDOW *win;
  WINHELP_BUTTON *button;
  SIZE button_size;
  INT  x, y;

  WINHELP_CheckPopup(msg);

  switch(msg)
    {
    case WM_NCCREATE:
      win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams;
      SetWindowLong(hWnd, 0, (LONG) win);
      win->hButtonBoxWnd = hWnd;
      break;

    case WM_WINDOWPOSCHANGING:
      winpos = (WINDOWPOS*) lParam;
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);

      /* Update buttons */
      button_size.cx = 0;
      button_size.cy = 0;
      for (button = win->first_button; button; button = button->next)
	{
	  HDC  hDc;
	  SIZE textsize;
	  if (!button->hWnd)
	    button->hWnd = CreateWindow(STRING_BUTTON, (LPSTR) button->lpszName,
					WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
					0, 0, 0, 0,
					hWnd, (HMENU) button->wParam,
					Globals.hInstance, 0);
	  hDc = GetDC(button->hWnd);
	  GetTextExtentPoint(hDc, button->lpszName,
			     lstrlen(button->lpszName), &textsize);
	  ReleaseDC(button->hWnd, hDc);

	  button_size.cx = max(button_size.cx, textsize.cx + BUTTON_CX);
	  button_size.cy = max(button_size.cy, textsize.cy + BUTTON_CY);
	}

      x = 0;
      y = 0;
      for (button = win->first_button; button; button = button->next)
	{
	  SetWindowPos(button->hWnd, HWND_TOP, x, y, button_size.cx, button_size.cy, 0);

	  if (x + 2 * button_size.cx <= winpos->cx)
	    x += button_size.cx;
	  else
	    x = 0, y += button_size.cy;
	}
      winpos->cy = y + (x ? button_size.cy : 0);
      break;

    case WM_COMMAND:
      SendMessage(GetParent(hWnd), msg, wParam, lParam);
      break;
    }

  return(DefWindowProc(hWnd, msg, wParam, lParam));
}

/***********************************************************************
 *
 *           WINHELP_TextWndProc
 */

static LRESULT CALLBACK WINHELP_TextWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  WINHELP_WINDOW    *win;
  WINHELP_LINE      *line;
  WINHELP_LINE_PART *part;
  WINDOWPOS         *winpos;
  PAINTSTRUCT        ps;
  HDC   hDc;
  POINT mouse;
  INT   scroll_pos;
  HWND  hPopupWnd;
  BOOL  bExit;

  if (msg != WM_LBUTTONDOWN)
    WINHELP_CheckPopup(msg);

  switch (msg)
    {
    case WM_NCCREATE:
      win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams;
      SetWindowLong(hWnd, 0, (LONG) win);
      win->hTextWnd = hWnd;
      if (!win->lpszName) Globals.hPopupWnd = win->hMainWnd = hWnd;
      WINHELP_InitFonts(hWnd);
      break;

    case WM_CREATE:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);

      /* Calculate vertical size and position of a popup window */
      if (!win->lpszName)
	{
	  POINT origin;
	  RECT old_window_rect;
	  RECT old_client_rect;
	  SIZE old_window_size;
	  SIZE old_client_size;
	  SIZE new_client_size;
	  SIZE new_window_size;

	  GetWindowRect(hWnd, &old_window_rect);
	  origin.x = old_window_rect.left;
	  origin.y = old_window_rect.top;
	  old_window_size.cx = old_window_rect.right  - old_window_rect.left;
	  old_window_size.cy = old_window_rect.bottom - old_window_rect.top;

	  GetClientRect(hWnd, &old_client_rect);
	  old_client_size.cx = old_client_rect.right  - old_client_rect.left;
	  old_client_size.cy = old_client_rect.bottom - old_client_rect.top;

	  new_client_size = old_client_size;
	  WINHELP_SplitLines(hWnd, &new_client_size);

	  if (origin.y + POPUP_YDISTANCE + new_client_size.cy <= GetSystemMetrics(SM_CYSCREEN))
	    origin.y += POPUP_YDISTANCE;
	  else
	    origin.y -= POPUP_YDISTANCE + new_client_size.cy;

	  new_window_size.cx = old_window_size.cx - old_client_size.cx + new_client_size.cx;
	  new_window_size.cy = old_window_size.cy - old_client_size.cy + new_client_size.cy;

	  win->hShadowWnd =
	    CreateWindow(SHADOW_WIN_CLASS_NAME, "", WS_POPUP | WS_VISIBLE,
			 origin.x + SHADOW_DX, origin.y + SHADOW_DY,
			 new_window_size.cx, new_window_size.cy,
			 0, 0, Globals.hInstance, 0);

	  SetWindowPos(hWnd, HWND_TOP, origin.x, origin.y,
		       new_window_size.cx, new_window_size.cy,
		       SWP_NOZORDER | SWP_NOACTIVATE);
	  ShowWindow(win->hShadowWnd, SW_NORMAL);
	}
      break;

    case WM_WINDOWPOSCHANGED:
      winpos = (WINDOWPOS*) lParam;
      if (!(winpos->flags & SWP_NOSIZE)) WINHELP_SetupText(hWnd);
      break;

    case WM_VSCROLL:
      {
	BOOL  update = TRUE;
	RECT  rect;
	INT   Min, Max;
	INT   CurPos = GetScrollPos(hWnd, SB_VERT);
	GetScrollRange(hWnd, SB_VERT, &Min, &Max);
	GetClientRect(hWnd, &rect);

	switch (wParam & 0xffff)
	  {
	  case SB_THUMBTRACK:
	  case SB_THUMBPOSITION: CurPos  = wParam >> 16;                   break;
	  case SB_TOP:           CurPos  = Min;                            break;
	  case SB_BOTTOM:        CurPos  = Max;                            break;
	  case SB_PAGEUP:        CurPos -= (rect.bottom - rect.top) / 2;   break;
	  case SB_PAGEDOWN:      CurPos += (rect.bottom - rect.top) / 2;   break;
	  case SB_LINEUP:        CurPos -= GetSystemMetrics(SM_CXVSCROLL); break;
	  case SB_LINEDOWN:      CurPos += GetSystemMetrics(SM_CXVSCROLL); break;
	  default: update = FALSE;
	  }
	if (update)
	  {
	    INT dy = GetScrollPos(hWnd, SB_VERT) - CurPos;
	    SetScrollPos(hWnd, SB_VERT, CurPos, TRUE);
	    ScrollWindow(hWnd, 0, dy, NULL, NULL);
	    UpdateWindow(hWnd);
	  }
      }
      break;

    case WM_PAINT:
      hDc = BeginPaint (hWnd, &ps);
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
      scroll_pos = GetScrollPos(hWnd, SB_VERT);

      for (line = win->first_line; line; line = line->next)
	for (part = &line->first_part; part; part = part->next)
	  {
	    SelectObject(hDc, part->hFont);
	    SetTextColor(hDc, part->color);
	    TextOut(hDc, part->rect.left, part->rect.top - scroll_pos,
		    (LPSTR) part->lpsText, part->wTextLen);
	  }

      EndPaint (hWnd, &ps);
      break;

    case WM_MOUSEMOVE:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);

      if(WINHELP_IsOverLink(hWnd, wParam, lParam))
        SetCursor(win->hHandCur); /* set to hand pointer cursor to indicate a link */
      else
        SetCursor(win->hArrowCur); /* set to hand pointer cursor to indicate a link */

      break;

    case WM_LBUTTONDOWN:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);

      hPopupWnd = Globals.hPopupWnd;
      Globals.hPopupWnd = 0;

      part = WINHELP_IsOverLink(hWnd, wParam, lParam);
      if(part)
      {
        mouse.x = LOWORD(lParam);
        mouse.y = HIWORD(lParam);

        WINHELP_CreateHelpWindow(part->link.lpszPath, part->link.lHash, NULL,
				     part->link.bPopup, hWnd, &mouse,  SW_NORMAL);
      }

      if (hPopupWnd)
	DestroyWindow(hPopupWnd);
      break;

    case WM_NCDESTROY:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);

      if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0;

      bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main"));

      WINHELP_DeleteWindow(win);

      if (bExit) MACRO_Exit();

      if (!Globals.win_list)
	PostQuitMessage (0);
      break;
    }

  return DefWindowProc (hWnd, msg, wParam, lParam);
}

/***********************************************************************
 *
 *           SetupText
 */

static VOID WINHELP_SetupText(HWND hWnd)
{
  HDC  hDc = GetDC(hWnd);
  RECT rect;
  SIZE newsize;

  ShowScrollBar(hWnd, SB_VERT, FALSE);
  if (!WINHELP_SplitLines(hWnd, NULL))
    {
      ShowScrollBar(hWnd, SB_VERT, TRUE);
      GetClientRect(hWnd, &rect);

      WINHELP_SplitLines(hWnd, &newsize);
      SetScrollRange(hWnd, SB_VERT, 0, rect.top + newsize.cy - rect.bottom, TRUE);
    }
  else SetScrollPos(hWnd, SB_VERT, 0, FALSE);

  ReleaseDC(hWnd, hDc);
}

/***********************************************************************
 *
 *           WINHELP_SplitLines
 */

static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE newsize)
{
  WINHELP_WINDOW     *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
  HLPFILE_PARAGRAPH  *p;
  WINHELP_LINE      **line = &win->first_line;
  WINHELP_LINE_PART **part = 0;
  INT                 line_ascent = 0;
  SIZE                space;
  RECT                rect;
  HDC                 hDc;

  if (newsize) newsize->cx = newsize->cy = 0;

  if (!win->page) return TRUE;

  WINHELP_DeleteLines(win);

  GetClientRect(hWnd, &rect);

  rect.top    += INTERNAL_BORDER_WIDTH;
  rect.left   += INTERNAL_BORDER_WIDTH;
  rect.right  -= INTERNAL_BORDER_WIDTH;
  rect.bottom -= INTERNAL_BORDER_WIDTH;


  space.cy = rect.top;
  space.cx = rect.left;

  hDc = GetDC(hWnd);

  for (p = win->page->first_paragraph; p; p = p->next)
    {
      TEXTMETRIC tm;
      SIZE textsize = {0, 0};
      LPCSTR text    = p->lpszText;
      UINT len    = strlen(text);
      UINT indent = 0;

      UINT  wFont      = (p->wFont < win->fonts_len) ? p->wFont : 0;
      BOOL  bUnderline = p->link && !p->link->bPopup;
      HFONT hFont      = win->fonts[wFont][bUnderline ? 1 : 0];

      COLORREF       color = RGB(0, 0, 0);
      if (p->link)   color = RGB(0, 0x80, 0);
      if (p->bDebug) color = RGB(0xff, 0, 0);

      SelectObject(hDc, hFont);

      GetTextMetrics (hDc, &tm);

      if (p->wIndent)
	{
	  indent = p->wIndent * 5 * tm.tmAveCharWidth;
	  if (!part)
	    space.cx = rect.left + indent - 2 * tm.tmAveCharWidth;
	}

      if (p->wVSpace)
	{
	  part = 0;
	  space.cx = rect.left + indent;
	  space.cy += (p->wVSpace - 1) * tm.tmHeight;
	}

      if (p->wHSpace)
	{
	  space.cx += p->wHSpace * 2 * tm.tmAveCharWidth;
	}

      while (len)
	{
	  INT free_width = rect.right - (part ? (*line)->rect.right : rect.left) - space.cx;
	  UINT low = 0, curr = len, high = len, textlen = 0;

	  if (free_width > 0)
	    {
	      while (1)
		{
		  GetTextExtentPoint(hDc, text, curr, &textsize);

		  if (textsize.cx <= free_width) low = curr;
		  else high = curr;

		  if (high <= low + 1) break;

		  if (textsize.cx) curr = (curr * free_width) / textsize.cx;
		  if (curr <= low) curr = low + 1;
		  else if (curr >= high) curr = high - 1;
		}
	      textlen = low;
	      while (textlen && text[textlen] && text[textlen] != ' ') textlen--;
	    }
	  if (!part && !textlen) textlen = max(low, 1);

	  if (free_width <= 0 || !textlen)
	    {
	      part = 0;
	      space.cx = rect.left + indent;
	      space.cx = min(space.cx, rect.right - rect.left - 1);
	      continue;
	    }

	  if (!WINHELP_AppendText(&line, &part, &space, &textsize,
				  &line_ascent, tm.tmAscent,
				  text, textlen, hFont, color, p->link) ||
	      (!newsize && (*line)->rect.bottom > rect.bottom))
	    {
	      ReleaseDC(hWnd, hDc);
	      return FALSE;
	    }

	  if (newsize)
	    newsize->cx = max(newsize->cx, (*line)->rect.right + INTERNAL_BORDER_WIDTH);

	  len -= textlen;
	  text += textlen;
	  if (text[0] == ' ') text++, len--;
	}
    }

  if (newsize)
    newsize->cy = (*line)->rect.bottom + INTERNAL_BORDER_WIDTH;

  ReleaseDC(hWnd, hDc);
  return TRUE;
}

/***********************************************************************
 *
 *           WINHELP_AppendText
 */

static BOOL WINHELP_AppendText(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp,
			       LPSIZE space, LPSIZE textsize,
			       INT *line_ascent, INT ascent,
			       LPCSTR text, UINT textlen,
			       HFONT font, COLORREF color, HLPFILE_LINK *link)
{
  HGLOBAL handle;
  WINHELP_LINE      *line;
  WINHELP_LINE_PART *part;
  LPSTR ptr;

  if (!*partp) /* New line */
    {
      *line_ascent  = ascent;

      handle = GlobalAlloc(GMEM_FIXED, sizeof(WINHELP_LINE) + textlen +
			   (link ? lstrlen(link->lpszPath) + 1 : 0));
      if (!handle) return FALSE;
      line          = GlobalLock(handle);
      line->next    = 0;
      part          = &line->first_part;
      ptr           = GlobalLock(handle);
      ptr          += sizeof(WINHELP_LINE);

      line->rect.top    = (**linep ? (**linep)->rect.bottom : 0) + space->cy;
      line->rect.bottom = line->rect.top;
      line->rect.left   = space->cx;
      line->rect.right  = space->cx;

      if (**linep) *linep = &(**linep)->next;
      **linep = line;
      space->cy = 0;
    }
  else /* Same line */
    {
      line = **linep;

      if (*line_ascent < ascent)
	{
	  WINHELP_LINE_PART *p;
	  for (p = &line->first_part; p; p = p->next)
	    {
	      p->rect.top    += ascent - *line_ascent;
	      p->rect.bottom += ascent - *line_ascent;
	    }
	  line->rect.bottom += ascent - *line_ascent;
	  *line_ascent = ascent;
	}

      handle = GlobalAlloc(GMEM_FIXED, sizeof(WINHELP_LINE_PART) + textlen +
			   (link ? lstrlen(link->lpszPath) + 1 : 0));
      if (!handle) return FALSE;
      part    = GlobalLock(handle);
      **partp = part;
      ptr     = GlobalLock(handle);
      ptr    += sizeof(WINHELP_LINE_PART);
    }

  memcpy(ptr, text, textlen);
  part->rect.left     = line->rect.right + (*partp ? space->cx : 0);
  part->rect.right    = part->rect.left + textsize->cx;
  line->rect.right    = part->rect.right;
  part->rect.top      =
    ((*partp) ? line->rect.top : line->rect.bottom) + *line_ascent - ascent;
  part->rect.bottom   = part->rect.top + textsize->cy;
  line->rect.bottom   = max(line->rect.bottom, part->rect.bottom);
  part->hSelf         = handle;
  part->lpsText       = ptr;
  part->wTextLen      = textlen;
  part->hFont         = font;
  part->color         = color;
  if (link)
    {
      strcpy(ptr + textlen, link->lpszPath);
      part->link.lpszPath = ptr + textlen;
      part->link.lHash    = link->lHash;
      part->link.bPopup   = link->bPopup;
    }
  else part->link.lpszPath = 0;

  part->next          = 0;
  *partp              = &part->next;

  space->cx = 0;

  return TRUE;
}

/***********************************************************************
 *
 *           WINHELP_CheckPopup
 */

static VOID WINHELP_CheckPopup(UINT msg)
{
  if (!Globals.hPopupWnd) return;

  switch (msg)
    {
    case WM_COMMAND:
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_NCLBUTTONDOWN:
    case WM_NCMBUTTONDOWN:
    case WM_NCRBUTTONDOWN:
      DestroyWindow(Globals.hPopupWnd);
      Globals.hPopupWnd = 0;
    }
}

/***********************************************************************
 *
 *           WINHELP_DeleteLines
 */

static VOID WINHELP_DeleteLines(WINHELP_WINDOW *win)
{
  WINHELP_LINE      *line, *next_line;
  WINHELP_LINE_PART *part, *next_part;
  for(line = win->first_line; line; line = next_line)
    {
      next_line = line->next;
      for(part = &line->first_part; part; part = next_part)
	{
	  next_part = part->next;
	  GlobalFree(part->hSelf);
	}
    }
  win->first_line = 0;
}

/***********************************************************************
 *
 *           WINHELP_DeleteWindow
 */

static VOID WINHELP_DeleteWindow(WINHELP_WINDOW *win)
{
  WINHELP_WINDOW **w;

  for (w = &Globals.win_list; *w; w = &(*w)->next)
    if (*w == win)
      {
	*w = win->next;
	break;
      }

  if (win->hShadowWnd) DestroyWindow(win->hShadowWnd);
  HLPFILE_FreeHlpFilePage(win->page);
  WINHELP_DeleteLines(win);
  GlobalFree(win->hSelf);
}

/***********************************************************************
 *
 *           WINHELP_InitFonts
 */

static VOID WINHELP_InitFonts(HWND hWnd)
{
  WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
  LOGFONT logfontlist[] = {
    {-10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
    {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
    {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
    {-12, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
    {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
    {-10, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"},
    { -8, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}};
#define FONTS_LEN (sizeof(logfontlist)/sizeof(*logfontlist))

  static HFONT fonts[FONTS_LEN][2];
  static BOOL init = 0;

  win->fonts_len = FONTS_LEN;
  win->fonts = fonts;

  if (!init)
    {
      INT i;

      for(i = 0; i < FONTS_LEN; i++)
	{
	  LOGFONT logfont = logfontlist[i];

	  fonts[i][0] = CreateFontIndirect(&logfont);
	  logfont.lfUnderline = 1;
	  fonts[i][1] = CreateFontIndirect(&logfont);
	}

      init = 1;
    }
}

/***********************************************************************
 *
 *           WINHELP_MessageBoxIDS
 */

INT WINHELP_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
{
  CHAR text[MAX_STRING_LEN];
  CHAR title[MAX_STRING_LEN];

  LoadString(Globals.hInstance, ids_text, text, sizeof(text));
  LoadString(Globals.hInstance, ids_title, title, sizeof(title));

  return(MessageBox(0, text, title, type));
}

/***********************************************************************
 *
 *           MAIN_MessageBoxIDS_s
 */

INT WINHELP_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
{
  CHAR text[MAX_STRING_LEN];
  CHAR title[MAX_STRING_LEN];
  CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];

  LoadString(Globals.hInstance, ids_text, text, sizeof(text));
  LoadString(Globals.hInstance, ids_title, title, sizeof(title));
  wsprintf(newtext, text, str);

  return(MessageBox(0, newtext, title, type));
}

WINHELP_LINE_PART* WINHELP_IsOverLink(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
  WINHELP_WINDOW* win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
  POINT mouse;
  WINHELP_LINE      *line;
  WINHELP_LINE_PART *part;
  int scroll_pos = GetScrollPos(hWnd, SB_VERT);

  mouse.x = LOWORD(lParam);
  mouse.y = HIWORD(lParam);
  for (line = win->first_line; line; line = line->next)
  {
    for (part = &line->first_part; part; part = part->next)
    {
      if (part->link.lpszPath &&
	   part->rect.left   <= mouse.x &&
	   part->rect.right  >= mouse.x &&
	   part->rect.top    <= mouse.y + scroll_pos &&
	   part->rect.bottom >= mouse.y + scroll_pos)
      {
        return part;
      }
    }
  }

  return NULL;
}

/* Local Variables:    */
/* c-file-style: "GNU" */
/* End:                */
