/*
 | TSSIM.C
 |
 | Standard driver for simulation graphics.
 |
 | Copyright (c) Siemens AG 1993.
 | All rights reserved.
 |
 | $Header:   P:/VCS/TSEX/TSSIM.C_V   1.1   10 Dec 1993 16:45:50   ror  $
 */

#pragma warning (disable:4001)
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <fpl.h>
#include <ts.h>
#include "tssim.h"

// Public Data.
//
HWND hWndGraphic=NULL;
HWND hWndFrame=NULL;
HWND hWndMDIClient=NULL;
HINSTANCE hInst;

// Prototypes.
//
LRESULT SimGraphic_API(PWINDATA pWinData, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK SimGraphic_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL SimGraphic_OnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);
VOID SimGraphic_OnNCDestroy(PWINDATA pWinData);
VOID SimGraphic_MDIActivate(PWINDATA pWinData, BOOL fActive, HWND hwndActivate, HWND hwndDeactivate);
VOID SimGraphic_OnSize(PWINDATA pWinData, UINT state, int cx, int cy);
BOOL SimGraphic_OnEraseBkGnd(PWINDATA pWinData, HDC hDC);

// Library Main Entry Point.
//
int FAR PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
{
    WNDCLASS wndclass;

    NOTUSED(wDataSeg);
    NOTUSED(lpszCmdLine);

    if (wHeapSize > 0)
	UnlockData (0);

    hInst = hInstance;

    wndclass.lpszClassName = (LPSTR) CLASS;
    wndclass.lpfnWndProc   = (WNDPROC) SimGraphic_WndProc;
    wndclass.hIcon	   = NULL;
    wndclass.hCursor	   = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = NULL;
    wndclass.style	   = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = sizeof (LOCALHANDLE);
    wndclass.hInstance	   = hInstance;
    wndclass.lpszMenuName  = NULL;

    RegisterClass (&wndclass);

    return 1;
}

// Standard WEP routine for DLL cleanup.
//
int FAR PASCAL WEP(int nParam)
{
    if (hWndGraphic)
	SendMessage (hWndGraphic, WM_CLOSE, 0, 0L);

    NOTUSED(nParam);

    return 1;
}

// Handle all API messages for this window.
//
LRESULT SimGraphic_API(PWINDATA pWinData, UINT msg, WPARAM wParam, LPARAM lParam)
{
    NOTUSED(lParam);
    NOTUSED(wParam);
    NOTUSED(pWinData);

    if (!hWndGraphic)
	return 0L;

    switch (msg)
    {
    case TSM_FILEOPENED:
    case TSM_OK:
    case TSM_CLOSE:
    case TSM_CANCEL:
	SendMessage (pWinData->hWnd, WM_CLOSE, 0, 0L);
	break;

    case TSM_GETCLASS:
	return -1L;

    case TSM_UPDATE:
	InvalidateRect (hWndGraphic, NULL, TRUE);
	UpdateWindow (hWndGraphic);
	break;
    }

    return 0L;
}

// Window callback routine.
//
LRESULT CALLBACK SimGraphic_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PWINDATA pWinData;

    // Get a pointer to the local data for this window.
    //
    pWinData = (PWINDATA) GetWinMem (hWnd);

    // Let the API handler process WM_USER+xxxx messages.
    //
    if (msg > WM_USER)
	return SimGraphic_API (pWinData, msg, wParam, lParam);

    // Process Windows messages.
    //
    switch (msg)
    {
    HANDLE_MSG(hWnd,	 WM_NCCREATE,	 SimGraphic_OnNCCreate);
    HANDLE_MSG(pWinData, WM_NCDESTROY,	 SimGraphic_OnNCDestroy);
    HANDLE_MSG(pWinData, WM_PAINT,	 SimGraphic_OnPaint);
    HANDLE_MSG(pWinData, WM_SIZE,	 SimGraphic_OnSize);
    HANDLE_MSG(pWinData, WM_ERASEBKGND,  SimGraphic_OnEraseBkGnd);
    HANDLE_MSG(pWinData, WM_MDIACTIVATE, SimGraphic_MDIActivate);

    default: return DefMDIChildProc (hWnd, msg, wParam, lParam);
    }
}

// Allocate memory for window.
//
BOOL SimGraphic_OnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
{
    LPARAM lParam;
    PWINDATA pWinData;

    // Reconstruct the original lParam from the message cracker.
    //
    lParam = (LPARAM) lpCreateStruct;

    // If no memory blow out with 0L, this causes CreateWindow to fail.
    //
    pWinData = (PWINDATA) LocalAlloc (LPTR, sizeof (WINDATA));
    if (pWinData == NULL)
	return FALSE;

    // Associate with window.
    //
    SetWinMem (hwnd, pWinData);

    // Initialize the pWinData structure.
    //
    pWinData->hWnd = hwnd;
    SimGraphic_InitWindowData (pWinData);

    return TRUE;
}

// This window has been activated, load its menu.
//
VOID SimGraphic_MDIActivate(PWINDATA pWinData, BOOL fActive, HWND hwndActivate, HWND hwndDeactivate)
{
    if (hWndFrame)
	SendMessage (hWndFrame, TSM_SIMSETMENU, (WPARAM) fActive, MAKELPARAM(hwndActivate, hwndDeactivate));

    FORWARD_WM_MDIACTIVATE(pWinData->hWnd, fActive, hwndActivate, hwndDeactivate, DefMDIChildProc);
}

// Free memory allocated for this window.  Deallocation of any
// fields in the window structure should be done here.
//
VOID SimGraphic_OnNCDestroy(PWINDATA pWinData)
{
    if (pWinData)
    {
	SetWinMem (pWinData->hWnd, NULL);
	LocalFree ((HLOCAL) pWinData);
    }

    hWndGraphic = NULL;
}

// Resize the window.
//
VOID SimGraphic_OnSize(PWINDATA pWinData, UINT state, int cx, int cy)
{
    InvalidateRect (pWinData->hWnd, NULL, TRUE);
    UpdateWindow (pWinData->hWnd);

    FORWARD_WM_SIZE(pWinData->hWnd, state, cx, cy, DefMDIChildProc);
}

// Paint the bkgnd white.
//
BOOL SimGraphic_OnEraseBkGnd(PWINDATA pWinData, HDC hDC)
{
    RECT r;

    GetClientRect (pWinData->hWnd, &r);
    FillRect (hDC, &r, GetStockObject (WHITE_BRUSH));

    return TRUE;
}
