//---------------------------------------------------------------------------
//#include <stdlib.h>
//#include <conio.h>

//#include <windows.h>
//#include <winbase.h>
#include <string.h>
#include <shlwapi.h>

#include <vcl.h>
#pragma hdrstop
#include "rizeni_rotatoru.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//	Deklarace globálních proměnných
HANDLE COM_handle = NULL;
bool CommFlag;
char InBuffer[101];

#define COM_rep 1

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	(*Form1).ClientWidth = 220;
//	okno je nastartováno se šířkou 220
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
//	tlačítko "odešli azimut"
	(*Timer2).Enabled = false;
	//	zastavení časovače pro periodické čtení azimutu
	char stovky, desitky, jednotky;
	int azimut = 0;
	//	požadovaný azimut

	azimut = (*Edit1).Text.ToInt();
	stovky = azimut / 100;
	azimut -= 100 * stovky;
	desitky = azimut / 10;
	azimut -= 10 * desitky;
	jednotky = azimut;

	stovky += 48;
	jednotky += 48;
	desitky += 48;
	//	úprava na ASCII tvar

	int i;
	for (i = 0; i < COM_rep; i++)
		{
		TransmitCommChar(COM_handle, 'M');
		TransmitCommChar(COM_handle, stovky);
		TransmitCommChar(COM_handle, desitky);
		TransmitCommChar(COM_handle, jednotky);
		//	odešle přes sériový port "Mpožadovaný azimut"
		FlushFileBuffers(COM_handle);
		//	nepodmíněné odvysílání bufferu
		}
	if ((*CheckBox2).State == cbChecked)
	//	pokud je aktivní automatické načítaní azimutu
	(*Timer2).Enabled = true;
	//	zastavení časovače pro periodické čtení azimutu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
//	tlačítko "nastav rychlost"
	(*Timer2).Enabled = false;
	//	zastavení časovače pro periodické čtení azimutu
	char temp[10];
	//	pomocná textová proměnná
	strcpy(temp, (*Edit2).Text.c_str());
	// text Editu2 do temp
	strcat(temp, "%");
	// k temp připoj znak %
	(*Label4).Caption = temp;
	// temp vypiš do Label4
	(*TrackBar1).Position = (*Edit2).Text.ToInt();
	//	uprav pozici TrackBar1 podle Edit2

	int rychlost;
	//	proměnná pro odeslání rychosti
	rychlost = (*Edit2).Text.ToInt() * 255 / 100;
	//	přepočet na tvar registrů uPC
	char stovky = 0, desitky = 0, jednotky = 0;
	//	proměnné pro odeslání
	stovky = rychlost / 100;
	//	počet stovek
	rychlost -= stovky * 100;
	desitky = rychlost / 10;
	//	počet desítek
	rychlost -= desitky * 10;
	jednotky = rychlost;
	//	počet jedniček

	stovky += 48;
	jednotky += 48;
	desitky += 48;
	//	úprava na ASCII tvar

	int i;
	for (i = 0; i < COM_rep; i++)
		{
		TransmitCommChar(COM_handle, 'M');
		TransmitCommChar(COM_handle, 'P');
		//	klíčový znak pro odlišení rychlosti od azimutu
		TransmitCommChar(COM_handle, stovky);
		TransmitCommChar(COM_handle, desitky);
		TransmitCommChar(COM_handle, jednotky);
		//	potvrzení příkazu
		}
	if ((*CheckBox2).State == cbChecked)
	//	pokud je aktivní automatické načítaní azimutu
	(*Timer2).Enabled = true;
	//	zastavení časovače pro periodické čtení azimutu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
//	tlačítko "načti azimut"
	(*Timer2).Enabled = false;
	//	zastavení časovače pro periodické čtení azimutu
	TransmitCommChar(COM_handle, 'C');
	//	odešle přes sériový port znak 'C' - žádost o aktuální azimut
	FlushFileBuffers(COM_handle);
	//	nepodmíněné odvysílání bufferu

	(*Timer1).Enabled = true;
	//	zapne prodlevu na odpoveď řídícího modulu rotátoru
	if ((*CheckBox2).State == cbChecked)
	//	pokud je aktivní automatické načítaní azimutu
	(*Timer2).Enabled = true;
	//	zastavení časovače pro periodické čtení azimutu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
