#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <time.h>

// Die folgenden 4 defines müssen völlig mit dem Datenauswerter übereinstimmen
#define CHANNELMAX           16       // Anzahl Outputkanäle
#define SIZEOFDATACHUNK      74       // Anzahl Bytes die pro Messung übermittelt wird
// Achtung: Sender muß Packete genau der Größe SZRECEIVEQUEUE = SZTRANSMITQUEUE liefern
#define SZRECEIVEQUEUE       74       // Größe der Empfangsqueue für serielle Übertragung
#define SZTRANSMITQUEUE      74       // Größe der Sendequeue für serielle Übertragung

// Timer-IDs
#define T_ID_EXPERIMENT       1       // Timer, der die Iteration im Experiment steuert
#define T_ID_STRIPCHARTTIMING 2       // Timer für die Stripcharts zur Inputdatenkontrolle

// Gemessene Eigenschaften der Fahrstandshardware

// Vorauberechnetes Inkrement des HeadingAngle pro Winkelgrad Lenkradeinschlag nach 1 Meter
// const double METER_EFFECT_OF_1_DEGREE = 0.023054886;
const double METER_EFFECT_OF_1_DEGREE = 0.011;
const double HEADING_EFFECT_OF_1_DEGREE = 0.005;  // Untertrieben, sonst wär´s unbeherrschbar
const double NUM_PIX_MAKING_5CENTIMETERS = 10.;   // durch Ausprobieren
const double TACHONORMIERUNG = 30.;               // Übertreibt etwas, wie ein richtiger Tachometer
const double STANDGAS = 10.;                      // 10 Prozent
const double DREHSTANDSOUND = 2000.;              // Artifizielle Drehzahl nur bei Standgas (zwecks Geräusch)

// Ende gemessene Eigenschaften der Fahrstandshardware

// Regressionsmodell-Gewichte Lookuptable Slots
enum {CONST=0,W_GAS,W_BREMS}; // Gas, Bremse, Geschwindigkeit 110 msec später

// Namen zur Unterscheidung der Analogmeßgerätefenster
enum {
  ANA_LENKRAD_FILM = 0,
  ANA_LENKRAD_VP   = 1,
  ANA_GAS_FILM     = 2,
  ANA_GAS_VP       = 3,
  ANA_BREMSE_FILM  = 4,
  ANA_BREMSE_VP    = 5,
  ANA_V_FILM       = 6,
  ANA_V_VP         = 7,
  ANA_HEADING_FILM = 8,
  ANA_HEADING_VP   = 9,
  ANA_VAR_TRACK    = 10,
  ANA_MIRROR_POS   = 11
};

typedef double WINKEL;

typedef struct TIMEONLY_tag {                      // These are in packed BCD format
   BYTE bcdSt;                                     // Hours
   BYTE bcdMi;                                     // Minutes
   BYTE bcdSe;                                     // Seconds
   BYTE bcdFr;                                     // Frames
} TIMEONLY;

typedef struct TIMEANDUSER_tag {
   BYTE bcdSt;                                     // Hours
   BYTE bcdMi;                                     // Minutes
   BYTE bcdSe;                                     // Seconds
   BYTE bcdFr;                                     // Frames
   BYTE us1_2;                                     // user nibbles 1/2
   BYTE us3_4;                                     // user nibbles 3/4
   BYTE us5_6;                                     // user nibbles 5/6
   BYTE us7_8;                                     // user nibbles 7/8
} TIMEANDUSER;


typedef struct INTFORMTC_tag {
   int intSt;                                      // Hours
   int intMi;                                      // Minutes
   int intSe;                                      // Seconds
   int intFr;                                      // Frames
} INTFORMTC;

typedef enum STEERSEG_tag {
   LEFTSEG,
   RIGHTSEG
} STEERSEG;

#define pred(v)     ((v)-1)
#define PI2TIMES    6.283185307   // 2 Pi mit hinreichender Genauigkeit
#define ELAPSETIME  110           // Timer-Zeit im Experiment, muß Vielfaches von 55 sein

#define IDM_PREPARE                    1050        // Menu "Vorbereitung"
#define IDM_EINSTELLUNGEN              1100

#define IDM_START                      1200        // Menu "Versuch"
#define IDM_RUNEXP                     1250
#define IDM_EXIT                       1300

#define IDM_SUCHE                      3000        // Menu "Suche"
#define IDM_S_BANDSTELLEANFAHREN       3150

