/*****************************************************************************
 *
 *  UI.c
 *
 *  Copyright (c) 1997 Microsoft Corporation.  All Rights Reserved.
 *
 *  Abstract:
 *
 *      The thing that does UI.
 *
 *****************************************************************************/

#include "msnspa.h"

/*****************************************************************************
 *
 *  Overview:
 *
 *      UI for the app is done on the main thread.  The app itself
 *      is not in the taskbar or in the tray.  The only way to get to
 *      it is to Alt+Tab to it.  When you minimize it, it vanishes again.
 *
 *      FEATURE -- someday create an optional tray icon
 *
 *  Details:
 *
 *          The main window
 *          is just a dialog box.  The window we create is just a
 *          subclassed static control.
 *
 *          By stealing an existing control, we don't need to register
 *          our own bogus class.
 *
 *          We hide from the taskbar by having a hidden owner.
 *
 *          We show up in Alt+Tab because the hidden owner is
 *          not marked WS_EX_TOOLWINDOW.
 *
 *          We vanish on minimization by hiding ourselves, parking
 *          the minimized window "in outer space" so it doesn't bother
 *          the user.  Then re-show it so it can take part in Alt+Tab.
 *
 *****************************************************************************/

/*
 *  These are the co-ordinates of outer space.  Note that we can't base
 *  this on GetSystemMetrics(SM_C[XY]SCREEN) because the user might be
 *  running multiple monitors, and we need to be sure we are outside all
 *  monitors.  So we pick a really absurd value for outer space.
 */
#define XOUTERSPACE         (-32000)
#define YOUTERSPACE         (-32000)

HWND g_hwndMain;
HWND g_hwndDlg;
int g_cMailUsers;
int g_cNewsUsers;

/*****************************************************************************
 *
 *  @func   void | UI_UpdateCounts |
 *
 *          Update the counts of things.
 *
 *****************************************************************************/

void INTERNAL
UI_UpdateCounts(void)
{
    SetDlgItemInt(g_hwndDlg, IDC_MAIL, g_cMailUsers, FALSE);
    SetDlgItemInt(g_hwndDlg, IDC_NEWS, g_cNewsUsers, FALSE);

    EnableWindow(GetDlgItem(g_hwndDlg, IDOK), !(g_cMailUsers | g_cNewsUsers));

}

/*****************************************************************************
 *
 *  @func   BOOL | UI_OnSysCommand |
 *
 *          Munge some commands around.
 *
 *****************************************************************************/

BOOL INTERNAL
UI_OnSysCommand(HWND hdlg, WPARAM wp)
{
    switch (wp & ~0xF) {
    case SC_CLOSE:
        FORWARD_WM_COMMAND(hdlg, IDCANCEL, 0, 0, PostMessage);
        return TRUE;
    }

    return FALSE;
}

/*****************************************************************************
 *
 *  @func   BOOL | UI_OnCommand |
 *
 *          Munge some commands around.
 *
 *****************************************************************************/

BOOL INTERNAL
UI_OnCommand(HWND hdlg, WPARAM wp)
{
    ANIMATIONINFO aniOld, aniNew;

    switch (wp) {
    case IDCANCEL:
        /*
         *  There is no way to minimize a hidden window.
         */

        aniOld.cbSize = sizeof(aniOld);
        SystemParametersInfo(SPI_GETANIMATION, sizeof(aniOld), &aniOld, 0);

        aniNew.cbSize = sizeof(aniNew);
        aniNew.iMinAnimate = 0;
        SystemParametersInfo(SPI_SETANIMATION, sizeof(aniNew), &aniNew, 0);

        ShowWindow(hdlg, SW_MINIMIZE);

        SystemParametersInfo(SPI_SETANIMATION, sizeof(aniOld), &aniOld, 0);

        SetWindowPos(hdlg, HWND_BOTTOM,
                     XOUTERSPACE, YOUTERSPACE, 0, 0,
                     SWP_NOACTIVATE | SWP_NOSIZE | SWP_SHOWWINDOW);
        return TRUE;

    case IDOK:
        FORWARD_WM_CLOSE(hdlg, PostMessage);
        return TRUE;
    }

    return FALSE;
}

/*****************************************************************************
 *
 *  @func   BOOL | UI_OnClose |
 *
 *          Note that various weird conditions can lead to us getting
 *          here while there are active sessions, so re-check before
 *          leaving.
 *
 *****************************************************************************/

void INTERNAL
UI_OnClose(HWND hdlg)
{
    if (IsWindowEnabled(GetDlgItem(hdlg, IDOK))) {
        DestroyWindow(hdlg);
    }
}

/*****************************************************************************
 *
 *  @func   INT_PTR | UI_DlgProc |
 *
 *          Our dialog procedure.
 *
 *****************************************************************************/

INT_PTR CALLBACK
UI_DlgProc(HWND hdlg, UINT wm, WPARAM wp, LPARAM lp)
{
    switch (wm) {
    case WM_SYSCOMMAND:
        return UI_OnSysCommand(hdlg, wp);

    case WM_COMMAND:
        return UI_OnCommand(hdlg, wp);

    case WM_NCPAINT:
        if (IsIconic(hdlg)) {
            return TRUE;
        }
        break;

    case WM_CLOSE:
        UI_OnClose(hdlg);
        return TRUE;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return FALSE;
}

/*****************************************************************************
 *
 *  @func   HWND | UI_Init |
 *
 *          Initialize the UI stuff.
 *
 *  @returns
 *
 *          Nonzero on success.
 *
 *****************************************************************************/

HWND INTERNAL
UI_Init(void)
{
    g_hwndMain = CreateWindow(
        "static",                       /* Class Name */
        "",                             /* Title */
        WS_OVERLAPPEDWINDOW | WS_MINIMIZE,
                                        /* Style (note: not visible) */
        CW_USEDEFAULT, CW_USEDEFAULT,   /* Position */
        CW_USEDEFAULT, CW_USEDEFAULT,   /* Size */
        NULL,                           /* Parent */
        NULL,                           /* Use class menu */
        g_hinst,                        /* Instance */
        0);                             /* No special parameters */

//    SubclassWindow(g_hwndMain, Main_WndProc);

    SendMessage(g_hwndMain, WM_SETICON, ICON_BIG,
                (LPARAM)LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_MAIN)));

    /*
     *  Create the dialog not visible because we're going to be shoving
     *  it around.
     */
    g_hwndDlg = CreateDialog(g_hinst, MAKEINTRESOURCE(IDD_MAIN),
                             g_hwndMain, UI_DlgProc);

    /*
     *  Tell the system that the window should be parked in outer space.
     */
    SetWindowPos(g_hwndDlg, HWND_BOTTOM,
                 XOUTERSPACE, YOUTERSPACE, 0, 0,
                 SWP_NOACTIVATE | SWP_NOSIZE | SWP_SHOWWINDOW);

    return g_hwndDlg;
}

/*****************************************************************************
 *
 *  @func   void | UI_Term |
 *
 *          Clean up the UI stuff.
 *
 *****************************************************************************/

void INTERNAL
UI_Term(void)
{
    DestroyWindow(g_hwndMain);
}