/***************************************************************************
 *                                                                         *
 *   WELOGSRV.CPP                                                          *
 *                                                                         *
 *   Copyright (c) 1996-1997 Galacticomm, Inc.    All Rights Reserved.    *
 *                                                                         *
 *   WG Event Log server.                                                  *
 *                                                                         *
 *                                        - I. Minkin 9/10/96              *
 *                                                                         *
 ***************************************************************************/

#include <windows.h>
#include <windowsx.h>
#include "welogdat.h"

#define FILREV "$Revision: 5 $"

// The normal HANDLE_MSG macro in WINDOWSX.H does not work properly for dialog
// boxes because DlgProc's return a BOOL instead of an LRESULT (like
// WndProcs). This HANDLE_DLGMSG macro corrects the problem:
#define HANDLE_DLGMSG(hwnd, message, fn)                      \
     case (message): return(SetDlgMsgResult(hwnd, uMsg,       \
                            HANDLE_##message((hwnd), (wParam), (lParam), (fn))))

#define WMU_ADDTOLIST (WM_APP+100)
// BOOL Cls_OnAddToList(HWND hwnd,CHAR *data)
#define HANDLE_WMU_ADDTOLIST(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd),(CHAR *)(lParam)))

static HWND createWindow();

static BOOL CALLBACK mainDlgProc(HWND  hWndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
static VOID mainDlg_OnClose(HWND hWnd);
static VOID mainDlg_OnSize(HWND hWnd,UINT state,INT cx,INT cy);
static VOID mainDlg_OnPaint(HWND hWnd);
static HICON mainDlg_OnQueryDragIcon(HWND hWnd);
static BOOL mainDlg_OnInitDialog(HWND hWnd,HWND hWndFocus,LPARAM lParam);
static BOOL mainDlg_OnAddToList(HWND hWnd,CHAR *data);
static VOID setLBTabStops(HWND hLBox);

static DWORD WINAPI eLogTh(VOID *pInfo);

HINSTANCE hInst;
HICON hiMain;

struct ELOGTHINFO
{
     HANDLE hevShutDown;
     HANDLE hevReady;
     HWND hMainWin;
};

INT WINAPI
WinMain(
HINSTANCE hInstance,               // handle of current instance
HINSTANCE /*hPrevInstance*/,       // handle of previous instance
LPSTR /*pCmdLine*/,                // pointer to command line
INT /*nCmdShow*/)                  // show state of window
{
     DWORD eLogThId;
     MSG msg;
     ELOGTHINFO eLogInfo;

     HANDLE hevELogRunning=CreateEvent(NULL,TRUE,FALSE,"/EVENT/WGSERVER/WELOGRUNNING");
     if (hevELogRunning == NULL
      || GetLastError() == ERROR_ALREADY_EXISTS) {
          CloseHandle(hevELogRunning);
          return(0);
     }
     hInst=hInstance;
     eLogInfo.hMainWin=createWindow();
     eLogInfo.hevShutDown=CreateEvent(NULL,TRUE,TRUE,NULL);
     eLogInfo.hevReady=CreateEvent(NULL,TRUE,FALSE,NULL);
     HANDLE hELogTh=CreateThread(NULL,0,eLogTh,static_cast<VOID *>(&eLogInfo),
                                 0,&eLogThId);
     WaitForSingleObject(eLogInfo.hevReady,INFINITE);
     CloseHandle(eLogInfo.hevReady);
     SetEvent(hevELogRunning);
     while (GetMessage(&msg, NULL, 0, 0) ) {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
     }
     ResetEvent(eLogInfo.hevShutDown);
     SetThreadPriority(hELogTh,THREAD_PRIORITY_HIGHEST);
     WaitForSingleObject(hELogTh,INFINITE);
     CloseHandle(hELogTh);
     CloseHandle(eLogInfo.hevShutDown);
     CloseHandle(hevELogRunning);
     return(0);
}

HWND
createWindow()
{
     hiMain=LoadIcon(hInst,"MAIN_ICON");
     return(CreateDialog(hInst,"MAIN_DIALOG",NULL,mainDlgProc));
}

static BOOL CALLBACK
mainDlgProc(                       // system status dialog process
HWND hWndDlg,                      //   handle of dialog box
UINT uMsg,                         //   message
WPARAM wParam,                     //   first message parameter
LPARAM lParam)                     //   second message parameter
{
     switch (uMsg) {
          HANDLE_DLGMSG(hWndDlg,WM_CLOSE,mainDlg_OnClose);
          HANDLE_DLGMSG(hWndDlg,WMU_ADDTOLIST,mainDlg_OnAddToList);
          HANDLE_DLGMSG(hWndDlg,WM_INITDIALOG,mainDlg_OnInitDialog);
          HANDLE_DLGMSG(hWndDlg,WM_SIZE,mainDlg_OnSize);
          HANDLE_DLGMSG(hWndDlg,WM_PAINT,mainDlg_OnPaint);
          HANDLE_DLGMSG(hWndDlg,WM_QUERYDRAGICON,mainDlg_OnQueryDragIcon);
          case WM_ERASEBKGND:
               if (IsIconic(hWndDlg)) {
                    SendMessage(hWndDlg,WM_ICONERASEBKGND,wParam,0L);
                    return TRUE;
               }
               else {
                    return(FALSE);
               }
          default:
               return(FALSE);
     }
}

static BOOL
mainDlg_OnInitDialog(              // handle WM_INITDIALOG
HWND hWnd,
HWND /*hWndFocus*/,
LPARAM /*lParam*/)
{
     RECT rc;

     SendMessage(hWnd,WM_SETICON,1 /*ICON_BIG*/,(LPARAM)hiMain);
     SendMessage(hWnd,WM_SETICON,0 /*ICON_SMALL*/,(LPARAM)hiMain);
     // adjust list box
     GetClientRect(hWnd,&rc);
     HWND hLBox=GetDlgItem(hWnd,101);
     SetWindowPos(hLBox,NULL,5,5,rc.right-10,rc.bottom-10,SWP_NOZORDER);
     setLBTabStops(hLBox);
     // move to the middle of the screen
     GetWindowRect(hWnd,&rc);
     INT dlgCX=rc.right-rc.left;
     INT dlgCY=rc.bottom-rc.top;
     INT dlgX=(GetSystemMetrics(SM_CXSCREEN)-dlgCX)/2;
     INT dlgY=(GetSystemMetrics(SM_CYSCREEN)-dlgCY)/2;
     SetWindowPos(hWnd,NULL,dlgX,dlgY,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_NOREDRAW);
     return(TRUE);
}

static VOID
mainDlg_OnSize(                    // handle WM_SIZE
HWND hWnd,
UINT /*state*/,
INT cx,
INT cy)
{
     SetWindowPos(GetDlgItem(hWnd,101),NULL,5,5,cx-10,cy-10,SWP_NOZORDER);
}

static VOID
mainDlg_OnPaint(                    // handle WM_PAINT
HWND hWnd)
{
     if (IsIconic(hWnd)) {
          PAINTSTRUCT ps;
          HDC hdc=BeginPaint(hWnd,&ps);
          DrawIcon(hdc,0,0,hiMain);
          EndPaint(hWnd,&ps);
     }
     else {
          FORWARD_WM_PAINT(hWnd,DefWindowProc);
     }
}

static HICON
mainDlg_OnQueryDragIcon(
HWND /* hWnd */)
{
     return(hiMain);
}


static VOID
mainDlg_OnClose(                   // handle WM_CLOSE
HWND hWnd)
{
     PostQuitMessage(0);
     DestroyWindow(hWnd);
}

static BOOL
mainDlg_OnAddToList(               // handle WMU_ADDTOLIST
HWND hWnd,
CHAR *data)
{
     HWND hCtrl=GetDlgItem(hWnd,101);
     ListBox_AddString(hCtrl,data);
     return(TRUE);
}

// HACK this function must belong to welogData class
static VOID
setLBTabStops(
HWND hLBox)
{
     HFONT hfCurrent=(HFONT)SendMessage(hLBox,WM_GETFONT,0,0);
     HDC hDC=GetDC(hLBox);
     HFONT hfOld=(HFONT)SelectObject(hDC,hfCurrent);
     INT i;
     CHAR ch;
     CHAR tmpBuf[256];
     for (i=0,ch=' ' ; ch <= 'z' ; ch++,i++) {
          tmpBuf[i]=ch;
     }
     SIZE size;
     GetTextExtentPoint32(hDC,tmpBuf,i,&size);
     LONG dlgBaseUnit=size.cx/i;
     // get longest string for date/time
     SYSTEMTIME st;
     st.wYear=2000;
     st.wMonth=12;
     st.wDayOfWeek=0;
     st.wDay=30;
     st.wHour=12;
     st.wMinute=59;
     st.wSecond=59;
     st.wMilliseconds=0;
     GetDateFormat(LOCALE_SYSTEM_DEFAULT,0,&st,NULL,tmpBuf,sizeof(tmpBuf));
     GetTextExtentPoint32(hDC,tmpBuf,lstrlen(tmpBuf),&size);
     INT tab[2];
     tab[0]=(size.cx*4/dlgBaseUnit)+4;
     GetTimeFormat(LOCALE_SYSTEM_DEFAULT,0,&st,NULL,tmpBuf,sizeof(tmpBuf));
     GetTextExtentPoint32(hDC,tmpBuf,lstrlen(tmpBuf),&size);
     tab[1]=(size.cx*4/dlgBaseUnit)+tab[0]+4;
     SelectObject(hDC,hfOld);
     ReleaseDC(hLBox,hDC);
     SendMessage(hLBox,LB_SETTABSTOPS,(WPARAM)(sizeof(tab)/sizeof(tab[0])),(LPARAM)tab);
}

////////////////////////////////////////////////////////////////////////////////
static DWORD WINAPI
eLogTh(
VOID *pInfo)
{
     welogData wd;
     welogDataMon mon;
     ELOGTHINFO eLogInfo=*(static_cast<ELOGTHINFO *> (pInfo));

     SetEvent(eLogInfo.hevReady);
     while (WaitForSingleObject(eLogInfo.hevShutDown,0) == WAIT_OBJECT_0) {
          if (mon.get(wd,1000)) {
               CHAR buf[1024];
               wd.formatString(buf,sizeof(buf));
               SendMessage(eLogInfo.hMainWin,WMU_ADDTOLIST,0,(LPARAM)buf);
          }
     }
     return(0);
}