#define IDM_STRIPCHARTS                5000        // Menu "Stripcharts"
#define IDM_S_KANAL0                   5050        // "Lenkrad"
#define IDM_S_KANAL1                   5100        // "Gaspedal"
#define IDM_S_KANAL2                   5150        // "Bremspedal"
#define IDM_S_HBT                      5151        // "Hupe-Blinker-Tempomat"
#define IDM_S_LGB                      5152        // "Lenkung-Gas_Bremse"
#define IDM_S_ALLES                    5350        // "Alles"
#define IDM_S_ENDCHARTS                4400
#define IDM_R_STEUERUNGA               7050
#define IDM_HELPSTUFF                  8000
#define IDM_H_HANDBUCH                 8050
#define IDM_H_INFO                     8100

#define IDM_DOSETUP                    9401        // Künstliches IDM

#define WM_BLACKPAINT                  (WM_USER+1) // Sent to main WndProc

// Dialog Box Elements

#define su_band_txt1                   100
#define su_band_txt2                   101
#define su_edit                        102

#define the_icon                       103
#define info_txt1                      104
#define info_txt2                      105
#define info_txt3                      106
#define steff                          107

#define butStandByOn                   108
#define butStandByOff                  109
#define butStop                        110
#define butPlay                        111
#define butEject                       112
#define butFF                          113
#define butRew                         114
#define butPreroll                     115
#define grVarSpeeds                    116

#define PROTOCOL                       501
#define SEND_IDEALLENK                 502
#define SEND_LENK                      503
#define SEND_IDEALSPEED                504
#define SEND_PSEUDOSPEED               505
#define SEND_GAS                       506
#define SEND_BREMS                     507
#define SEND_MIRRANGLE                 508
#define SEND_CURPOS                    509
#define SEND_VIDEOTC                   510
#define SEND_REALTIME                  511
#define SEND_HUPE                      512
#define SEND_BLILINKS                  513
#define SEND_BLIRECHTS                 514
#define SEND_TEMPOMAT                  515
#define SEND_DREHZAHL                  516
#define RUNTACHO                       517
#define RUNCURSOR                      518
#define RUNMIRROR                      519
#define SERIALOPTION                   520
#define SENDSERIAL                     521
#define OPTIONS                        522
#define NOISE_FREQU_EDI                523
#define NOISE_AMPLITUDE_EDI            524
#define NOISE_FREQ_TXT                 525
#define NOISE_AMPLITUDE_TXT            526
#define NOISE                          527
#define RUNTIME                        528
#define RUN_BEGIN_TXT                  529
#define RUN_BEGIN_EDI                  530
#define RUN_END_TXT                    531
#define RUN_END_EDI                    532
#define BUTT_GET_INTERVAL              533
#define BUTT_SET_INTERVAL              534
#define NAMES                          535
#define NAMES_TXT                      536
#define NAMES_EDI                      537
#define PARAMETERS                     538
#define PARAMETERS_TXT1                539
#define PARAMETERS_TXT2                540
#define PARAMETERS_TXT3                541
#define PARAMETERS_EDI1                542
#define PARAMETERS_EDI2                543
#define PARAMETERS_EDI3                544
#define ID_DEFAULTS                    545
#define ID_LOADSETTINGS                546
#define ID_SAVESETTINGS                547


char szString[128];   // variable to load resource strings
char szAppName[20];   // class name for the window
HWND hInst;
HWND hWndMain;
STEERSEG currentSeg;  // Segment (0-360 Grad-Scheibe)
int lastLW;

void cwCenter(HWND, int);

// Aliases to introduce new win 3.1 terminology
#define UINT      WORD
#define HINSTANCE HANDLE
#define LPCSTR    LPSTR
#define LPARAM    LONG
#define CALLBACK  FAR PASCAL
#define WPARAM    WORD
#define WINAPI    FAR PASCAL

