
#define MAX_AUXS	32

class VEXON_REMOTE;
class VEXON_COIND;
class VEXON_COIND_AUX;

struct VEXON_JOB_VALUES
{
	char coinbase[4*1024];
	char merkleroot_be[1024];

	char header[1024];
	char header_be[1024];
	unsigned char header_bin[1024];

	char hash_hex[1024];
	char hash_be[1024];
	unsigned char hash_bin[1024];
};

struct VEXON_JOB_TEMPLATE
{
	int created;
	char flags[64];

	char prevhash_hex[512];
	char prevhash_be[512];

	char extradata_hex[512];
	char extradata_be[512];

	// todo: can use extra field
	char claim_hex[128];
	char claim_be[128];

	int txcount;
	char txmerkles[VEXON_SMALLBUFSIZE];

	vector<string> txsteps;
	vector<string> txdata;

	char version[32];
	char nbits[32];
	char ntime[32];

	int height;
	int target;

	json_int_t value;

	char coinb1[4*1024];
	char coinb2[4*1024];

	char header[256];

	bool has_segwit_txs;

	bool has_filtered_txs;
	int filtered_txs_fee;

	int auxs_size;
	VEXON_COIND_AUX *auxs[MAX_AUXS];
};

#define VEXON_JOB_MAXSUBIDS		200

class VEXON_JOB: public VEXON_OBJECT
{
public:
	bool block_found;
	char name[1024];

	int count;
	double speed;

	double maxspeed;
	double profit;

	VEXON_COIND *coind;			// either one of them
	VEXON_REMOTE *remote;
	VEXON_JOB_TEMPLATE *templ;

	bool remote_subids[VEXON_JOB_MAXSUBIDS];
};

inline void job_delete(VEXON_OBJECT *object)
{
	VEXON_JOB *job = (VEXON_JOB *)object;
	if (!job) return;
	if (job->templ && job->templ->txcount) {
		job->templ->txsteps.clear();
		job->templ->txdata.clear();
	}
	if (job->templ) delete job->templ;
	delete job;
}

/////////////////////////////////////////////////////////////////////////////////////////////

int job_get_jobid();

void job_sort();
void job_relock_clients(int jobid_old, int jobid_new);
void job_unlock_clients(VEXON_JOB *job=NULL);
void job_assign_locked_clients(VEXON_JOB *job);

bool job_can_mine(VEXON_JOB *job);
void job_reset_clients(VEXON_JOB *job=NULL);
bool job_has_free_client();

//VEXON_JOB_TEMPLATE *job_create_template(VEXON_COIND *coind);
//void job_create_last(VEXON_COIND *coind, bool force=false);

/////////////////////////

void job_send_jobid(VEXON_CLIENT *client, int jobid);
void job_send_last(VEXON_CLIENT *client);
void job_broadcast(VEXON_JOB *job);

/////////////////////////

void *job_thread(void *p);
void job_signal();
void job_update();
void job_init();


void coinbase_create(VEXON_COIND *coind, VEXON_JOB_TEMPLATE *templ, json_value *json_result);

vector<string> coind_aux_hashlist(VEXON_COIND_AUX **auxs, int size);
vector<string> coind_aux_merkle_branch(VEXON_COIND_AUX **auxs, int size, int index);
void coind_aux_build_auxs(VEXON_JOB_TEMPLATE *templ);






