#include <windows.h>
#include "hoz.h"
#include "hozwin.h"

HFONT g_font;
HWND maindlg;
HINSTANCE hinst;
char nchar, hozfile[MAX_PATH + 1];

extern char outpath[MAXLEN];
extern size_t fullsize, partsize, headersize;
extern int showprogress, forceow, simulate;

void hoz_print(const char *str)
{
    SendDlgItemMessage(maindlg, ID_EDIT_RPRT, EM_REPLACESEL,
                       (WPARAM) FALSE, (LPARAM) str);
}

void hoz_lf()
{
    SendDlgItemMessage(maindlg, ID_EDIT_RPRT, EM_REPLACESEL,
                       (WPARAM) FALSE, (LPARAM) "\r\n");
}


/**
 * WinMain
 */
int APIENTRY
WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    hinst = hInstance;
    return (int) hoz_dlgopen();
}

/**
 * hoz_replace_ask - ask the user if an output file should be replaced
 * @s: filename
 */
int hoz_replace_ask(const char *s)
{
    char foo[1024];
    int bar;
    sprintf(foo, HOZ_REPLACE_W, s);
    bar = MessageBox(maindlg, foo, HOZ_PROGNAME,
                     MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL);
    return (bar == IDYES);
}

/**
 * hoz_getsize - Gets the size in bytes from the size editbox
 */
size_t hoz_getsize()
{
    char foo[100], baz[61];
    size_t bar, mult = 1;
    GetDlgItemText(maindlg, ID_EDIT_SIZE, foo, 60);
    switch (SendDlgItemMessage(maindlg, ID_COMBO_SIZE, CB_GETCURSEL, (WPARAM)0, (LPARAM)0)) {
        case 0:
            mult = 1;
	    break;
        case 1:
            mult = 1024;
	    break;
        case 2:
            mult = 1024*1024;
    }
    sprintf(baz, HOZ_BADSIZE, foo);
    bar = (size_t) atolmp((char*)foo, mult);
    partsize = (bar) ? bar : 0;
    if (!partsize) {
        MessageBox(NULL, baz, HOZ_PROGNAME, MB_ICONERROR | MB_SYSTEMMODAL);
    }
    sprintf(foo, "partsize=%u", partsize);
    return partsize;
}


/**
 * hoz_getoutpdir - Gets the output path from the editbox
 */
int hoz_getoutpdir()
{
    GetDlgItemText(maindlg, ID_EDIT_OUTP, outpath, MAXLEN);
    if (!isdir(outpath)) {
        hoz_echo(411, outpath);
        return 411;
    }
    return 0;
}


/**
 * hoz_initofn - initializes an OPENFILENAME structure to open a load/save file
 *               dialog
 * @ofn: pointer to OPENFILENAME
 * @outfile: buffer to store the filename
 */
void hoz_initofn(OPENFILENAME * ofn, char *outfile)
{
    ZeroMemory(ofn, sizeof(OPENFILENAME));
    ofn->lStructSize = sizeof(OPENFILENAME);
    ofn->hwndOwner = maindlg;   /* modal dialog */
    ofn->hInstance = NULL;
    ofn->lpstrFilter = NULL;
    ofn->lpstrCustomFilter = NULL;
    ofn->nMaxCustFilter = 0;
    ofn->nFilterIndex = 1;
    ofn->lpstrFile = outfile;
    ofn->nMaxFile = MAX_PATH;
    ofn->lpstrFileTitle = NULL;
    ofn->nMaxFileTitle = 0;
    ofn->lpstrInitialDir = NULL;
    ofn->lpstrTitle = NULL;
    ofn->lpstrDefExt = NULL;

    ofn->Flags =
        OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN | OFN_NODEREFERENCELINKS |
        OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;

    /* MSDN:
     *   "The first character of this buffer must be NULL if initialization is
     *   not necessary."
     */
    lstrcpy(outfile, "");
}

/**
 * hoz_fileop - pops up an open/save file dialog
 * @cutpaste: 0=cut, 1=paste
 */
int hoz_fileop(const int cutpaste)
{
    OPENFILENAME ofn;
    char file[MAX_PATH + 1], foo[1024];

    hoz_initofn(&ofn, file);
    if (cutpaste) {             /* paste */
        sprintf(foo, "%s (*.0)$*.0", HOZ_FDPASTE);
        foo[strlen(foo) + 1] = 0;
        foo[strlen(HOZ_FDPASTE) + 6] = 0;
        ofn.lpstrFilter = foo;
        ofn.lpstrTitle = HOZ_PROGNAME;
        ofn.lpstrDefExt = "0";
    } else {                    /* cut */
        sprintf(foo, "%s (*)$*", HOZ_FDCUT);
        foo[strlen(foo) + 1] = 0;
        foo[strlen(HOZ_FDCUT) + 4] = 0;
        ofn.lpstrFilter = foo;
        ofn.lpstrTitle = HOZ_PROGNAME;
        ofn.lpstrDefExt = "*";
    }
    if (GetOpenFileName(&ofn) == TRUE) {
        lstrcpy(hozfile, file);
        return 0;
    }
    return 1;
}

