/*
 * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 */
/* Boehm, February 6, 1995 12:29 pm PST */

/*
 * The MS Windows specific part of de.  
 * This started as the generic Windows application template
 * made available by Rob Haack (rhaack@polaris.unm.edu), but
 * significant parts didn't survive to the final version.
 *
 * This was written by a nonexpert windows programmer.
 */


#include "windows.h"
#include "gc.h"
#include "cord.h"
#include "de_cmds.h"
#include "de_win.h"

int LINES = 0;
int COLS = 0;

char       szAppName[]     = "DE";
char       FullAppName[]   = "Demonstration Editor";

HWND        hwnd;

void de_error(char *s)
{
    MessageBox( hwnd, (LPSTR) s,
                (LPSTR) FullAppName,
                MB_ICONINFORMATION | MB_OK );
    InvalidateRect(hwnd, NULL, TRUE);
}

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR command_line, int nCmdShow)
{
   MSG         msg;
   WNDCLASS    wndclass;
   HANDLE      hAccel;

   if (!hPrevInstance)
   {
      wndclass.style          = CS_HREDRAW | CS_VREDRAW;
      wndclass.lpfnWndProc    = WndProc;
      wndclass.cbClsExtra     = 0;
      wndclass.cbWndExtra     = DLGWINDOWEXTRA;
      wndclass.hInstance      = hInstance;
      wndclass.hIcon          = LoadIcon (hInstance, szAppName);
      wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
      wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH);
      wndclass.lpszMenuName   = "DE";
      wndclass.lpszClassName  = szAppName;

      if (RegisterClass (&wndclass) == 0) {
          char buf[50];
   	
   	  sprintf(buf, "RegisterClass: error code: 0x%X", GetLastError());
   	  de_error(buf);
   	  return(0);
      }
   }
   
   /* Empirically, the command line does not include the command name ...
   if (command_line != 0) {
       while (isspace(*command_line)) command_line++;
       while (*command_line != 0 && !isspace(*command_line)) command_line++;
       while (isspace(*command_line)) command_line++;
   } */
   
   if (command_line == 0 || *command_line == 0) {
        de_error("File name argument required");
        return( 0 );
   } else {
        char *p = command_line;
        
        while (*p != 0 && !isspace(*p)) p++;
   	arg_file_name = CORD_to_char_star(
   			    CORD_substr(command_line, 0, p - command_line));
   }

   hwnd = CreateWindow (szAppName,
   			FullAppName,
   			WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
   			CW_USEDEFAULT, 0, /* default pos. */
   			CW_USEDEFAULT, 0, /* default width, height */
   			NULL,	/* No parent */
   			NULL, 	/* Window class menu */
   			hInstance, NULL);
   if (hwnd == NULL) {
   	char buf[50];
   	
   	sprintf(buf, "CreateWindow: error code: 0x%X", GetLastError());
   	de_error(buf);
   	return(0);
   }

   ShowWindow (hwnd, nCmdShow);

   hAccel = LoadAccelerators( hInstance, szAppName );
   
   while (GetMessage (&msg, NULL, 0, 0))
   {
      if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
      {
         TranslateMessage (&msg);
         DispatchMessage (&msg);
      }
   }
   return msg.wParam;
}

/* Return the argument with all control characters replaced by blanks.	*/
char * plain_chars(char * text, size_t len)
{
    char * result = GC_MALLOC_ATOMIC(len + 1);
    register size_t i;
    
    for (i = 0; i < len; i++) {
       if (iscntrl(text[i])) {
           result[i] = ' ';
       } else {
           result[i] = text[i];
       }
    }
    result[len] = '\0';
    return(result);
}

/* Return the argument with all non-control-characters replaced by 	*/
/* blank, and all control characters c replaced by c + 32.		*/
char * control_chars(char * text, size_t len)
{
    char * result = GC_MALLOC_ATOMIC(len + 1);
    register size_t i;
    
    for (i = 0; i < len; i++) {
       if (iscntrl(text[i])) {
           result[i] = text[i] + 0x40;
       } else {
           result[i] = ' ';
       }
    }
    result[len] = '\0';
    return(result);
}

int char_width;
int char_height;

void get_line_rect(int line, int win_width, RECT * rectp)
{
    rectp -> top = line * char_height;
    rectp -> bottom = rectp->top + char_height;
    rectp -> left = 0;
    rectp -> right = win_width;
}

int caret_visible = 0;	/* Caret is currently visible.	*/

int screen_was_painted = 0;/* Screen has been painted at least once.	*/

void update_cursor(void);

LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
                          WPARAM wParam, LPARAM lParam)
{
   static FARPROC lpfnAboutBox;
   static HANDLE  hInstance;
   HDC dc;
   PAINTSTRUCT ps;
   RECT client_area;
   RECT this_line;
   RECT dummy;
   TEXTMETRIC tm;
   register int i;
   int id;

   switch (message)
   {
      case WM_CREATE:
           hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
           lpfnAboutBox = MakeProcInstance( (FARPROC) AboutBox, hInstance );
           dc = GetDC(hwnd);
           SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
           GetTextMetrics(dc, &tm);
           ReleaseDC(hwnd, dc);
           char_width = tm.tmAveCharWidth;
           char_height = tm.tmHeight + tm.tmExternalLeading;
           GetClientRect(hwnd, &client_area);
      	   COLS = (client_area.right - client_area.left)/char_width;
      	   LINES = (client_area.bottom - client_area.top)/char_height;
      	   generic_init();
           return(0);

      case WM_CHAR:
      	   if (wParam == QUIT) {
      	       SendMessage( hwnd, WM_CLOSE, 0, 0L );
      	   } else {
      	       do_command(wParam);
      	   }
      	   return(0);
      
      case WM_SETFOCUS:
      	   CreateCaret(hwnd, NULL, char_width, char_height);
      	   ShowCaret(hwnd);
      	   caret_visible = 1;
      	   update_cursor();
      	   return(0);
      	   
      case WM_KILLFOCUS:
      	   HideCaret(hwnd);
      	   DestroyCaret();
      	   caret_visible = 0;
      	   return(0);
      	   
      case WM_LBUTTONUP:
      	   {
      	       unsigned xpos = LOWORD(lParam);	/* From left	*/
      	       unsigned ypos = HIWORD(lParam);	/* from top */
      	       
      	       set_position( xpos/char_width, ypos/char_height );
      	       return(0);
      	   }
      	   
      case WM_COMMAND:
      	   id = LOWORD(wParam);
      	   if (id & EDIT_CMD_FLAG) {
               if (id & REPEAT_FLAG) do_command(REPEAT);
               do_command(CHAR_CMD(id));
               return( 0 );
           } else {
             switch(id) {
               case IDM_FILEEXIT:
                  SendMessage( hwnd, WM_CLOSE, 0, 0L );
                  return( 0 );

               case IDM_HELPABOUT:
                  if( DialogBox( hInstance, "ABOUTBOX",
                                 hwnd, lpfnAboutBox ) )
                     InvalidateRect( hwnd, NULL, TRUE );
                  return( 0 );
	       case IDM_HELPCONTENTS:
	     	  de_error(
	     	       "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
	     	       "Undo: ^U    Write: ^W   Quit:^D  Repeat count: ^R[n]\n"
	     	       "Top: ^T   Locate (search, find): ^L text ^L\n");
	     	  return( 0 );
	     }
	   }
           break;

      case WM_CLOSE:
           DestroyWindow( hwnd );
           return 0;

      case WM_DESTROY:
           PostQuitMessage (0);
	   GC_win32_free_heap();
           return 0;
      
      case WM_PAINT:
      	   dc = BeginPaint(hwnd, &ps);
      	   GetClientRect(hwnd, &client_area);
      	   COLS = (client_area.right - client_area.left)/char_width;
      	   LINES = (client_area.bottom - client_area.top)/char_height;
      	   SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
      	   for (i = 0; i < LINES; i++) {
      	       get_line_rect(i, client_area.right, &this_line);
      	       if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) {
      	           CORD raw_line = retrieve_screen_line(i);
      	           size_t len = CORD_len(raw_line);
      	           char * text = CORD_to_char_star(raw_line);
      	           		/* May contain embedded NULLs	*/
      	           char * plain = plain_chars(text, len);
      	           char * blanks = CORD_to_char_star(CORD_chars(' ',
      	           				                COLS - len));
      	           char * control = control_chars(text, len);
#		   define RED RGB(255,0,0)
      	           
      	           SetBkMode(dc, OPAQUE);
      	           SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
      	           
      	           TextOut(dc, this_line.left, this_line.top,
      	           	   plain, len);
      	           TextOut(dc, this_line.left + len * char_width, this_line.top,
      	           	   blanks, COLS - len);
      	           SetBkMode(dc, TRANSPARENT);
      	           SetTextColor(dc, RED);
      	           TextOut(dc, this_line.left, this_line.top,
      	           	   control, strlen(control));
      	       }
      	   }
      	   EndPaint(hwnd, &ps);
      	   screen_was_painted = 1;
      	   return 0;
   }
   return DefWindowProc (hwnd, message, wParam, lParam);
}

int last_col;
int last_line;

void move_cursor(int c, int l)
{
    last_col = c;
    last_line = l;
    
    if (caret_visible) update_cursor();
}

void update_cursor(void)
{
    SetCaretPos(last_col * char_width, last_line * char_height);
    ShowCaret(hwnd);
}

void invalidate_line(int i)
{
    RECT line;
    
    if (!screen_was_painted) return;
    	/* Invalidating a rectangle before painting seems result in a	*/
    	/* major performance problem.					*/
    get_line_rect(i, COLS*char_width, &line);
    InvalidateRect(hwnd, &line, FALSE);
}

LRESULT CALLBACK AboutBox( HWND hDlg, UINT message,
                           WPARAM wParam, LPARAM lParam )
{
   switch( message )
   {
      case WM_INITDIALOG:
           SetFocus( GetDlgItem( hDlg, IDOK ) );
           break;

      case WM_COMMAND:
           switch( wParam )
           {
              case IDOK:
                   EndDialog( hDlg, TRUE );
                   break;
           }
           break;

      case WM_CLOSE:
           EndDialog( hDlg, TRUE );
           return TRUE;

   }
   return FALSE;
}

