/*
 *  Notepad
 *
 *  Copyright 2000 Mike McCormack <Mike_McCormack@looksmart.com.au>
 *  Copyright 1997,98 Marcel Baur <mbaur@g26.ethz.ch>
 *  To be distributed under the Wine License
 *
 *  FIXME,TODO list:
 *  - Use wine Heap instead of malloc/free (done)
 *  - use scroll bars (vertical done)
 *  - cut 'n paste (clipboard)
 *  - save file
 *  - print file
 *  - find dialog
 *  - encapsulate data structures (?) - half done
 *  - free unused memory
 *  - solve Open problems
 *  - smoother scrolling
 *  - seperate view code and document code
 *
 * This program is intended as a testbed for winelib as much as
 * a useful application.
 */

#include <stdio.h>
#include "windows.h"

#ifdef LCC
#include "lcc.h"
#endif

#include "main.h"
#include "license.h"
#include "dialog.h"
#include "language.h"

extern BOOL DoCloseFile(void);
extern void DoOpenFile(LPCSTR szFileName);

NOTEPAD_GLOBALS Globals;


/* Using a pointer to pointer data structure to
   achieve a little more efficiency. Hopefully
   it will be worth it, because it complicates the
   code - mjm 26 Jun 2000 */

#define BUFFERCHUNKSIZE 0xe0
typedef struct TAGLine {
    LPSTR lpLine;
    DWORD dwWidth;
    DWORD dwMaxWidth;
} LINE, *LPLINE;

/* FIXME: make this info into a structure */
/* typedef struct tagBUFFER { */
DWORD dwVOffset=0;
DWORD dwLines=0;
DWORD dwMaxLines=0;
LPLINE lpBuffer=NULL;
DWORD dwXpos=0,dwYpos=0;        /* position of caret in char coords */
DWORD dwCaretXpos=0,dwCaretYpos=0; /* position of caret in pixel coords */
TEXTMETRIC tm;                  /* textmetric for current font */
RECT rectClient;        /* client rectangle of the window we're drawing in */
/* } BUFFER, *LPBUFFER */

VOID InitFontInfo(HWND hWnd)
{
    HDC hDC = GetDC(hWnd);

    if(hDC)
    {
        GetTextMetrics(hDC, &tm);
        ReleaseDC(hWnd,hDC);
    }
}

void InitBuffer(void)
{
    lpBuffer = NULL;
    dwLines = 0;
    dwMaxLines = 0;
    dwXpos=0;
    dwYpos=0;
}

/* convert x,y character co-ords into x pixel co-ord */
DWORD CalcStringWidth(HDC hDC, DWORD x, DWORD y)
{
    DWORD len;
    SIZE size;

    size.cx = 0;
    size.cy = 0;

    if(y>dwLines)
        return size.cx;
    if(lpBuffer == NULL) 
        return size.cx;
    if(lpBuffer[y].lpLine == NULL)
        return size.cx;
    len = (x<lpBuffer[y].dwWidth) ? 
           x : lpBuffer[y].dwWidth;
    GetTextExtentPoint(hDC, lpBuffer[y].lpLine, len, &size);

    return size.cx;
}

void CalcCaretPos(HDC hDC, DWORD dwXpos, DWORD dwYpos)
{
    dwCaretXpos = CalcStringWidth(hDC, dwXpos, dwYpos);
    dwCaretYpos = tm.tmHeight*(dwYpos-dwVOffset);
    SetCaretPos(dwCaretXpos,dwCaretYpos);
}

DWORD GetLinesPerPage(HWND hWnd)
{
    return (rectClient.bottom/tm.tmHeight); /* round down */
}

/* render one line of text and blank space */
void RenderLine(HDC hDC, DWORD lineno)
{
    RECT rect;
    HBRUSH hPrev;

    if(!hDC)
        return;

    /* erase the space at the end of a line using a white rectangle */
    rect.top = tm.tmHeight*(lineno-dwVOffset);
    rect.bottom = tm.tmHeight*(lineno-dwVOffset+1);

    if(lpBuffer && (lineno<dwLines))
        rect.left = CalcStringWidth(hDC, lpBuffer[lineno].dwWidth,lineno);
    else
        rect.left = 0;
    rect.right = rectClient.right;

    /* use the white pen so there's not outline */
    hPrev = SelectObject(hDC, GetStockObject(WHITE_PEN));
    Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
    SelectObject(hDC, hPrev);
    
    if(lpBuffer && lpBuffer[lineno].lpLine)
    {
        TextOut(hDC, 0, rect.top, lpBuffer[lineno].lpLine, 
                       lpBuffer[lineno].dwWidth);
    }
}

