/*
 | QS.C
 |
 | Global public definitions for SieFuzzy
 |
 | Copyright (c) Siemens AG 1993.
 | All rights reserved.
 |
 | $Header:   P:/VCS/TSEX/QCKSTRT/QS.C_V   1.1   10 Dec 1993 17:52:44   ror  $
 */

#include <windows.h>
#include <string.h>
#include <fpl.h>
#include <ts.h>
#include "qs.h"

// Local Data.
//
HINSTANCE hInst;

// Prototypes.
//
VOID EXPORT FAR PASCAL TSUtility(TSUTILITY FAR *lpTSUtility);
BOOL EXPORT CALLBACK TSUtilityDlg(HWND hDlg, int msg, WPARAM wParam, LPARAM lParam);
BOOL TSUtilityAction(OBJHANDLE hObjProject, int iInputs, int iOutputs);
BOOL TSUtilityError(HWND hWnd, HWND hWndFocus, LPSTR lpszError);

// Library main (entry point to the DLL from our perspective)
//
int FAR PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
{
    NOTUSED(wDataSeg);
    NOTUSED(lpszCmdLine);

    hInst = hInstance;

    if (wHeapSize > 0)
	UnlockData (0);

    return 1;
}

// WEP routine for utility.
//
int FAR PASCAL WEP(int nParam)
{
    NOTUSED(nParam);

    return 1;
}

// Entry point for SieFuzzy user defined utility.
//
VOID EXPORT FAR PASCAL TSUtility(TSUTILITY FAR *lpTSUtility)
{
    // Pop-up a dialog for this utility.
    //
    DialogBoxParam (hInst,
		    MAKEINTRESOURCE(IDD_QUICKSTART),
		    lpTSUtility->hWndFrame,
		    (DLGPROC) TSUtilityDlg,
		    (LPARAM) lpTSUtility);
}

// Dialog callback routine for this utility.
//
BOOL EXPORT CALLBACK TSUtilityDlg(HWND hDlg, int msg, WPARAM wParam, LPARAM lParam)
{
    RECT r;
    BOOL fTrans;
    int iInputs;
    int iOutputs;
    OBJHANDLE hObjProject;
    static TSUTILITY FAR *lpTSUtility;

    switch (msg)
    {
    case WM_INITDIALOG:
	// Grab TSUtility structure passed via the create dialog call.
	//
	lpTSUtility = (TSUTILITY FAR *) lParam;

	// Center the dialog on the screen.
	//
	GetWindowRect (hDlg, &r);

	SetWindowPos (hDlg,
		      NULL,
		      (GetSystemMetrics (SM_CXSCREEN) - (r.right  - r.left)) / 2,
		      (GetSystemMetrics (SM_CYSCREEN) - (r.bottom - r.top )) / 2,
		      0,
		      0,
		      SWP_NOSIZE | SWP_NOACTIVATE);

	// Limit the number of characters in the edit controls.
	//
	SendDlgItemMessage (hDlg, IDD_INPUTS,  EM_LIMITTEXT, 1, 0L);
	SendDlgItemMessage (hDlg, IDD_OUTPUTS, EM_LIMITTEXT, 1, 0L);

	// Enter default values.
	//
	SetWindowText (GetDlgItem (hDlg, IDD_INPUTS),  "2");
	SetWindowText (GetDlgItem (hDlg, IDD_OUTPUTS), "1");
	return TRUE;

    case WM_COMMAND:
	switch (wParam)
	{
	case IDOK:
	    // Get the number of inputs.
	    //
	    iInputs = (int) GetDlgItemInt (hDlg, IDD_INPUTS, &fTrans, FALSE);

	    // Put up error if problem.
	    //
	    if (!fTrans || iInputs <= 0)
		return TSUtilityError (lpTSUtility->hWndFrame,
				       GetDlgItem (hDlg, IDD_NAME),
				       "Expected a value between 1 and 9.");

	    // Get the number of outputs.
	    //
	    iOutputs = (int) GetDlgItemInt (hDlg, IDD_OUTPUTS, &fTrans, FALSE);

	    // Put up error if problem.
	    //
	    if (!fTrans || iOutputs <= 0)
		return TSUtilityError (lpTSUtility->hWndFrame,
				       GetDlgItem (hDlg, IDD_NAME),
				       "Expected a value between 1 and 9.");

	    // Attempt to close the currently loaded SieFuzzy project
	    // (prompting the user if it needs saving) and create a new
	    // untitled project.  A valid project handle is returned if
	    // successful, NULL is return otherwise.
	    //
	    TSCloseProject ();

	    hObjProject = TSGetProject ();

	    // Ensure that no project exists.
	    //
	    if (hObjProject != NULL)
	    {
		MessageBox (lpTSUtility->hWndFrame, "SieFuzzy is still active.\n\nTry QuickStart once again.", "QuickStart", MB_ICONHAND | MB_OK | MB_APPLMODAL);
		EndDialog (hDlg, FALSE);
		return TRUE;
	    }

	    hObjProject = TSNewProject ();

	    // If there was a problem, close the dialog and take no action.
	    //
	    if (hObjProject == NULL)
	    {
		MessageBox (lpTSUtility->hWndFrame, "Unable to create new project.", "QuickStart", MB_ICONHAND | MB_OK | MB_APPLMODAL);
		EndDialog (hDlg, FALSE);
		return TRUE;
	    }

	    // Build the user requested project.
	    //
	    if (!TSUtilityAction (hObjProject, iInputs, iOutputs))
	    {
		EndDialog (hDlg, FALSE);
		return TRUE;
	    }

	    TSUpdate ();

	    // Close the dialog.
	    //
	    EndDialog (hDlg, TRUE);
	    return TRUE;

	case IDCANCEL:
	    EndDialog (hDlg, FALSE);
	    return TRUE;
	}
    }

    return FALSE;
}