// Error message Strings
#define IDS_ERR_CREATE_WINDOW            1
#define IDS_ERR_REGISTER_CLASS           2
#define IDS_ERR_COM_IE_BADID             3
#define IDS_ERR_COM_IE_BAUDRATE          4
#define IDS_ERR_COM_IE_BYTESIZE          5
#define IDS_ERR_COM_IE_DEFAULT           6
#define IDS_ERR_COM_IE_HARDWARE          7
#define IDS_ERR_COM_IE_MEMORY            8
#define IDS_ERR_COM_IE_NOPEN             9
#define IDS_ERR_COM_IE_OPEN              10
#define IDS_ERR_COM_GETCOMMSTATE         11
#define IDS_ERR_COM_SETCOMMSTATE         12
#define IDS_ERR_COM_UNKNOWN              13
#define IDS_ERR_CE_RXOVER                14
#define IDS_ERR_CE_OVERRUN               15
#define IDS_ERR_CE_RXPARITY              16
#define IDS_ERR_CE_FRAME                 17
#define IDS_ERR_CE_BREAK                 18
#define IDS_ERR_CE_CTSTO                 19
#define IDS_ERR_CE_DSRTO                 20
#define IDS_ERR_CE_RLSDTO                21
#define IDS_ERR_CE_TXFULL                22
#define IDS_ERR_CE_PTO                   23
#define IDS_ERR_CE_IOE                   24
#define IDS_ERR_CE_DNS                   25
#define IDS_ERR_CE_OOP                   26
#define IDS_ERR_CE_MODE                  27
#define IDS_ERR_READCOMMSZFAILURE        28
#define IDS_COMPORTNOTSETUP              29
#define IDS_NUMWRITTENMISMATCH           30
#define IDS_MONITORSTARTRECORDINGERR     31
#define IDS_MONITORENDRECORDINGERR       32

DWORD WINAPI timeGetTime(void); // Aus mmsystem.h

// Common Functions
LONG FAR PASCAL WndProc(HWND, WORD, WORD, LONG);
LONG FAR PASCAL TheExpWndProc(HWND, WORD, WORD, LONG);
LONG FAR PASCAL StripWndProc(HWND, WORD, WORD, LONG);
BOOL FAR PASCAL SU_BANDMsgProc(HWND, WORD, WORD, LONG);
BOOL FAR PASCAL RECORDERMsgProc(HWND, WORD, WORD, LONG);
BOOL FAR PASCAL INFOMsgProc(HWND, WORD, WORD, LONG);
BOOL FAR PASCAL ConfigureMsgProc(HWND hWndDlg,WORD Message,WORD wParam,LONG lParam);
BOOL FAR PASCAL IsEscapeCondition(void);
int FAR PASCAL ItsTheEnd(TIMEONLY *tc);
int FAR PASCAL GetTC(TIMEANDUSER *tu);
BOOL FAR PASCAL SetupCommunicationEDV(LPSTR comName);
void FAR  PASCAL ShutDownCommunicationEDV(void);
void FAR PASCAL InternalErrorBox(int ID);
int FAR PASCAL GetErrIDS4OpenComm(int ErrCode);
void FAR PASCAL ExplainCommError(int errCode);
void FAR PASCAL CommunicationErrorBox(int ID);
void FAR PASCAL IntParts(int value,BYTE *a,BYTE *b);
void FAR PASCAL FloatParts(float value,BYTE *a,BYTE *b,BYTE *c,BYTE *d);
int FAR PASCAL MakeChecksum(BYTE *bufPointer,int sumBytes);
INTFORMTC BCDTC2IntFormatTc(TIMEONLY tc);
long FAR PASCAL VideoSecondsMade(INTFORMTC startWas,INTFORMTC nowIs);
void FAR PASCAL GetSim97ProfileData(void);
void FAR PASCAL WriteSim97ProfileData(void);
void FAR PASCAL DropBeginCode2Buf(char *buf12);
void FAR PASCAL DropEndCode2Buf(char *buf12);
double FAR PASCAL Renorm(double oldVal,double oldMin,double oldMax,double newMin,double newMax);
double FAR PASCAL Range(double value1,double value2);
void FAR PASCAL CreateControlInstruments(HWND *vec10HWNDs,HWND hwndParent,HANDLE hInstance,LPRECT bounding);
int FAR PASCAL RebuildInteger(BYTE low,BYTE high);
int FAR PASCAL RebuildIntegerFromByte(BYTE raw);
int FAR PASCAL LenkBeruhigung(int sollLenkWinkel,double currentSpeed);
int GetIntFromJankerBCD(BYTE hi,BYTE lo);
BYTE getHiNibble(BYTE b);
BYTE getLoNibble(BYTE b);
//int eliminateSegments(int segmentedLW,int straight);

int nCwRegisterClasses(void);
void CwUnRegisterClasses(void);