/**
 * hoz_loadfonts - creates a logic font in g_font (global var)
 * @font: font's name
 * @fsize: font's height
 *
 * the logic font must be removed with DeleteObject() when the program closes
 */
void hoz_loadfonts(const char *font, const int fsize)
{
    LOGFONT lfont;
    lfont.lfHeight = fsize;
    lfont.lfWidth = 0;
    lfont.lfEscapement = 0;
    lfont.lfOrientation = 0;
    lfont.lfWeight = 200;
    lfont.lfItalic = 0;
    lfont.lfUnderline = 0;
    lfont.lfStrikeOut = 0;
    lfont.lfCharSet = ANSI_CHARSET;
    lfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
    lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lfont.lfQuality = DEFAULT_QUALITY;
    lfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
    lstrcpy(lfont.lfFaceName, font);
    g_font = CreateFontIndirect(&lfont);
}

/**
 * hoz_ready - useless...
 */
void hoz_ready()
{
    hoz_lf();
    hoz_print(HOZ_READY);
    hoz_lf();
}

/**
 * dialog_main - dialog's message handler
 */
LRESULT CALLBACK
dialog_main(HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam)
{

    switch (message) {
    case WM_INITDIALOG:
        maindlg = hdlg;
        getcwd(outpath, MAXLEN);
        hoz_loadfonts("Tahoma", 13);
        SendDlgItemMessage(maindlg, ID_EDIT_SIZE, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_BUTTON_CUT, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_BUTTON_PASTE, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_STATIC_SIZE, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_STATIC_OUTP, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_EDIT_OUTP, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_EDIT_RPRT, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_CHECK_PRGR, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SendDlgItemMessage(maindlg, ID_COMBO_SIZE, WM_SETFONT,
                           (WPARAM) g_font, (DWORD) TRUE);
        SetDlgItemText(maindlg, ID_EDIT_SIZE, "1457152");
        SetDlgItemText(maindlg, ID_EDIT_OUTP, outpath);
        SetDlgItemText(maindlg, ID_STATIC_SIZE, HOZ_PSIZECAPTION);
        SetDlgItemText(maindlg, ID_STATIC_OUTP, HOZ_OUTPCAPTION);
        SetDlgItemText(maindlg, ID_CHECK_PRGR, HOZ_CBPRGRCAPTION);
        SetDlgItemText(maindlg, ID_BUTTON_CUT, HOZ_BTNCUTCAPTION);
        SetDlgItemText(maindlg, ID_BUTTON_PASTE, HOZ_BTNPASTECAPTION);
	SendDlgItemMessage(maindlg, ID_COMBO_SIZE, CB_ADDSTRING, 0, (LPARAM)"bytes");
	SendDlgItemMessage(maindlg, ID_COMBO_SIZE, CB_ADDSTRING, 0, (LPARAM)"KiB");
	SendDlgItemMessage(maindlg, ID_COMBO_SIZE, CB_ADDSTRING, 0, (LPARAM)"MiB");
	SendDlgItemMessage(maindlg, ID_COMBO_SIZE, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
        {
            char foo[60];
            sprintf(foo, "%s - Hacha Open Zource", HOZ_PROGNAME);
            SendMessage(maindlg, WM_SETTEXT, (WPARAM) 0, (LPARAM) foo);
        }
        hoz_echo(301, NULL);
        hoz_ready();
        fullsize = 0;
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD(wparam)) {
        case ID_BUTTON_CUT:
            SendDlgItemMessage(maindlg, ID_EDIT_RPRT, EM_SETSEL,
                               (WPARAM) 99998, (DWORD) 99999);
            SendDlgItemMessage(maindlg, ID_EDIT_RPRT, EM_SCROLLCARET,
                               (WPARAM) 0, (DWORD) 0);
            if (hoz_getsize() && !hoz_getoutpdir() && !hoz_fileop(0)) {
                hoz_cut_main(hozfile);
                hoz_ready();
            }
            break;
        case ID_BUTTON_PASTE:
            SendDlgItemMessage(maindlg, ID_EDIT_RPRT, EM_SETSEL,
                               (WPARAM) 99998, (DWORD) 99999);
            SendDlgItemMessage(maindlg, ID_EDIT_RPRT, EM_SCROLLCARET,
                               (WPARAM) 0, (DWORD) 0);
            if (!hoz_fileop(1) && !hoz_getoutpdir()) {
                hoz_paste_main(hozfile);
                hoz_ready();
            }
            break;
        case ID_CHECK_PRGR:
            showprogress = !SendDlgItemMessage(maindlg,
                                               ID_CHECK_PRGR, BM_GETCHECK,
                                               (WPARAM) 0, (DWORD) 0);
            CheckDlgButton(maindlg, ID_CHECK_PRGR, showprogress);
            break;
        case ID_EDIT_RPRT:
            if (HIWORD(wparam) == EN_ERRSPACE) {
                MessageBox(NULL, "ID_EDIT_RPRT", "EN_ERRSPACE", 0);
            }
            break;
        case IDCANCEL:
            EndDialog(maindlg, LOWORD(wparam));
            return TRUE;
        }
    }
    return FALSE;
}



/*
    Helper routine.  Take an input pointer, return closest
    pointer that is aligned on a DWORD (4 byte) boundary.
 */
LPWORD lpwAlign(LPWORD lpIn)
{
    ULONG ul;
    ul = (ULONG) lpIn;
    ul += 3;
    ul >>= 2;
    ul <<= 2;
    return (LPWORD) ul;
}

/**
 * hoz_dlgopen - opens the dialog
 */
LRESULT hoz_dlgopen()
{
    HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWORD lpw;
    LRESULT ret;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
    if (!hgbl)
        return -1;
    lpdt = (LPDLGTEMPLATE) GlobalLock(hgbl);
    lpdt->style =
        WS_POPUP | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | DS_CENTER;
    lpdt->cdit = 9;             /* number of controls */
    lpdt->x = -1;
    lpdt->y = -1;
    lpdt->cx = 170;
    lpdt->cy = 186;
    lpw = (LPWORD) (lpdt + 1);
    *lpw++ = 0;                 /* no menu */
    *lpw++ = 0;                 /* predefined dialog box class (by default) */
    *lpw++ = 0;

    /*
     * ID_STATIC_SIZE
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 3;
    lpdit->y = 6;
    lpdit->cx = 40;
    lpdit->cy = 8;
    lpdit->id = ID_STATIC_SIZE;
    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0082;            /* static */
    *lpw++ = 0;
    *lpw++ = 0;


    /*
     * ID_EDIT_SIZE
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 42;
    lpdit->y = 4;
    lpdit->cx = 55;
    lpdit->cy = 11;
    lpdit->id = ID_EDIT_SIZE;
    lpdit->style =
        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL/* | ES_NUMBER*/;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0081;            /* editbox */
    *lpw++ = 0;
    *lpw++ = 0;

    /*
     * ID_COMBO_SIZE
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 97;
    lpdit->y = 4;
    lpdit->cx = 30;
    lpdit->cy = 95;
    lpdit->id = ID_COMBO_SIZE;
    lpdit->style =
        WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_DROPDOWNLIST;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0085;            /* combobox */
    *lpw++ = 0;
    *lpw++ = 0;

    /*
     * ID_CHECK_PRGR
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 3;
    lpdit->y = 27;
    lpdit->cx = 100;
    lpdit->cy = 12;
    lpdit->id = ID_CHECK_PRGR;
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_CHECKBOX;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;            /* button */
    *lpw++ = 0;
    *lpw++ = 0;

    /*
     * ID_BUTTON_CUT
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 132;
    lpdit->y = 3;
    lpdit->cx = 34;
    lpdit->cy = 12;
    lpdit->id = ID_BUTTON_CUT;
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;            /* button */
    *lpw++ = 0;
    *lpw++ = 0;

    /*
     * ID_BUTTON_PASTE
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 132;
    lpdit->y = 18;
    lpdit->cx = 34;
    lpdit->cy = 12;
    lpdit->id = ID_BUTTON_PASTE;
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;
    *lpw++ = 0;
    *lpw++ = 0;


    /*
     * ID_EDIT_RPRT
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 5;
    lpdit->y = 40;
    lpdit->cx = 161;
    lpdit->cy = 140;
    lpdit->id = ID_EDIT_RPRT;
    lpdit->style =
        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOVSCROLL | ES_MULTILINE |
        ES_READONLY | WS_VSCROLL;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0081;            /* editbox */
    *lpw++ = 0;
    *lpw++ = 0;

    /*
     * ID_STATIC_OUTP
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 3;
    lpdit->y = 17;
    lpdit->cx = 40;
    lpdit->cy = 8;
    lpdit->id = ID_STATIC_OUTP;
    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0082;            /* static */
    *lpw++ = 0;
    *lpw++ = 0;

    /*
     * ID_EDIT_OUTP
     */
    lpw = lpwAlign(lpw);
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x = 42;
    lpdit->y = 17;
    lpdit->cx = 85;
    lpdit->cy = 10;
    lpdit->id = ID_EDIT_OUTP;
    lpdit->style = WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL;
    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0081;            /* editbox */
    *lpw++ = 0;
    *lpw++ = 0;

    GlobalUnlock(hgbl);
    ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl, NULL,
                            (DLGPROC) dialog_main);
    GlobalFree(hgbl);
    return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1