/*
 *  Notepad (dialog.c)
 *
 *  Copyright 1998,99 Marcel Baur <mbaur@g26.ethz.ch>
 *  To be distributed under the Wine License
 */

#include <assert.h>
#include <stdio.h>
#include <windows.h>
#include <commdlg.h>
#include <winerror.h>

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

static LRESULT WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);



int AlertIDS(UINT ids_message, UINT ids_caption, WORD type) {
  /*
   * Given some ids strings, this acts as a language-aware wrapper for 
   * "MessageBox"
   */
   CHAR szMessage[MAX_STRING_LEN];
   CHAR szCaption[MAX_STRING_LEN];
   
   LoadString(Globals.hInstance, ids_message, szMessage, sizeof(szMessage));
   LoadString(Globals.hInstance, ids_caption, szCaption, sizeof(szCaption));
   
   return (MessageBox(Globals.hMainWnd, szMessage, szCaption, type));
}

void AlertFileNotFound(LPSTR szFileName) {

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

   /* Load and format szMessage */
   LoadString(Globals.hInstance, IDS_NOTFOUND, szRessource, sizeof(szRessource));
   wsprintf(szMessage, szRessource, szFileName);
   
   /* Load szCaption */
   LoadString(Globals.hInstance, IDS_ERROR,  szRessource, sizeof(szRessource));

   /* Display Modal Dialog */
   nResult = MessageBox(Globals.hMainWnd, szMessage, szRessource, MB_ICONEXCLAMATION);

}

int AlertFileNotSaved(LPSTR szFileName) {

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

   /* Load and format Message */

   LoadString(Globals.hInstance, IDS_NOTSAVED, szRessource, sizeof(szRessource));
   wsprintf(szMessage, szRessource, szFileName);
   
   /* Load Caption */

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

   /* Display modal */
   nResult = MessageBox(Globals.hMainWnd, szMessage, szRessource, MB_ICONEXCLAMATION|MB_YESNOCANCEL);
   return(nResult);
}


VOID AlertOutOfMemory(void) {
   int nResult;
   
   nResult = AlertIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_ICONEXCLAMATION);
   PostQuitMessage(1);
}


BOOL FileExists(LPCSTR szFilename) {
/*
 *  Returns: TRUE  - if "szFileName" exists
 *           FALSE - if it does not
 */
   WIN32_FIND_DATA entry;
   HANDLE hFile;
   
   hFile = FindFirstFile(szFilename, &entry);
   
   return (hFile!=INVALID_HANDLE_VALUE);
}

VOID DoSaveFile(VOID) {

    /* FIXME: Really Save the file */
    /* ... (Globals.szFileName); */
}


BOOL DoCloseFile(void) {
/* Return value: TRUE  - User agreed to close (both save/don't save) */
/*               FALSE - User cancelled close by selecting "Cancel" */

    int nResult;
   
    if (strlen(Globals.szFileName)>0) {
        /* prompt user to save changes */
        nResult = AlertFileNotSaved(Globals.szFileName);
        switch (nResult) {
            case IDYES:     DoSaveFile();
                            break;

            case IDNO:      break;

            case IDCANCEL:  return(FALSE);
                            break;
                      
            default:        return(FALSE);
                            break;
        } /* switch */
    } /* if */
  
    /* Forget file name  */
    lstrcpy(Globals.szFileName, "");
    LANGUAGE_UpdateWindowCaption();
    return(TRUE);
}


void DoOpenFile(LPCSTR szFileName) {

    /* Close any files and prompt to save changes */
    if (DoCloseFile()) {
        GetFileTitle(szFileName, Globals.szFileName, sizeof(Globals.szFileName));
        LANGUAGE_UpdateWindowCaption();

        LoadBufferFromFile(szFileName);
    }
}


VOID DIALOG_FileNew(VOID)
{
    /* Close any files and promt to save changes */
    if (DoCloseFile()) {
        TrashBuffer();
    }
}

