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

#include <vcl.h>
#include <winsock.h>
#include <vector>
#pragma hdrstop

#include "sendapp.h"
#include "Unit1.h"
#include "Static.h"
#pragma package(smart_init)

using namespace std;

extern SOCKET socket_udp;
extern sockaddr_in sock_udp_name;

__fastcall sendapp::sendapp(bool CreateSuspended)
	: TThread(CreateSuspended)
{
	FreeOnTerminate = true;
}

// Zjisteni kolik dat je jiz odeslano (pro progressbar) ---------------------
int __fastcall sendapp::GetProgress()
{
	if (velikost != 0) {
		ProgressPosition = (int)((float(tx_pos) / velikost)*100);
	} else ProgressPosition = 0;
	return ProgressPosition;
}

//---------------------------------------------------------------------------
void __fastcall sendapp::UpdateCaption()
{
	Form1->Memo1->Lines->Add(GetTime().TimeString()+"> "+Message);
}

//---------------------------------------------------------------------------
// Funce pro konstrukci a odesilani paketu vlastniho protokolu.
// |operation (8bit)|   flags (8bit)   |    ID (16 bit)        |
// ID je poradove cislo paketu
void send_data(char operation, char flags, char data[], int len)
{
send_packet p;
myUDP *myhdr = new (myUDP);
unsigned char *hdr = (char *)myhdr;

	// Vytvoreni nadstavby UDP paketu
	myhdr->operation = operation;
	myhdr->flags = flags;
	myhdr->id = GLOBAL_ID_TX;
	// prepis do bajtoveho pole
	p.id = myhdr->id;
	p.operation = myhdr->operation;
	p.flags =  myhdr->flags;
	p.len = len + 4;
	p.data[0] = hdr[0];
	p.data[1] = hdr[1];
	p.data[2] = hdr[3];
	p.data[3] = hdr[2];
	// Doplneni o data k odeslani
	int i;
	for (i = 0; i < len; i++) {
		p.data[i+4] = data[i];
	}
	sendto(socket_udp, p.data, p.len, 0, (sockaddr *)&sock_udp_name, sizeof(sock_udp_name));
	if (myhdr->operation == 0xCC) {
	// zapis datoveho paketu do odeslane fronty
		out_queue.push_front(p);
	}
	delete myhdr;
	delete hdr;
};

void __fastcall sendapp::Execute()
{
char databuf[1500];
send_packet packetbuf;
FILE *file_tx;
int lenght;
int i, count, start_time;
bool TXCOMPLETED = false;

	NameThreadForDebugging("sendapp");
	locker->Acquire();
	out_queue.clear();
	locker->Release();
	if (!CONNECTED) {
		Message = "Chyba! Musíte nejprve navázat spojení.";
		Synchronize(&UpdateCaption);
		Terminate();
	}
	// Otevřeni souboru pokud existuje
	if ((file_tx = fopen(Form1->FileListBox1->FileName.t_str(),"rb")) == NULL) {
		Message = "Nepodařilo se otevřít soubor!";
		Synchronize(&UpdateCaption);
		Terminate();
	}
	// Zjisti velikost souboru (omezeno na max 4GB)
	if (!Terminated) {
		fseek(file_tx,0,SEEK_END);
		velikost = ftell(file_tx);
		rewind(file_tx);
		tx_pos = ftell(file_tx);
		Message = "Odesílám soubor " + Form1->FileListBox1->FileName + " ...";
		Synchronize(&UpdateCaption);
	}

	// Vlastní odeslání souboru - ve vlaknu pro čteni se overuje ACK
	count = 0;
	lenght = 1;
	start_time = GetTickCount();

	while ((!TXCOMPLETED) && (!Terminated)) {

		if ((out_queue.size() < OUTBUFFER_SIZE) && (lenght != 0 )) {

			if (lenght != 0) {
				lenght = fread(databuf, sizeof(char),UDP_SIZE-4,file_tx);
				tx_pos = ftell(file_tx);
			}
	   //		locker->Acquire();
			if (lenght != 0) {
				if (((OUTBLOCK_SIZE - 1) == count)||(tx_pos == velikost)) {
					locker->Acquire();
					send_data(0xCC, 1, databuf, lenght);
					locker->Release();
					count = 0;
				} else {
					locker->Acquire();
					send_data(0xCC, 0, databuf, lenght);
					locker->Release();
					count ++;
				}

				locker->Acquire();
				GLOBAL_ID_TX ++;
				locker->Release();
			}

		} else {
			if ((lenght == 0) && (out_queue.empty())) {
				TXCOMPLETED = true;
			}
		}
	}

	// konec
	if (file_tx != NULL) fclose(file_tx);
	if (TXCOMPLETED) {
		int time = GetTickCount() - start_time;
		if (time == 0) { time = 1; }
		int speed = velikost/time;
		Message = "Soubor odeslán za "+IntToStr(time/1000)+"s. Průměrná rychlost "+speed+"kB/s.";
	} else {
		Message = "Nepodařilo se odeslat soubor.";
	}

	Synchronize(&UpdateCaption);
	ProgressPosition = 0;
	Terminate();
}
//---------------------------------------------------------------------------