// Handle utility errors.
//
BOOL TSUtilityError(HWND hWnd, HWND hWndFocus, LPSTR lpszError)
{
    MessageBox (hWnd, lpszError, "QuickTest", MB_ICONHAND | MB_OK | MB_APPLMODAL);

    if (hWndFocus)
    {
	SetFocus (hWndFocus);
	SendMessage (hWndFocus, EM_SETSEL, 0, MAKELONG(0, -1));
    }

    return TRUE;
}


// A dummy var object.
//
static char szInputVar[]= "\
VAR Input0 \
OPTIONS \
ICONPOS=1.0,0.5 \
ICONCOLOR=255 \
GRIDSPACE=0.1,0.2 \
END \
TYPE float  \
MIN -1 \
MAX 1 \
END \
";

// A dummy output var object.
//
static char szOutputVar[]= "\
VAR Output0 \
OPTIONS \
ICONPOS=4.0,0.5 \
ICONCOLOR=16711680 \
GRIDSPACE=0.1,0.2 \
END \
TYPE float  \
MIN -1 \
MAX 1 \
END \
";

// A dummy rulebase object.
//
static char szRulebase[]= "\
RULEBASE Rules \
OPTIONS \
    ICONCOLOR=65535 \
    ICONPOS=2.5,1 \
END \
END \
";

// Build the project with the given number of inputs and outputs.  Returns
// FALSE if errors, returns TRUE iff no errors.
//
BOOL TSUtilityAction(OBJHANDLE hObjProject, int iInputs, int iOutputs)
{
    int i;
    BOOL fBusy;
    char buf[100];
    char szConnect[200];

    // Get the name of the created project.
    //
    FPLGetProjectName (hObjProject, (LPSTR) buf);

    // Create the rulebase.
    //
    if (!FPLAddObject (hObjProject, szRulebase, OBJ_RULEBASE, "", buf, &fBusy) || fBusy)
    {
	TSUtilityError (NULL, NULL, "Cannot create the entire project.");
	return FALSE;
    }

    // Create the input variables.
    //
    for (i=0; i<iInputs; i++)
    {
	szInputVar[9]  = (char) ('0'+(char)i);
	szInputVar[31] = (char) ('0'+(char)i);
	szInputVar[33] = (char) '5';

	if (!FPLAddObject (hObjProject, szInputVar, OBJ_VAR, "", buf, &fBusy) || fBusy)
	{
	    return TSUtilityError (NULL, NULL, "Cannot create the entire project.");
	    return FALSE;
	}

	// Add the connect to the rulebase.
	//
	wsprintf (szConnect, "CONNECT FROM Input%d TO Rules END", i);
	if (!FPLAddObject (hObjProject, (LPSTR) szConnect, OBJ_CONNECT, "", buf, &fBusy) || fBusy)
	{
	    return TSUtilityError (NULL, NULL, "Cannot create the entire project.");
	    return FALSE;
	}
    }

    // Create the output variables.
    //
    for (i=0; i<iOutputs; i++)
    {
	szOutputVar[10] = (char) ('0'+ (char) i);
	szOutputVar[32] = (char) ('0'+(char)i);
	szOutputVar[34] = (char) '5';

	if (!FPLAddObject (hObjProject, szOutputVar, OBJ_VAR, "", buf, &fBusy) || fBusy)
	{
	    return TSUtilityError (NULL, NULL, "Cannot create the entire project.");
	    return FALSE;
	}

	// Add the connect from the rulebase.
	//
	wsprintf (szConnect, "CONNECT FROM Rules TO Output%d END", i);
	if (!FPLAddObject (hObjProject, (LPSTR) szConnect, OBJ_CONNECT, "", buf, &fBusy) || fBusy)
	{
	    return TSUtilityError (NULL, NULL, "Cannot create the entire project.");
	    return FALSE;
	}
    }

    // Return OK status.
    //
    return TRUE;
}
