/*
 * $Header: /home/gene/library/website/docsrc/sdkskel/src/RCS/demo0001.c,v 395.1 2008/04/20 17:25:51 gene Exp $
 *
 * Copyright (c) 2005 Gene Michael Stover.  All rights reserved.
 *
 * This program 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 of the
 * License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
/*
 * Simple window that prints the current time in a static text.
 */

#include "this.h"

/*
 */
static char *S_moduleName = __FILE__;

/*
 */
static MsgMap *S_map;

/*
 * Window instance data
 */
typedef struct {
  char *magic;
  HWND child_time; /* static text showing time */
  HWND child_count; /* static text showing counter */
  unsigned long count;
} Data;

/*
 */
static Data *
S_GetData (HWND wnd)
{
  Data *x;

  x = (Data *) GetProp (wnd, S_moduleName);
  return x;
}

/*
 */
static LRESULT CALLBACK
S_OnCreate (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LRESULT rc = 0;
  Data *x;

  DefWindowProc (hwnd, uMsg, wParam, lParam);
  x = (Data *) xmalloc (sizeof *x);
  SetProp (hwnd, S_moduleName, x);
  bzero (x, sizeof *x);
  x->child_time = CreateWindow ("STATIC",
                                "time goes here",
                                WS_CHILD | WS_VISIBLE,
                                10, /* x */
                                10, /* y */
                                200, /* width */
                                40, /* height */
                                hwnd, /* parent */
                                NULL, /* menu */
                                CFG_Instance (),
                                NULL); /* lpParam, not used */
  if (x->child_time != NULL) {
    x->child_count = CreateWindow ("STATIC",
                                   "count",
                                   WS_CHILD | WS_VISIBLE,
                                   10, /* x */
                                   10, /* y */
                                   200, /* width */
                                   40, /* height */
                                   hwnd, /* parent */
                                   NULL, /* menu */
                                   CFG_Instance (),
                                   NULL); /* lpParam, not used */
    if (x->child_count != NULL) {
      SetTimer (hwnd, 0, 2997, NULL);
    } else {
      LOG_LastError ("S_OnCreate", __FILE__, __LINE__);
      rc = 3;
    }
  } else {
    LOG_LastError ("S_OnCreate", __FILE__, __LINE__);
    rc = 3;
  }
  return rc;
}

/*
 */
static LRESULT CALLBACK
S_OnDestroy (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  Data *x;

  x = (Data *) GetProp (hwnd, S_moduleName);
  if (x != NULL) {
    SetProp (hwnd, S_moduleName, NULL);
    KillTimer (hwnd, 0);
    x = (Data *) xfree (x);
  }
  PostQuitMessage (0);
  return DefWindowProc (hwnd, uMsg, wParam, lParam);
}

/*
 */
static LRESULT CALLBACK
S_OnSize (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LRESULT rc = 0;
  Data *x;
  RECT rect;
  int height, width;

  x = S_GetData (hwnd);
  if (x != NULL) {
    GetClientRect (hwnd, &rect);
    width= rect.right - rect.left;
    height = (rect.bottom - rect.top) / 2;
    SetWindowPos (x->child_time,
                  NULL,                 /* on top, but we don't care */
                  rect.left,            /* x */
                  rect.top,             /* y */
                  width,
                  height,
                  0);                   /* flags */
    SetWindowPos (x->child_count,
                  NULL,                 /* on top, but we don't care */
                  rect.left,            /* x */
                  rect.top + height,             /* y */
                  width,
                  height,
                  0);                   /* flags */
  }
  rc = DefWindowProc (hwnd, uMsg, wParam, lParam);
  return rc;
}

/*
 */