/*
 * Paint the buffer onto the window.
 */
void RenderWindow(HDC hDC) {
    DWORD i;

    if(!hDC)
        return;

    /* FIXME: render only necessary lines */
    for(i = dwVOffset; i < (dwVOffset+GetLinesPerPage(0)); i++)
    {
        RenderLine(hDC,i);
    }
}

/* 
 * Check that correct buffers exist to access line y pos x
 * Only manages memory.
 *
 * Returns TRUE if the line is accessable
 *         FALSE if there is a problem
 */
BOOL ValidateLine(DWORD y,DWORD x)
{
    DWORD max;

    /* check to see that the BUFFER has enough lines */
    max = dwMaxLines;
    if( (max<=y) || (lpBuffer == NULL))
    {
        while(max<=y)
            max += BUFFERCHUNKSIZE;
        /* use GlobalAlloc first time round */
        if(lpBuffer)
            lpBuffer = (LPLINE) GlobalReAlloc((HGLOBAL)lpBuffer,GMEM_FIXED,
                                          max*sizeof(LINE)) ;
        else
            lpBuffer = (LPLINE) GlobalAlloc(GMEM_FIXED, max*sizeof(LINE));
        if(lpBuffer == NULL)
            return FALSE;
        ZeroMemory(&lpBuffer[dwLines], sizeof(LINE)*(max-dwLines) );
        dwMaxLines = max;
    }

    /* check to see that the LINE is wide enough */
    max = lpBuffer[y].dwMaxWidth;
    if( (max <= x) || (lpBuffer[y].lpLine == NULL) )
    {
        while(max <= x)
            max += BUFFERCHUNKSIZE;
        /* use GlobalAlloc first */
        if(lpBuffer[y].lpLine)
            lpBuffer[y].lpLine = (LPSTR)GlobalReAlloc((HGLOBAL)lpBuffer[y].lpLine,
                                                  GMEM_FIXED, max) ;
        else
            lpBuffer[y].lpLine = (LPSTR)GlobalAlloc( GMEM_FIXED, max);
        if(lpBuffer[y].lpLine == NULL)
            return FALSE;
        lpBuffer[y].dwWidth = 0;
        lpBuffer[y].dwMaxWidth = max;
    }
    return TRUE;
}

/* inserts a new line into the buffer */
BOOL DoNewLine(HDC hDC)
{
    DWORD i,cnt;
    LPSTR src,dst;

    /* check to see if we need more memory for the buffer pointers */
    if(!ValidateLine(dwLines,0))
        return FALSE;

    /* shuffle up all the lines */
    for(i=dwLines; i>(dwYpos+1); i--)
    {
        lpBuffer[i] = lpBuffer[i-1];
        RenderLine(hDC,i);
    }
    ZeroMemory(&lpBuffer[dwYpos+1],sizeof(LINE));

    /* copy the characters after the carat (if any) to the next line */
    src = &lpBuffer[dwYpos].lpLine[dwXpos];
    cnt = lpBuffer[dwYpos].dwWidth-dwXpos;
    if(!ValidateLine(dwYpos+1,cnt)) /* allocates the buffer */
        return FALSE; /* FIXME */
    dst = &lpBuffer[dwYpos+1].lpLine[0];
    memcpy(dst, src, cnt);
    lpBuffer[dwYpos+1].dwWidth = cnt;
    lpBuffer[dwYpos].dwWidth  -= cnt;

    /* move the cursor */
    dwLines++;
    dwXpos = 0;
    dwYpos++;

    /* update the window */
    RenderLine(hDC, dwYpos-1);
    RenderLine(hDC, dwYpos);
    CalcCaretPos(hDC, dwXpos, dwYpos);
    /* FIXME: don't use globals */
    SetScrollRange(Globals.hMainWnd, SB_VERT, 0, dwLines, TRUE);

    return TRUE;
}

/*
 * Attempt a basic edit buffer
 */