VOID DIALOG_FileOpen(VOID)
{
        OPENFILENAME openfilename;
        CHAR szPath[MAX_PATHNAME_LEN];
        CHAR szDir[MAX_PATHNAME_LEN];
        CHAR szzFilter[2 * MAX_STRING_LEN + 100];
        CHAR szDefaultExt[4];
        LPSTR p = szzFilter;

        lstrcpy(szDefaultExt, "txt");

        LoadString(Globals.hInstance, IDS_TEXT_FILES_TXT, p, MAX_STRING_LEN);
        p += strlen(p) + 1;
        lstrcpy(p, "*.txt");
        p += strlen(p) + 1;
        LoadString(Globals.hInstance, IDS_ALL_FILES, p, MAX_STRING_LEN);
        p += strlen(p) + 1;
        lstrcpy(p, "*.*");
        p += strlen(p) + 1;
        *p = '\0';

        GetCurrentDirectory(sizeof(szDir), szDir);
        lstrcpy(szPath,"*.txt");

        openfilename.lStructSize       = sizeof(OPENFILENAME);
        openfilename.hwndOwner         = Globals.hMainWnd;
        openfilename.hInstance         = Globals.hInstance;
        openfilename.lpstrFilter       = szzFilter;
        openfilename.lpstrCustomFilter = 0;
        openfilename.nMaxCustFilter    = 0;
        openfilename.nFilterIndex      = 0;
        openfilename.lpstrFile         = szPath;
        openfilename.nMaxFile          = sizeof(szPath);
        openfilename.lpstrFileTitle    = 0;
        openfilename.nMaxFileTitle     = 0;
        openfilename.lpstrInitialDir   = szDir;
        openfilename.lpstrTitle        = 0;
        openfilename.Flags             = OFN_FILEMUSTEXIST + OFN_PATHMUSTEXIST;
        openfilename.nFileOffset       = 0;
        openfilename.nFileExtension    = 0;
        openfilename.lpstrDefExt       = szDefaultExt;
        openfilename.lCustData         = 0;
        openfilename.lpfnHook          = 0;
        openfilename.lpTemplateName    = 0;

        if (GetOpenFileName(&openfilename)) {
                
                if (FileExists(openfilename.lpstrFile))
                    DoOpenFile(openfilename.lpstrFile);
                else 
                    AlertFileNotFound(openfilename.lpstrFile);
                    
        }
}

VOID DIALOG_FileSave(VOID)
{
        /* FIXME: Save File */

        DIALOG_FileSaveAs();
}

VOID DIALOG_FileSaveAs(VOID)
{
        OPENFILENAME saveas;
        CHAR szPath[MAX_PATHNAME_LEN];
        CHAR szDir[MAX_PATHNAME_LEN];
        CHAR szDefaultExt[4];
        CHAR szzFilter[2 * MAX_STRING_LEN + 100];
       
        LPSTR p = szzFilter;

        lstrcpy(szDefaultExt, "txt");

        LoadString(Globals.hInstance, IDS_TEXT_FILES_TXT, p, MAX_STRING_LEN);
        p += strlen(p) + 1;
        lstrcpy(p, "*.txt");
        p += strlen(p) + 1;
        LoadString(Globals.hInstance, IDS_ALL_FILES, p, MAX_STRING_LEN);
        p += strlen(p) + 1;
        lstrcpy(p, "*.*");
        p += strlen(p) + 1;
        *p = '\0';

        lstrcpy(szPath,"*.*");

        GetCurrentDirectory(sizeof(szDir), szDir);

        saveas.lStructSize       = sizeof(OPENFILENAME);
        saveas.hwndOwner         = Globals.hMainWnd;
        saveas.hInstance         = Globals.hInstance;
        saveas.lpstrFilter       = szzFilter;
        saveas.lpstrCustomFilter = 0;
        saveas.nMaxCustFilter    = 0;
        saveas.nFilterIndex      = 0;
        saveas.lpstrFile         = szPath;
        saveas.nMaxFile          = sizeof(szPath);
        saveas.lpstrFileTitle    = 0;
        saveas.nMaxFileTitle     = 0;
        saveas.lpstrInitialDir   = szDir;
        saveas.lpstrTitle        = 0;
        saveas.Flags             = OFN_PATHMUSTEXIST + OFN_OVERWRITEPROMPT + OFN_HIDEREADONLY;
        saveas.nFileOffset       = 0;
        saveas.nFileExtension    = 0;
        saveas.lpstrDefExt       = szDefaultExt;
        saveas.lCustData         = 0;
        saveas.lpfnHook          = 0;
        saveas.lpTemplateName    = 0;

        if (GetSaveFileName(&saveas)) {
            lstrcpy(Globals.szFileName, saveas.lpstrFile);
            LANGUAGE_UpdateWindowCaption();
            DIALOG_FileSave();
        }
}

