/*
 *  Notepad
 *
 *  Copyright 2000 Mike McCormack <Mike_McCormack@looksmart.com.au>
 *  Copyright 1997,98 Marcel Baur <mbaur@g26.ethz.ch>
 *  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
 *
 *  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
 *  - separate 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"

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

extern BOOL FileExists(LPCSTR szFilename);
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)
{
    HANDLE hFile;
    CHAR *pTemp;
    DWORD size,i,len,bytes_left,bytes_read;

    hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    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);
}

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 0x100:          DIALOG_FileNew(); break;
     case 0x101:         DIALOG_FileOpen(); break;
     case 0x102:         DIALOG_FileSave(); break;
     case 0x103:       DIALOG_FileSaveAs(); break;
     case 0x104:        DIALOG_FilePrint(); break;
     case 0x105:    DIALOG_FilePageSetup(); break;
     case 0x106:   DIALOG_FilePrinterSetup();break;
     case 0x108:         DIALOG_FileExit(); break;

     case 0x110:         DIALOG_EditUndo(); break;
     case 0x111:          DIALOG_EditCut(); break;
     case 0x112:         DIALOG_EditCopy(); break;
     case 0x113:        DIALOG_EditPaste(); break;
     case 0x114:       DIALOG_EditDelete(); break;
     case 0x116:    DIALOG_EditSelectAll(); break;
     case 0x117:     DIALOG_EditTimeDate();break;
     case 0x119:         DIALOG_EditWrap(); break;

     case 0x120:     DIALOG_Search(); break;
     case 0x121:       DIALOG_SearchNext(); break;

     case 0x130:     DIALOG_HelpContents(); break;
     case 0x131:       DIALOG_HelpSearch(); break;
     case 0x132:      DIALOG_HelpHelp(); break;
     case 0x135:      DIALOG_HelpLicense(); break;
     case 0x136:  DIALOG_HelpNoWarranty(); break;
     case 0x137:   DIALOG_HelpAboutWine(); break;

//     default:
//      LANGUAGE_DefaultHandle(wParam);
   }
   return 0;
}



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

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

int AlertFileDoesNotExist(LPSTR szFileName) {

   int nResult;
   CHAR szMessage[MAX_STRING_LEN];
   CHAR szRessource[MAX_STRING_LEN];

   LoadString(Globals.hInstance, STRING_DOESNOTEXIST, szRessource,
              sizeof(szRessource));
   wsprintf(szMessage, szRessource, szFileName);

   LoadString(Globals.hInstance, STRING_ERROR,  szRessource, sizeof(szRessource));

   nResult = MessageBox(Globals.hMainWnd, szMessage, szRessource,
                        MB_ICONEXCLAMATION | MB_YESNO);

   return(nResult);
}

void HandleCommandLine(LPSTR cmdline)
{

    while (*cmdline && (*cmdline == ' ' || *cmdline == '-'))

    {
        CHAR   option;

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

    if (*cmdline)
    {
        /* file name is passed in the command line */
        char *file_name;
        BOOL file_exists;
        char buf[MAX_PATH];

        if (FileExists(cmdline))
        {
            file_exists = TRUE;
            file_name = cmdline;
        }
        else
        {
            /* try to find file with ".txt" extention */
            if (!strcmp(".txt", cmdline + strlen(cmdline) - strlen(".txt")))
            {
                file_exists = FALSE;
                file_name = cmdline;
            }
            else
            {
                strncpy(buf, cmdline, MAX_PATH - strlen(".txt") - 1);
                strcat(buf, ".txt");
                file_name = buf;
                file_exists = FileExists(buf);
            }
        }

        if (file_exists)
        {
            DoOpenFile(file_name);
            InvalidateRect(Globals.hMainWnd, NULL, FALSE);
        }
        else
        {
            switch (AlertFileDoesNotExist(file_name)) {
            case IDYES:
                DoOpenFile(file_name);
                break;

            case IDNO:
                break;
            }
        }
     }
}


/***********************************************************************
 *
 *           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";

    /* 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_LoadMenus();

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

    HandleCommandLine(cmdline);

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