BOOL AddCharToBuffer(HDC hDC, char ch)
{
    /* we can use lpBuffer[dwYpos] */
    if(!ValidateLine(dwYpos,0))
        return FALSE;

    /* shuffle the rest of the line*/
    if(!ValidateLine(dwYpos, lpBuffer[dwYpos].dwWidth))
        return FALSE;
    lpBuffer[dwYpos].dwWidth++;
    memmove(&lpBuffer[dwYpos].lpLine[dwXpos+1],
            &lpBuffer[dwYpos].lpLine[dwXpos],
            lpBuffer[dwYpos].dwWidth-dwXpos);

    /* add the character */
    lpBuffer[dwYpos].lpLine[dwXpos] = ch;
    if(dwLines == 0)
        dwLines++;
    dwXpos++;

    /* update the window and cursor position */
    RenderLine(hDC,dwYpos);
    CalcCaretPos(hDC,dwXpos,dwYpos);

    return TRUE;
}


/* erase a character */
BOOL DoBackSpace(HDC hDC)
{
    DWORD i;

    if(lpBuffer == NULL)
        return FALSE;
    if(lpBuffer[dwYpos].lpLine && (dwXpos>0))
    {
        dwXpos --;
        /* FIXME: use memmove */
        for(i=dwXpos; i<(lpBuffer[dwYpos].dwWidth-1); i++)
            lpBuffer[dwYpos].lpLine[i]=lpBuffer[dwYpos].lpLine[i+1];

        lpBuffer[dwYpos].dwWidth--;
        RenderLine(hDC, dwYpos);
        CalcCaretPos(hDC,dwXpos,dwYpos);
    }
    else 
    {
        /* Erase a newline. To do this we join two lines */
        LPSTR src, dest;
        DWORD len, oldlen;

        if(dwYpos==0)
            return FALSE;

        oldlen = lpBuffer[dwYpos-1].dwWidth;
        if(lpBuffer[dwYpos-1].lpLine&&lpBuffer[dwYpos].lpLine)
        {
            /* concatonate to the end of the line above line */
            src  = &lpBuffer[dwYpos].lpLine[0];
            dest = &lpBuffer[dwYpos-1].lpLine[lpBuffer[dwYpos-1].dwWidth];
            len  = lpBuffer[dwYpos].dwWidth;

            /* check the length of the new line */
            if(!ValidateLine(dwYpos-1,lpBuffer[dwYpos-1].dwWidth + len))
                return FALSE;

            memcpy(dest,src,len);
            lpBuffer[dwYpos-1].dwWidth+=len;
            GlobalFree( (HGLOBAL)lpBuffer[dwYpos].lpLine);
        }
        else if (!lpBuffer[dwYpos-1].lpLine)
        {
            lpBuffer[dwYpos-1]=lpBuffer[dwYpos];
        } /* else both are NULL */
        RenderLine(hDC,dwYpos-1);

        /* don't zero - it's going to get trashed anyhow */

        /* shuffle up all the lines below this one */
        for(i=dwYpos; i<(dwLines-1); i++)
        {
            lpBuffer[i] = lpBuffer[i+1];
            RenderLine(hDC,i);
        }

        /* clear the last line */
        ZeroMemory(&lpBuffer[dwLines-1],sizeof (LINE));
        RenderLine(hDC,dwLines-1);
        dwLines--;

        /* adjust the cursor position to joining point */
        dwYpos--;
        dwXpos = oldlen;

        CalcCaretPos(hDC,dwXpos,dwYpos);
        SetScrollRange(Globals.hMainWnd, SB_VERT, 0, dwLines, TRUE);
    }
    return TRUE;
}

/* as used by File->New */
void TrashBuffer(void)
{
    DWORD i;

    /* variables belonging to the buffer */
    if(lpBuffer)
    {
        for(i=0; i<dwLines; i++)
        {
            if(lpBuffer[i].lpLine)
                GlobalFree ((HGLOBAL)lpBuffer[i].lpLine);
            ZeroMemory(&lpBuffer[i],sizeof (LINE));
        }
        GlobalFree((HGLOBAL)lpBuffer);
        lpBuffer=NULL;
    }
    dwLines = 0;
    dwMaxLines = 0;

    /* variables belonging to the view */
    dwXpos = 0;
    dwYpos = 0;
    dwVOffset = 0 ;
    /* FIXME: don't use globals */
    SetScrollPos(Globals.hMainWnd, SB_VERT, dwVOffset, FALSE);
    SetScrollRange(Globals.hMainWnd, SB_VERT, 0, dwLines, TRUE);
}