VOID DIALOG_FilePrint(VOID)
{
        LONG bFlags, nBase;
        WORD nOffset;
        DOCINFO di;
        int nResult;
        HDC hContext;
        PRINTDLG printer;

        CHAR szDocumentName[MAX_STRING_LEN]; /* Name of document */
        CHAR szPrinterName[MAX_STRING_LEN];  /* Name of the printer */
        CHAR szDeviceName[MAX_STRING_LEN];   /* Name of the printer device */
        CHAR szOutput[MAX_STRING_LEN];       /* in which file/device to print */

/*        LPDEVMODE  hDevMode;   */
/*        LPDEVNAMES hDevNames; */

/*        hDevMode  = GlobalAlloc(GMEM_MOVEABLE + GMEM_ZEROINIT, sizeof(DEVMODE)); */
/*        hDevNames = GlobalAlloc(GMEM_MOVEABLE + GMEM_ZEROINIT, sizeof(DEVNAMES)); */

        /* Get Current Settings */

        printer.lStructSize           = sizeof(PRINTDLG);
        printer.hwndOwner             = Globals.hMainWnd;
        printer.hInstance             = Globals.hInstance;

        /* Let PrintDlg create a DEVMODE structure */
        printer.hDevMode              = 0;
        printer.hDevNames             = 0;
        printer.hDC                   = 0;
        printer.Flags                 = PD_RETURNDEFAULT;
        printer.nFromPage             = 0;
        printer.nToPage               = 0;
        printer.nMinPage              = 0;
        printer.nMaxPage              = 0;
        printer.nCopies               = 0;
        printer.lCustData             = 0;
        printer.lpfnPrintHook         = 0;
        printer.lpfnSetupHook         = 0;
        printer.lpPrintTemplateName   = 0;
        printer.lpSetupTemplateName   = 0;
        printer.hPrintTemplate        = 0;
        printer.hSetupTemplate        = 0;

        nResult = PrintDlg(&printer);

/*        hContext = CreateDC(, szDeviceName, "TEST.TXT", 0); */

        /* Congratulations to those Microsoft Engineers responsable */
        /* for the following pointer acrobatics */

        assert(printer.hDevNames!=0);

        nBase = (LONG)(printer.hDevNames);

        nOffset = (WORD)((LPDEVNAMES) printer.hDevNames)->wDriverOffset;
        lstrcpy(szPrinterName, (LPCSTR) (nBase + nOffset));

        nOffset = (WORD)((LPDEVNAMES) printer.hDevNames)->wDeviceOffset;
        lstrcpy(szDeviceName, (LPCSTR) (nBase + nOffset));

        nOffset = (WORD)((LPDEVNAMES) printer.hDevNames)->wOutputOffset;
        lstrcpy(szOutput, (LPCSTR) (nBase + nOffset));

        MessageBox(Globals.hMainWnd, szPrinterName, "Printer Name", MB_ICONEXCLAMATION);
        MessageBox(Globals.hMainWnd, szDeviceName,  "Device Name",  MB_ICONEXCLAMATION);
        MessageBox(Globals.hMainWnd, szOutput,      "Output",       MB_ICONEXCLAMATION);

        /* Set some default flags */

        bFlags = PD_RETURNDC + PD_SHOWHELP;

        if (TRUE) {
             /* Remove "Print Selection" if there is no selection */
             bFlags = bFlags + PD_NOSELECTION;
        } 

        printer.Flags                 = bFlags;
/*
        printer.nFromPage             = 0;
        printer.nToPage               = 0;
        printer.nMinPage              = 0;
        printer.nMaxPage              = 0;
*/

        /* Let commdlg manage copy settings */
        printer.nCopies               = (WORD)PD_USEDEVMODECOPIES;

        if (PrintDlg(&printer)) {

            /* initialize DOCINFO */
            di.cbSize = sizeof(DOCINFO);
            lstrcpy((LPSTR)di.lpszDocName, szDocumentName);
            lstrcpy((LPSTR)di.lpszOutput,  szOutput);

            hContext = printer.hDC;
            assert(hContext!=0);
            assert( (int) hContext!=PD_RETURNDC);

            SetMapMode(hContext, MM_LOMETRIC);
/*          SetViewPortExExt(hContext, 10, 10, 0); */
            SetBkMode(hContext, OPAQUE);

            nResult = TextOut(hContext, 0, 0, " ", 1);
            assert(nResult != 0);

            nResult = StartDoc(hContext, &di);
            assert(nResult != SP_ERROR);

            nResult = StartPage(hContext);
            assert(nResult >0);

            /* FIXME: actually print */

            nResult = EndPage(hContext);

            switch (nResult) {
               case SP_ERROR:
                       MessageBox(Globals.hMainWnd, "Generic Error", "Print Engine Error", MB_ICONEXCLAMATION);
                       break;
               case SP_APPABORT:
                       MessageBox(Globals.hMainWnd, "The print job was aborted.", "Print Engine Error", MB_ICONEXCLAMATION);
                       break;
               case SP_USERABORT:
                       MessageBox(Globals.hMainWnd, "The print job was aborted using the Print Manager ", "Print Engine Error", MB_ICONEXCLAMATION);
                       break;
               case SP_OUTOFDISK:
                       MessageBox(Globals.hMainWnd, "Out of disk space", "Print Engine Error", MB_ICONEXCLAMATION);
                       break;
               case SP_OUTOFMEMORY:
                       AlertOutOfMemory();
                       break;
               default:
                       MessageBox(Globals.hMainWnd, "Default", "Print", MB_ICONEXCLAMATION); 
            } /* switch */
            nResult = EndDoc(hContext);
            assert(nResult>=0);
            nResult = DeleteDC(hContext);
            assert(nResult!=0);
        } /* if */

/*       GlobalFree(hDevNames); */
/*       GlobalFree(hDevMode); */
}

