#pragma once
#include "base_head.h"
#include "th.h"
#include "garray.h"
//clase generica de transmision de datos por socket--------------
/*
la idea de esta clase es que para transmitir datos se usaran 2 socket, uno de envio/recepcion del socket y otro para llenar/vaciar bufferes
*/

class DataTransfer;
//thread de socket-------
class UTILES_EXPORT ThSockDataTransfer: public Cth
{
	int ibuf;
	void runSend();
	void runReceive();

	virtual void run();
public:
	DataTransfer *data;

};

//thread de buffer-------
class UTILES_EXPORT ThBufDataTransfer: public Cth
{
	
	
	int ibuf;
	virtual void run();
	void runFill();
	void runClear();
public:
	DataTransfer *data;

};
#define VERSION_HEAD_DATA_TRANSFER 100
typedef struct Head_DataTransfer
{
	int version;			//version informacion de usuaros
	__int64 nb_total;		//numero de bytes totales de los datos
	__int64 nb_ini;			//numero de usuarios en archivo
}Head_DataTransfer;

class Csock_cl;
class UTILES_EXPORT DataTransfer
{
	friend class ThBufDataTransfer;
	friend class ThSockDataTransfer;
	
	__int64 nb_total;//numero de bytes totales de los datos
	__int64 nb_ini;//byte inicial desde el cual se empieza a transmitir / guardar
	Cgarray<char> buf;//buffer
	Cgarray<int> nb_buf;//indica el numero de bites cargados en el buffer iesimo

	Csock_cl* sc;//puntero a socket
	IdataTransfer*dt;

	int total_p;//total de partes en las que se dividen los datos
	int sc_p;//partes recopiladas por th de socket
	int dt_p;//partes recopiladas por th de bufer
	int n_buf;//numero de bufferes
	int sizeBuf;//tamaņo de cada buffer
	int mode;
	
	int errorSoc;
	int errorDat;

	bool cancela;
	bool mal;
	double porcen;
	ThSockDataTransfer thsoc;
	ThBufDataTransfer thbuf;
public:
	enum ModeDataTransfer{
		MODE_RECEIVE,//modo recepcion
		MODE_SEND//modo transmision
	};

	DataTransfer(void);
	~DataTransfer(void);

	//funciones de configuracion
	bool setData(Csock_cl* soc, IdataTransfer*datat);
	bool setMode(int mode, int nbbuf = (1024*50),int nbuf=2);//configura el modo y cuantos buffer y de cuantos bytes son cada uno
	
	bool start();

	double getStatus();
	bool isCanceled();
	bool currando();
	void cancel();
	void join();
	
};