static LRESULT CALLBACK
S_OnTimer (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  LRESULT rc = 0;
  Data *x;
  time_t tt;
  struct tm stm;
  char str[100];

  rc = DefWindowProc (hwnd, uMsg, wParam, lParam);
  if (rc == 0) {
    x = S_GetData (hwnd);
    if (x != NULL) {
      time (&tt);
      memcpy (&stm, localtime (&tt), sizeof stm);
      strftime (str, 100, "%Y %B %d T %H:%M:%S %Z", &stm);
      SetWindowText (x->child_time, str);
      ++x->count;
      sprintf (str, "%lu", x->count);
      SetWindowText (x->child_count, str);
    }
  }
  return rc;
}

/*
 */
static LRESULT CALLBACK
S_WindowProc (HWND wnd, WindowMessage msg, WPARAM wparam, LPARAM lparam)
{
  return GWP_WindowProc0 (wnd, msg, wparam, lparam, S_map, &DefWindowProc);
}

/*
 */
static int
S_Init (HINSTANCE hInstance)
{
  int rc = 0;
  WNDCLASS wndclass;

  setbuf (stdout, NULL);
  CFG_hInstance = hInstance;
  bzero (&wndclass, sizeof wndclass);
  wndclass.lpfnWndProc = &S_WindowProc;
  wndclass.hInstance = hInstance;
  wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
  wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wndclass.lpszClassName = S_moduleName;
  S_map = MSGMAP_Create ();
  MSGMAP_Insert (WM_CREATE, &S_OnCreate, S_map);
  MSGMAP_Insert (WM_DESTROY, &S_OnDestroy, S_map);
  MSGMAP_Insert (WM_SIZE, &S_OnSize, S_map);
  MSGMAP_Insert (WM_TIMER, &S_OnTimer, S_map);
  if (RegisterClass (&wndclass)) {
    /* good */
  } else {
    printf ("\n%s:%d: RegisterClass failed", __FILE__, __LINE__);
    rc = 44;
  }
  return rc;
}

/*
 */
static HWND
S_CreateWindow (int nShowCmd)
{
  HWND wnd;

  LOG_TraceEntry (__FILE__, __LINE__, "S_CreateWindow");
  wnd = CreateWindow (S_moduleName, /* class name */
                      S_moduleName, /* window name */
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, /* x position */
                      CW_USEDEFAULT, /* y position */
                      CW_USEDEFAULT, /* width */
                      CW_USEDEFAULT, /* height */
                      NULL, /* parent window */
                      NULL, /* menu */
                      CFG_Instance (),
                      NULL); /* not used */
  if (wnd != NULL) {
    LOG_TraceMoo (__FILE__, __LINE__, "S_CreateWindow");
    ShowWindow (wnd, nShowCmd);
  } else {
    LOG_LastError ("CreateWindow", __FILE__, __LINE__);
  }
  LOG_TraceExit (__FILE__, __LINE__, "S_CreateWindow");
  return wnd;
}

/*
 */
static int
S_Loop ()
{
  int rc = 0;
  MSG msg;

  while (rc == 0 && GetMessage (&msg, NULL, 0, 0)) {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
  }
  return rc;
}

/*
 */
static void
S_Uninit ()
{
}

/*
 */
int WINAPI
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, char lpCmdLine[],
         int nShowCmd)
{
  int rc = 0;
  HWND wnd;

  LOG_TraceMoo (__FILE__, __LINE__, "WinMain");
  if (S_Init (hInstance) == 0) {
  LOG_TraceMoo (__FILE__, __LINE__, "WinMain");
    wnd = S_CreateWindow (nShowCmd);
  LOG_TraceMoo (__FILE__, __LINE__, "WinMain");
    if (wnd != NULL) {
  LOG_TraceMoo (__FILE__, __LINE__, "WinMain");
      if (S_Loop () == 0) {
        /* good */
      } else {
        printf ("\n%s:%d: S_Loop failed", __FILE__, __LINE__);
        rc = -11;
      }
    } else {
      printf ("\n%s:%d: S_CreateWindow failed", __FILE__, __LINE__);
      rc = 40;
    }
    S_Uninit ();
  } else {
    printf ("\n%s:%d: S_Init failed", __FILE__, __LINE__);
    rc = 3;
  }
  return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

/* --- end of file --- */