VOID DIALOG_FilePageSetup(VOID)
{
        DIALOG_PageSetup();
}

VOID DIALOG_FilePrinterSetup(VOID)
{
        PRINTDLG printer;

        printer.lStructSize          = sizeof(PRINTDLG);
        printer.hwndOwner            = Globals.hMainWnd;
        printer.hInstance            = Globals.hInstance;
        printer.hDevMode             = 0;
        printer.hDevNames            = 0;
        printer.hDC                  = 0;
        printer.Flags                = PD_PRINTSETUP;
        printer.nFromPage            = 0;
        printer.nToPage              = 0;
        printer.nMinPage             = 0;
        printer.nMaxPage             = 0;
        printer.nCopies              = 1;
        printer.lCustData            = 0;
        printer.lpfnPrintHook        = 0;
        printer.lpfnSetupHook        = 0;
        printer.lpPrintTemplateName  = 0;
        printer.lpSetupTemplateName  = 0;
        printer.hPrintTemplate       = 0;
        printer.hSetupTemplate       = 0;
        
        if (PrintDlg(&printer)) {
            /* do nothing */
        };

}

VOID DIALOG_FileExit(VOID)
{
        if (DoCloseFile()) {
               PostQuitMessage(0);
        }
}

VOID DIALOG_EditUndo(VOID)
{
   MessageBox(Globals.hMainWnd, "Undo", "Debug", MB_ICONEXCLAMATION);
        /* undo */
}