/*
 * Add a line to the buffer
 */
/* FIXME: this breaks lines longer than BUFFERCHUNKSIZE */
DWORD CreateLine(
    LPSTR buffer, /* pointer to buffer with file data */
    DWORD size, /* number of bytes available in buffer */
    BOOL nomore)
{
    DWORD i;
    
    if(size == 0)
        return 0;

    for(i=0; i<size; i++)
    {
        if(buffer[i]==0x0a)
        {
            if(ValidateLine(dwLines,i))
            {
                memcpy(&lpBuffer[dwLines].lpLine[0],&buffer[0],i);
                lpBuffer[dwLines].dwWidth = i;
                dwLines++;
            }
            return i+1;
        }
    }

    /* make a line of the rest */
    if( (i == BUFFERCHUNKSIZE) || nomore )
    {
        if(ValidateLine(dwLines,i))
        {
            memcpy(&lpBuffer[dwLines].lpLine[0],&buffer[0],i);
            lpBuffer[dwLines].dwWidth = i;
            dwLines++;
        }
        return i;
    }

    return 0;
}


/* 
 * This is probably overcomplicated by lpBuffer data structure... 
 * Read blocks from the file, then add each line from the
 *  block to the buffer until there is none left. If all
 *  a slab isn't used, try load some more data from the file.
 */
void LoadBufferFromFile(LPCSTR szFileName)
{
    HFILE hFile;
    OFSTRUCT ofs;
    CHAR *pTemp;
    DWORD size,i,len,bytes_left,bytes_read;

    hFile = OpenFile(szFileName, &ofs, OF_READ);
    if(hFile == INVALID_HANDLE_VALUE)
        return;
    size = BUFFERCHUNKSIZE;
    pTemp = (LPSTR) GlobalAlloc(GMEM_FIXED, size);
    if(!pTemp)
        return;
    bytes_read = 1; /* anything non-zero */
    bytes_left = 0;
    while(bytes_read)
    {
        if(!ReadFile(hFile, 
                     &pTemp[bytes_left], 
                     size-bytes_left, 
                     &bytes_read, NULL))
            break;
        bytes_left+=bytes_read;

        /* add strings to buffer */
        for(i = 0; 
            (i<size) &&
            (len  = CreateLine(&pTemp[i], bytes_left, !bytes_read));
            i+= len,bytes_left-=len );

        /* move leftover to front of buffer */
        if(bytes_left)
            memmove(&pTemp[0],&pTemp[i], bytes_left);
    }
    CloseHandle(hFile);
    MessageBox(Globals.hMainWnd, "Finished", "Info", MB_OK);
}

BOOL DoInput(HDC hDC, WPARAM wParam, LPARAM lParam)
{
    switch(wParam)
    {
    case 0x08:
        return DoBackSpace(hDC);
    case 0x0d:
        return DoNewLine(hDC);
    default:
        return AddCharToBuffer(hDC,wParam);
    }
}

BOOL GotoHome(HWND hWnd)
{
    dwXpos = 0;
    dwYpos = 0;
    dwVOffset = 0;
    return TRUE;
}

BOOL GotoEndOfLine(HWND hWnd)
{
    dwXpos = lpBuffer[dwYpos].dwWidth;
    return TRUE;
}

BOOL GotoDown(HWND hWnd)
{
    if((dwYpos+1) >= dwLines)
    {
        return FALSE;
    }
    dwYpos++;
    if (dwXpos>lpBuffer[dwYpos].dwWidth)
        GotoEndOfLine(hWnd);
    return TRUE;
}

BOOL GotoUp(HWND hWnd)
{
    if(dwYpos==0)
        return FALSE;
    dwYpos--;
    if (dwXpos>lpBuffer[dwYpos].dwWidth)
        GotoEndOfLine(hWnd);
    return TRUE;
}

BOOL GotoLeft(HWND hWnd)
{
    if(dwXpos > 0)
    {
        dwXpos--;
        return TRUE;
    }
    if(GotoUp(hWnd))   
        return GotoEndOfLine(hWnd);
    return FALSE;
}

BOOL GotoRight(HWND hWnd)
{
    if(dwXpos<lpBuffer[dwYpos].dwWidth)
    {
        dwXpos++;
        return TRUE;
    }
    if(!GotoDown(hWnd))
        return FALSE;
    dwXpos=0;
    return TRUE;
}

