/*
 * Help Viewer
 *
 * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
 */

#include <stdio.h>
#include "windows.h"
#ifdef WINELIB
#include "resource.h"
#include "options.h"
#include "shell.h"
#endif
#include "winhelp.h"

VOID LIBWINE_Register_De(void);
VOID LIBWINE_Register_En(void);
VOID LIBWINE_Register_Fi(void);
VOID LIBWINE_Register_Fr(void);
VOID LIBWINE_Register_It(void);
VOID LIBWINE_Register_Ko(void);
VOID LIBWINE_Register_Hu(void);
VOID LIBWINE_Register_Va(void);

static BOOL    WINHELP_RegisterWinClasses();
static LRESULT WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT WINHELP_TextWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT 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*);

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

static BOOL MacroTest = FALSE;

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

int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
{
  LPCSTR opt_lang = "En";
  CHAR   lang[3];
  MSG    msg;
  LONG   lHash = 0;
  INT    langnum;

#if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR)
  /* Register resources */
  LIBWINE_Register_De();
  LIBWINE_Register_En();
  LIBWINE_Register_Fi();
  LIBWINE_Register_Fr();
  LIBWINE_Register_It();
  LIBWINE_Register_Ko();
  LIBWINE_Register_Hu();
  LIBWINE_Register_Va();
#endif

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

#ifdef WINELIB
  opt_lang = Languages[Options.language].name;
#endif

  /* Find language specific string table */
  for (langnum = 0; langnum <= MAX_LANGUAGE_NUMBER; langnum++)
    {
      Globals.wStringTableOffset = langnum * 0x100;
      if (LoadString(hInstance, IDS_LANGUAGE_ID, lang, sizeof(lang)) &&
	  !lstrcmp(opt_lang, lang))
	break;
    }
  if (langnum > MAX_LANGUAGE_NUMBER)
    {
      /* Find fallback language */
      for (langnum = 0; langnum <= MAX_LANGUAGE_NUMBER; langnum++)
	{
	  Globals.wStringTableOffset = langnum * 0x100;
	  if (LoadString(hInstance, IDS_LANGUAGE_ID, lang, sizeof(lang)))
	    break;
	}
      if (langnum > MAX_LANGUAGE_NUMBER)
	{
	MessageBox(0, "No language found", "FATAL ERROR", MB_OK);
	return(1);
	}
    }

  /* Change Resource names */
  lstrcpyn(STRING_MENU_Xx + lstrlen(STRING_MENU_Xx) - 2, lang, 3);

  /* 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(IDS_HLPFILE_ERROR_s, lpszFile, IDS_ERROR, 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;

  Globals.active_win = win;

  /* Initialize default pushbuttons */
  if (MacroTest && !bPopup)
    MACRO_CreateButton("BTN_TEST", "&Test", "MacroTest");
  if (bPrimary && page)
    {
      LoadString(Globals.hInstance, IDS_CONTENTS, szContents, sizeof(szContents));
      LoadString(Globals.hInstance, IDS_SEARCH,   szSearch,   sizeof(szSearch));
      LoadString(Globals.hInstance, IDS_BACK,     szBack,     sizeof(szBack));
      LoadString(Globals.hInstance, IDS_HISTORY,  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, IDS_WINE_HELP, 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, STRING_MENU_Xx) : 0,
		       Globals.hInstance, win);

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

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

static LRESULT 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 WH_OPEN:            MACRO_FileOpen();       break;
	case WH_PRINT:           MACRO_Print();          break;
	case WH_PRINTER_SETUP:   MACRO_PrinterSetup();   break;
	case WH_EXIT:            MACRO_Exit();           break;

	  /* Menu EDIT */
	case WH_COPY_DIALOG:     MACRO_CopyDialog();     break;
	case WH_ANNOTATE:        MACRO_Annotate();       break;

	  /* Menu Bookmark */
	case WH_BOOKMARK_DEFINE: MACRO_BookmarkDefine(); break;

	  /* Menu Help */
	case WH_HELP_ON_HELP:    MACRO_HelpOn();         break;
	case WH_HELP_ON_TOP:     MACRO_HelpOnTop();      break;

	  /* Menu Info */
	case WH_ABOUT:           MACRO_About();          break;

	case WH_ABOUT_WINE: 
	  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(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
	  break;
	}
      break;
    }

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

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

static LRESULT 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 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_LBUTTONDOWN:
      win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0);
      scroll_pos = GetScrollPos(hWnd, SB_VERT);

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

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

  hmemcpy(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));
}

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