VOID DIALOG_EditCut(VOID)
{
    HANDLE hMem;

    hMem = GlobalAlloc(GMEM_ZEROINIT, 99);

    OpenClipboard(Globals.hMainWnd);
    EmptyClipboard();

    /* FIXME: Get text */
    lstrcpy((CHAR *)hMem, "Hello World");

    SetClipboardData(CF_TEXT, hMem);
    CloseClipboard();

    GlobalFree(hMem);
}

VOID DIALOG_EditCopy(VOID)
{
    HANDLE hMem;

    hMem = GlobalAlloc(GMEM_ZEROINIT, 99);

    OpenClipboard(Globals.hMainWnd);
    EmptyClipboard();

    /* FIXME: Get text */
    lstrcpy((CHAR *)hMem, "Hello World");

    SetClipboardData(CF_TEXT, hMem);
    CloseClipboard();

    GlobalFree(hMem);
}

VOID DIALOG_EditPaste(VOID)
{
    HANDLE hClipText;

    if (IsClipboardFormatAvailable(CF_TEXT)) {
        OpenClipboard(Globals.hMainWnd);
        hClipText = GetClipboardData(CF_TEXT);
        CloseClipboard();
        MessageBox(Globals.hMainWnd, (CHAR *)hClipText, "PASTE", MB_ICONEXCLAMATION);
    }
}

VOID DIALOG_EditDelete(VOID)
{
        /* Delete */
}

VOID DIALOG_EditSelectAll(VOID)
{
        /* Select all */
}

VOID DIALOG_EditTimeDate(VOID)
{
    SYSTEMTIME   st;
    LPSYSTEMTIME lpst = &st;
    CHAR         szDate[MAX_STRING_LEN];
    LPSTR        date = szDate;
    
    GetLocalTime(&st);
    GetDateFormat(LOCALE_USER_DEFAULT, LOCALE_SLONGDATE, lpst, NULL, date, MAX_STRING_LEN);
    GetTimeFormat(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, lpst, NULL, date, MAX_STRING_LEN);

}