/* check the caret is still on the screen */
BOOL ScrollABit(HWND hWnd)
{
    if(dwYpos<dwVOffset)
    {
        dwVOffset = dwYpos;
        return TRUE;
    }
    if(dwYpos>(dwVOffset+GetLinesPerPage(hWnd)))
    {
        dwVOffset = dwYpos - GetLinesPerPage(hWnd) + 1;
        return TRUE;
    }
    return FALSE;
}

/* FIXME: move the window around so we can still see the caret */
VOID DoEdit(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    HDC hDC;

    if(lpBuffer==NULL)
        return;
    switch(wParam)
    {
    case VK_HOME: GotoHome(hWnd);
        break;

    case VK_END: GotoEndOfLine(hWnd);
        break;

    case VK_LEFT: GotoLeft(hWnd);
        break;

    case VK_RIGHT: GotoRight(hWnd);
        break;

    case VK_DOWN: GotoDown(hWnd);
        break;

    case VK_UP: GotoUp(hWnd);
        break;

    default:
        return;
    }

    hDC = GetDC(hWnd);
    if(hDC)
    {
        CalcCaretPos(hDC, dwXpos, dwYpos);
        ReleaseDC(hWnd,hDC);
    }
    if(ScrollABit(hWnd))
        InvalidateRect(hWnd, NULL, FALSE);
}

void ButtonDownToCaretPos(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    DWORD x, y, caretx, carety;
    BOOL refine_guess = TRUE;
    HDC hDC;

    x = LOWORD(lParam);
    y = HIWORD(lParam);

    caretx = x/tm.tmAveCharWidth; /* guess */
    carety = dwVOffset + y/tm.tmHeight;

    hDC = GetDC(hWnd);

    if(lpBuffer == NULL)
    {
        caretx = 0;
        carety = 0;
        refine_guess = FALSE;
    }

    /* if the cursor is past the bottom, put it after the last char */
    if(refine_guess && (carety>=dwLines) )
    {
        carety=dwLines-1;
        caretx=lpBuffer[carety].dwWidth;
        refine_guess = FALSE;
    }

    /* cursor past end of line? */
    if(refine_guess && (x>CalcStringWidth(hDC,lpBuffer[carety].dwWidth,carety)))
    {
        caretx = lpBuffer[carety].dwWidth;
        refine_guess = FALSE;
    }

    /* FIXME: doesn't round properly */
    if(refine_guess)
    {
        if(CalcStringWidth(hDC,caretx,carety)<x)
        {
            while( (caretx<lpBuffer[carety].dwWidth) &&
                   (CalcStringWidth(hDC,caretx+1,carety)<x))
                caretx++;
        }
        else
        {
            while((caretx>0)&&(CalcStringWidth(hDC,caretx-1,carety)>x))
                caretx--;
        }
    }
    
    /* set the caret's position */
    dwXpos = caretx;
    dwYpos = carety;
    CalcCaretPos(hDC, caretx, carety);
    ReleaseDC(hWnd,hDC);
}

void DoScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    DWORD dy = GetLinesPerPage(hWnd);

    switch(wParam) /* vscroll code */
    {
    case SB_LINEUP:
        if(dwVOffset)
            dwVOffset--;
        break;
    case SB_LINEDOWN:
        if(dwVOffset<dwLines)
            dwVOffset++;
        break;
    case SB_PAGEUP:
        if( (dy+dwVOffset) > dwLines)
            dwVOffset = dwLines - 1;
        break;
    case SB_PAGEDOWN:
        if( dy > dwVOffset)
            dwVOffset=0;
        break;
    }
    /* position scroll */
    SetScrollPos(hWnd, SB_VERT, dwVOffset, TRUE);
}

/***********************************************************************
 *
 *           NOTEPAD_MenuCommand
 *
 *  All handling of main menu events
 */