//	tlačítko menu
	static bool sw = true;
	sw = !sw;
	//	proměnná určující přechod mezi menu oknem a oknem nastvaneí

	if (sw)
		{
		(*Form1).Caption = "Řízení rotátoru";
		(*Button4).Caption = "Nastavení";
		(*Form1).ClientWidth = 220;
		//	režim Řízení rotátoru
		}
	else
		{
		(*Form1).Caption = "Řízení rotátoru + nastavení";
		(*Button4).Caption = "méně";
		(*Form1).ClientWidth = 440;
		//	režim Řízení rotátoru + Nastavení
		}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)
{
//	počet zpráv o azimutu do minuty
	if (((*Edit3).Text.ToInt() >= 1) & ((*Edit3).Text.ToInt() <= 60))
		{
		(*Edit3).Color = clWindow;
		(*Timer2).Interval = 60000 / (*Edit3).Text.ToInt();
		//	nastavení periody časovače 2 od 100ms do 60s
		(*Button5).Enabled = false;
		//	vypnutí tlačítka
		}
	else
		(*Edit3).Color = clRed;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button6Click(TObject *Sender)
{
//	tlačítko "otáčej vlevo"
	(*Timer2).Enabled = false;
	//	zastavení časovače pro periodické čtení azimutu
	int i;
	for (i = 0; i < COM_rep; i++)
		{
		TransmitCommChar(COM_handle, 'L');
		//	odešle přes sériový port znaky 'L' - žádost o spuštění otáčení vlevo
		FlushFileBuffers(COM_handle);
		//	nepodmíněné odvysílání bufferu
		}

if ((*CheckBox1).State == cbChecked)
		{
		(*Timer3).Enabled = true;
		//	mikroposuv aktivní! - generuje se prodleva pro odvysílání STOP příkazu
		(*Button6).Enabled = false;
		(*Button8).Enabled = false;
		//	deaktivace tlačítek
		}
	else
		{
		(*Timer3).Enabled = false;
		//	mikroposuv neaktivní, nebude požadováno vysílání zastavovacího příkazu
		//	generování prodlevy a odvysílání příkazu STOP
		}
	if ((*CheckBox2).State == cbChecked)
	//	pokud je aktivní automatické načítaní azimutu
	(*Timer2).Enabled = true;
	//	zastavení časovače pro periodické čtení azimutu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{
//	tlačítko "STOP"
	(*Timer2).Enabled = false;
	//	zastavení časovače pro periodické čtení azimutu
	int i;
	for (i = 0; i < COM_rep; i++)
		{
		TransmitCommChar(COM_handle, 'S');
		//	odešle přes sériový port znaky 'S' - žádost o zastavení rotátoru
		FlushFileBuffers(COM_handle);
		//	nepodmíněné odvysílání bufferu
		}

	(*Button6).Enabled = true;
	(*Button8).Enabled = true;
	//	aktivace tlačítek směru - odeznění pulzu mikroposuvu

	(*Timer3).Enabled = false;
	//	deaktivace časovače - příkaz STOP byl odeslán tlačítkem STOP
	if ((*CheckBox2).State == cbChecked)
	//	pokud je aktivní automatické načítaní azimutu
	(*Timer2).Enabled = true;
	//	zastavení časovače pro periodické čtení azimutu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button8Click(TObject *Sender)
{
//	tlačítko "otáčej vpravo"
	(*Timer2).Enabled = false;
	//	zastavení časovače pro periodické čtení azimutu
	int i;
	for (i = 0; i < COM_rep; i++)
		{
		TransmitCommChar(COM_handle, 'R');
		//	odešle přes sériový port znaky 'R' - žádost o spuštění otáčení vpravo
		FlushFileBuffers(COM_handle);
		//	nepodmíněné odvysílání bufferu
		}

if ((*CheckBox1).State == cbChecked)
		{
		(*Timer3).Enabled = true;
		//	mikroposuv aktivní! - generuje se prodleva pro odvysílání STOP příkazu
		(*Button6).Enabled = false;
		(*Button8).Enabled = false;
		//	deaktivace tlačítek
		}
	else
		{
		(*Timer3).Enabled = false;
		//	mikroposuv neaktivní, nebude požadováno vysílání zastavovacího příkazu
		//	generování prodlevy a odvysílání příkazu STOP
		}
	if ((*CheckBox2).State == cbChecked)
	//	pokud je aktivní automatické načítaní azimutu
	(*Timer2).Enabled = true;
   	//	zastavení časovače pro periodické čtení azimutu
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button9Click(TObject *Sender)
{
//	tlačítko "otevři port"
	DCB dcbCommPort;
	BOOL bPort;
	COMMTIMEOUTS CommTimeouts;
	DWORD BytesRead;

/*	Otevření portu pomocí funkce WIN32 API CreateFile,
	CreateFile vrátí HANDLE COM_handle
	non-overlapped serial I/O.	*/
	//"COM4"
	char com_port[10];
	strcpy(com_port, "COM");
	strcat(com_port, IntToStr((*ComboBox1).ItemIndex + 1).c_str());
	COM_handle = CreateFile(com_port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);


//	Pokud by se port nedal otevřít

	if (COM_handle == INVALID_HANDLE_VALUE)
		{

		}

/* Načti aktuální DCB parametry	*/

	dcbCommPort.DCBlength = sizeof(DCB);
	GetCommState(COM_handle, &dcbCommPort);

/* 	Pomocí funkce WIN32 API BuildCommDCB nachystej konfiguraci portu.	*/

	if(!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcbCommPort))
		{
		COM_handle = NULL;
		}

/*	Pomocí funkce WIN32 API SetCommState uplatni aktuální konfiguraci
	portu z DCB. Pokud by se nedala uplatnit, zavři port.	*/

	if(!SetCommState(COM_handle, &dcbCommPort))
		{
		CloseHandle(COM_handle);
		COM_handle = NULL;
		}

/*	Nachystej CommTimeouts parametry.	*/

	CommTimeouts.ReadIntervalTimeout = MAXDWORD;
	CommTimeouts.ReadTotalTimeoutConstant = 0;
	CommTimeouts.ReadTotalTimeoutMultiplier = 0;
	CommTimeouts.WriteTotalTimeoutConstant = 250;
	CommTimeouts.WriteTotalTimeoutMultiplier = 1;


/* 	Pomocí funkce WIN32 API SetCommTimeouts uplatni aktuální konfiguraci
	z BCD. Pokud se to nepodaří, zavři port.	*/

	if(!SetCommTimeouts(COM_handle, &CommTimeouts))
		{
		CloseHandle(COM_handle);
		COM_handle = NULL;
		}

	while(CommFlag)
	{
		Application->ProcessMessages();
		ReadFile(COM_handle, InBuffer, 100, &BytesRead, NULL);
		if(BytesRead)
			{
			InBuffer[BytesRead] = 0;
			}
	}
	Application->ProcessMessages();	//přerušení od ostatních zdrojů
	strcpy(InBuffer, (*Edit1).Text.c_str());
	ReadFile(COM_handle, InBuffer, 100, &BytesRead, NULL);
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button10Click(TObject *Sender)
{
//	nastavení mikroposuvu
	if (((*Edit4).Text.ToInt() >= 200) & ((*Edit4).Text.ToInt() <= 2000))
		{
		(*Edit4).Color = clWindow;
		(*TrackBar2).Position = (*Edit4).Text.ToInt();
		//	nastavení posuvníku délky mikroposuvu podle Editu4
		(*Timer3).Interval = (*Edit4).Text.ToInt();
		//	nastavení intervalu časovače
		(*Button10).Enabled = false;
		//	vypnutí tlačítka
		}
	else
		(*Edit4).Color = clRed;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button11Click(TObject *Sender)
{
//	tlačítko "zavři port"
	//Uzavření COM portu a vynulovaní HANDLE
	CloseHandle(COM_handle);
	COM_handle = NULL;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{
//	posuvník rychlosti
	char temp[10];
	//	pomocná textová proměnná
	strcpy(temp, IntToStr((*TrackBar1).Position).c_str());
	//	do temp se nahraje pozice posuvníku
	strcat(temp, "%");
	//	k temp se přidá znak %
	(*Label4).Caption = temp;
	//	Label4 vypíše aktuální polohu posuvníku
	(*Edit2).Text = IntToStr((*TrackBar1).Position);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrackBar2Change(TObject *Sender)
{
//	posuvník délky mikroposuvu
	(*Timer3).Interval = (*TrackBar2).Position;
	//posuvník do timeru!
	char temp[10];
	//	pomocná textová proměnná
	strcpy(temp, IntToStr((*TrackBar2).Position).c_str());
	//	do temp se nahraje pozice posuvníku
	(*Edit4).Text = temp;
	//	Edit4 vypíše aktuální polohu posuvníku
	(*Button10).Enabled = true;
	//	zapnutí tlačítka
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Edit3Enter(TObject *Sender)
{
//	vstup do editu počtu zpráv o azimutu
	(*Button5).Enabled = true;
	//	zapnutí tlačítka
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Edit4Enter(TObject *Sender)
{
//	vstup do editu délky mikroposuvu
	(*Button10).Enabled = true;
	//	zapnutí tlačítka
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
//	zatržítko mikroposuvu
	;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBox2Click(TObject *Sender)
{
//	zatržítko automatického načítání azimutu
	if ((*CheckBox2).State == cbChecked)
		{
		(*Timer2).Enabled = true;
		//	požadováno automatické načítání azimutu
		}
	else
		{
		(*Timer2).Enabled = false;
		//	není požadováno automatické načítání azimutu
		}
}

//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
/*	časovač pro generovaní prodlevy pro odpověď řídícího modulu
	na žádost o odvysílání aktuálního azimutu */
	(*Timer1).Enabled = false;
//	deaktivace časovače pro manuální reřim odečítání azimutu
	char temp[20];
	char rtemp[20];
	DWORD BytesRead;
	ReadFile(COM_handle, InBuffer, 12, &BytesRead, NULL);
	//	přečte 12 znaky z bufferu sériového portu
	StrCpyN(temp, InBuffer, 12);
	//	12 znaky včetně /NULL
	int i = 0;
	for (i = 0; i <= 2; i++)
		{
		rtemp[i] = temp[i+2];
		}
	rtemp[3] = '°';
	// znak "°"
	rtemp[4] = '\0';
	//	ukončovací znak
	//	ořez znaků "+0aaa0000000"
	(*Label2).Caption = rtemp;
	//	rtemp! výpis do labelu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
//	časovač pro periodické načítání azimutu
	TransmitCommChar(COM_handle, 'C');
	//	odešle přes sériový port znak '?' - žádost o aktuální azimut
	FlushFileBuffers(COM_handle);
	//	nepodmíněné odvysílání bufferu

	(*Timer1).Enabled = true;
	//	zapne prodlevu na odpoveď řídícího modulu rotátoru
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer3Timer(TObject *Sender)
{
//	příkaz STOP
	int i;
	for (i = 0; i < COM_rep; i++)
		{
		TransmitCommChar(COM_handle, 'S');
		//	odešle přes sériový port znaky 'S' - žádost o zastavení rotátoru
		FlushFileBuffers(COM_handle);
		//	nepodmíněné odvysílání bufferu
		}

	(*Timer3).Enabled = false;
	//	zastavení časovače

	(*Button6).Enabled = true;
	(*Button8).Enabled = true;
	//	aktivace tlačítek směru - odeznění pulzu mikroposuvu
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
//	Žádost o uzavření okna
	//Uzavření COM portu a vynulovaní HANDLE
	CloseHandle(COM_handle);
	COM_handle = NULL;
}
//---------------------------------------------------------------------------