VOID DIALOG_EditWrap(VOID)
{
        Globals.bWrapLongLines = !Globals.bWrapLongLines;
        CheckMenuItem(Globals.hEditMenu, NP_EDIT_WRAP, MF_BYCOMMAND | 
        (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
}

VOID DIALOG_Search(VOID)
{
        Globals.find.lStructSize      = sizeof(Globals.find);
        Globals.find.hwndOwner        = Globals.hMainWnd;
        Globals.find.hInstance        = Globals.hInstance;
        Globals.find.lpstrFindWhat    = (CHAR *) &Globals.szFindText;
        Globals.find.wFindWhatLen     = sizeof(Globals.szFindText);
        Globals.find.lpstrReplaceWith = 0;
        Globals.find.wReplaceWithLen  = 0;
        Globals.find.Flags            = FR_DOWN;
        Globals.find.lCustData        = 0;
        Globals.find.lpfnHook         = 0;
        Globals.find.lpTemplateName   = 0;

        /* We only need to create the modal FindReplace dialog which will */
        /* notify us of incoming events using hMainWnd Window Messages    */

        Globals.hFindReplaceDlg = FindText(&Globals.find);
        assert(Globals.hFindReplaceDlg !=0);
}

VOID DIALOG_SearchNext(VOID)
{
        /* Search Next */
}

VOID DIALOG_HelpContents(VOID)
{
        WinHelp(Globals.hMainWnd, HELPFILE, HELP_INDEX, 0);
}

VOID DIALOG_HelpSearch(VOID)
{
        /* Search Help */
}

VOID DIALOG_HelpHelp(VOID)
{
        WinHelp(Globals.hMainWnd, HELPFILE, HELP_HELPONHELP, 0);
}

VOID DIALOG_HelpLicense(VOID)
{
        WineLicense(Globals.hMainWnd);
}

VOID DIALOG_HelpNoWarranty(VOID)
{
        WineWarranty(Globals.hMainWnd);
}

VOID DIALOG_HelpAboutWine(VOID)
{
        CHAR szNotepad[MAX_STRING_LEN];

        LoadString(Globals.hInstance, IDS_NOTEPAD, szNotepad, sizeof(szNotepad));
        ShellAbout(Globals.hMainWnd, szNotepad, "Notepad\n" WINE_RELEASE_INFO, 0);
}

/***********************************************************************
 *
 *           DIALOG_PageSetup
 */

VOID DIALOG_PageSetup(VOID)
{
  WNDPROC lpfnDlg;

  lpfnDlg = MakeProcInstance(DIALOG_PAGESETUP_DlgProc, Globals.hInstance);
  DialogBox(Globals.hInstance, STRING_PAGESETUP_Xx, Globals.hMainWnd, (DLGPROC)lpfnDlg);
  FreeProcInstance(lpfnDlg);
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *           DIALOG_PAGESETUP_DlgProc
 */

static LRESULT WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{

   switch (msg)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case IDOK:
          /* save user input and close dialog */
          GetDlgItemText(hDlg, NP_PAGESETUP_HEAD,   Globals.szHeader,       sizeof(Globals.szHeader));
          GetDlgItemText(hDlg, NP_PAGESETUP_TAIL,   Globals.szFooter,       sizeof(Globals.szFooter));
          GetDlgItemText(hDlg, NP_PAGESETUP_TOP,    Globals.szMarginTop,    sizeof(Globals.szMarginTop));
          GetDlgItemText(hDlg, NP_PAGESETUP_BOTTOM, Globals.szMarginBottom, sizeof(Globals.szMarginBottom));
          GetDlgItemText(hDlg, NP_PAGESETUP_LEFT,   Globals.szMarginLeft,   sizeof(Globals.szMarginLeft));
          GetDlgItemText(hDlg, NP_PAGESETUP_RIGHT,  Globals.szMarginRight,  sizeof(Globals.szMarginRight));
          EndDialog(hDlg, IDOK);
          return TRUE;

        case IDCANCEL:
          /* discard user input and close dialog */
          EndDialog(hDlg, IDCANCEL);
          return TRUE;

        case IDHELP:
          /* FIXME: Bring this to work */
          MessageBox(Globals.hMainWnd, "Sorry, no help available", "Help", MB_ICONEXCLAMATION);
          return TRUE;
        }
      break;

    case WM_INITDIALOG:
       /* fetch last user input prior to display dialog */
       SetDlgItemText(hDlg, NP_PAGESETUP_HEAD,   Globals.szHeader);
       SetDlgItemText(hDlg, NP_PAGESETUP_TAIL,   Globals.szFooter);
       SetDlgItemText(hDlg, NP_PAGESETUP_TOP,    Globals.szMarginTop);
       SetDlgItemText(hDlg, NP_PAGESETUP_BOTTOM, Globals.szMarginBottom);
       SetDlgItemText(hDlg, NP_PAGESETUP_LEFT,   Globals.szMarginLeft);
       SetDlgItemText(hDlg, NP_PAGESETUP_RIGHT,  Globals.szMarginRight);
       break;
    }

  return FALSE;
}