int NOTEPAD_MenuCommand (WPARAM wParam)
{  
   switch (wParam) {
     case NP_FILE_NEW:          DIALOG_FileNew(); break;
     case NP_FILE_OPEN:         DIALOG_FileOpen(); break;
     case NP_FILE_SAVE:         DIALOG_FileSave(); break;
     case NP_FILE_SAVEAS:       DIALOG_FileSaveAs(); break;
     case NP_FILE_PRINT:        DIALOG_FilePrint(); break;
     case NP_FILE_PAGESETUP:    DIALOG_FilePageSetup(); break;
     case NP_FILE_PRINTSETUP:   DIALOG_FilePrinterSetup();break;
     case NP_FILE_EXIT:         DIALOG_FileExit(); break;

     case NP_EDIT_UNDO:         DIALOG_EditUndo(); break;
     case NP_EDIT_CUT:          DIALOG_EditCut(); break;
     case NP_EDIT_COPY:         DIALOG_EditCopy(); break;
     case NP_EDIT_PASTE:        DIALOG_EditPaste(); break;
     case NP_EDIT_DELETE:       DIALOG_EditDelete(); break;
     case NP_EDIT_SELECTALL:    DIALOG_EditSelectAll(); break;
     case NP_EDIT_TIMEDATE:     DIALOG_EditTimeDate();break;
     case NP_EDIT_WRAP:         DIALOG_EditWrap(); break;

     case NP_SEARCH_SEARCH:     DIALOG_Search(); break;
     case NP_SEARCH_NEXT:       DIALOG_SearchNext(); break;

     case NP_HELP_CONTENTS:     DIALOG_HelpContents(); break;
     case NP_HELP_SEARCH:       DIALOG_HelpSearch(); break;
     case NP_HELP_ON_HELP:      DIALOG_HelpHelp(); break;
     case NP_HELP_LICENSE:      DIALOG_HelpLicense(); break;
     case NP_HELP_NO_WARRANTY:  DIALOG_HelpNoWarranty(); break;
     case NP_HELP_ABOUT_WINE:   DIALOG_HelpAboutWine(); break;
     
     /* Handle languages */
     default:
      LANGUAGE_DefaultHandle(wParam);
   }
   return 0;
}



/***********************************************************************
 *
 *           NOTEPAD_WndProc
 */

LRESULT NOTEPAD_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hContext;
    HANDLE hDrop;                      /* drag & drop */
    CHAR szFileName[MAX_STRING_LEN];
    RECT Windowsize;

    lstrcpy(szFileName, "");

    switch (msg) {

       case WM_CREATE:
          GetClientRect(hWnd, &rectClient);
          InitFontInfo(hWnd);
          break;

       case WM_SETFOCUS:
          CreateCaret(Globals.hMainWnd, 0, 1, tm.tmHeight);
          SetCaretPos(dwCaretXpos, dwCaretYpos);
          ShowCaret(Globals.hMainWnd);
          break;

       case WM_KILLFOCUS:
          DestroyCaret();
          break;

       case WM_PAINT:
          GetClientRect(hWnd, &rectClient);
          hContext = BeginPaint(hWnd, &ps);
          RenderWindow(hContext);
          EndPaint(hWnd, &ps);
        break;

       case WM_KEYDOWN:
          DoEdit(hWnd, wParam, lParam);
          break;

       case WM_CHAR:
          GetClientRect(hWnd, &rectClient);
          HideCaret(hWnd);
          hContext = GetDC(hWnd);
          DoInput(hContext,wParam,lParam);
          ReleaseDC(hWnd,hContext);
          ShowCaret(hWnd);
          break;

       case WM_LBUTTONDOWN:
          /* figure out where the mouse was clicked */
          ButtonDownToCaretPos(hWnd, wParam, lParam);
          break;

       case WM_VSCROLL:
          DoScroll(hWnd, wParam, lParam);
	  InvalidateRect(hWnd, NULL, FALSE); /* force a redraw */
          break;

       case WM_COMMAND:
          /* FIXME: this is a bit messy */
          NOTEPAD_MenuCommand(wParam);
          InvalidateRect(hWnd, NULL, FALSE); /* force a redraw */
          hContext = GetDC(hWnd);
          CalcCaretPos(hContext,dwXpos,dwYpos);
          ReleaseDC(hWnd,hContext);
          break;

       case WM_DESTROYCLIPBOARD:
          MessageBox(Globals.hMainWnd, "Empty clipboard", "Debug", MB_ICONEXCLAMATION);
          break;

       case WM_CLOSE:
          if (DoCloseFile()) {
             PostQuitMessage(0);
          }
          break;

       case WM_DESTROY:
             PostQuitMessage (0);
          break;

       case WM_SIZE:
          GetClientRect(Globals.hMainWnd, &Windowsize);
          break;

       case WM_DROPFILES:
          /* User has dropped a file into main window */
          hDrop = (HANDLE) wParam;
          DragQueryFile(hDrop, 0, (CHAR *) &szFileName, sizeof(szFileName));
          DragFinish(hDrop);
          DoOpenFile(szFileName);
          break;        

       default:
          return DefWindowProc (hWnd, msg, wParam, lParam);
    }
    return 0l;
}



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

int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
{
    MSG      msg;
    WNDCLASS class;
    char className[] = "NPClass";  /* To make sure className >= 0x10000 */
    char winName[]   = "Notepad";

    /* Select Language */
    LANGUAGE_Init();

    /* setup buffer */
    InitBuffer();

    /* Setup Globals */

    Globals.lpszIniFile = "notepad.ini";
    Globals.lpszIcoFile = "notepad.ico";

    Globals.hInstance       = hInstance;

#ifndef LCC
    Globals.hMainIcon       = ExtractIcon(Globals.hInstance, 
                                        Globals.lpszIcoFile, 0);
#endif
    if (!Globals.hMainIcon) {
        Globals.hMainIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
    }

    lstrcpy(Globals.szFindText,     "");
    lstrcpy(Globals.szFileName,     "");
    lstrcpy(Globals.szMarginTop,    "25 mm");
    lstrcpy(Globals.szMarginBottom, "25 mm");
    lstrcpy(Globals.szMarginLeft,   "20 mm");
    lstrcpy(Globals.szMarginRight,  "20 mm");
    lstrcpy(Globals.szHeader,       "&n");
    lstrcpy(Globals.szFooter,       "Page &s");
    lstrcpy(Globals.Buffer, "Hello World");

    if (!prev){
        class.style         = CS_HREDRAW | CS_VREDRAW;
        class.lpfnWndProc   = NOTEPAD_WndProc;
        class.cbClsExtra    = 0;
        class.cbWndExtra    = 0;
        class.hInstance     = Globals.hInstance;
        class.hIcon         = LoadIcon (0, IDI_APPLICATION);
        class.hCursor       = LoadCursor (0, IDC_ARROW);
        class.hbrBackground = GetStockObject (WHITE_BRUSH);
        class.lpszMenuName  = 0;
        class.lpszClassName = className;
    }

    if (!RegisterClass (&class)) return FALSE;

    /* Setup windows */


    Globals.hMainWnd = CreateWindow (className, winName, 
       WS_OVERLAPPEDWINDOW + WS_HSCROLL + WS_VSCROLL,
       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 
       LoadMenu(Globals.hInstance, STRING_MENU_Xx),
       Globals.hInstance, 0);

    Globals.hFindReplaceDlg = 0;

    LANGUAGE_SelectByName(Globals.lpszLanguage);

    SetMenu(Globals.hMainWnd, Globals.hMainMenu);               
                        
    ShowWindow (Globals.hMainWnd, show);
    UpdateWindow (Globals.hMainWnd);

    /* Set up dialogs */

    /* Identify Messages originating from FindReplace */

    Globals.nCommdlgFindReplaceMsg = RegisterWindowMessage("commdlg_FindReplace");
    if (Globals.nCommdlgFindReplaceMsg==0) {
       MessageBox(Globals.hMainWnd, "Could not register commdlg_FindReplace window message", 
                  "Error", MB_ICONEXCLAMATION);
    }

    /* now handle command line */
    
    while (*cmdline && (*cmdline == ' ' || *cmdline == '-')) 
    
    {
        CHAR   option;
/*      LPCSTR topic_id; */

        if (*cmdline++ == ' ') continue;

        option = *cmdline;
        if (option) cmdline++;
        while (*cmdline && *cmdline == ' ') cmdline++;

        switch(option)
        {
            case 'p':
            case 'P': printf("Print file: ");
                      /* Not yet able to print a file */
                      break;
        }
    }

    /* Set up Drag&Drop */

    DragAcceptFiles(Globals.hMainWnd, TRUE);

    /* now enter mesage loop     */
    
    while (GetMessage (&msg, 0, 0, 0)) {
        if (IsDialogMessage(Globals.hFindReplaceDlg, &msg)!=0) {
          /* Message belongs to FindReplace dialog */
          /* We just let IsDialogMessage handle it */
        } 
          else
        { 
          /* Message belongs to the Notepad Main Window */
          TranslateMessage (&msg);
          DispatchMessage (&msg);
        }
    }
    return 0;
}
