#include "parlib.h"
#include "plutils.h"
#include <stdlib.h>


// BExchange list [definition]
// -------------------------------------------------------------------------- //
BExchange* bexch_hlist[MAX_BEXCH_HANDLES];	// list of BExchange handles
int bexch_hmode[MAX_BEXCH_HANDLES];			// Bexchange mode for each handle
int bexch_hptr;								// pointer to available BExchange handle
// -------------------------------------------------------------------------- //

// Transpose list [definition]
// -------------------------------------------------------------------------- //
Transposition* transp_hlist[MAX_TRANSP_HANDLES];	// list of Transpose handles
int transp_hmode[MAX_TRANSP_HANDLES];				// Transpose mode for each handle
int transp_hptr;									// pointer to available Transpose handle
// -------------------------------------------------------------------------- //


// ParLib init-deinit
// -------------------------------------------------------------------------- //
void ParLib_init()
{
	init_plbuf();	// pl-buffers

	bexch_hptr = 0;		// BExchange list
	transp_hptr = 0;	// Transpose list
}

void ParLib_deinit()
{
	int k, exch_mode;

	// BExchange list
	BExchange *bexchange;
	for (k = 0; k < bexch_hptr; k++) {
		get_bexch_handle(&bexchange, &exch_mode, k);

		P_BExchange_opt_free(bexchange, exch_mode);
		free(bexchange);
	}
	bexch_hptr = 0;

	// Transp list
	Transposition *transp;
	for (k = 0; k < transp_hptr; k++) {
		get_transp_handle(&transp, &exch_mode, k);

		P_Transpose_opt_free(transp, exch_mode);
		free(transp);
	}
	transp_hptr = 0;

	deinit_plbuf();	// pl-buffers
}
// -------------------------------------------------------------------------- //


// BExchange handle list interface
// -------------------------------------------------------------------------- //
int save_bexch_handle(BExchange *bexchange, int exch_mode)
{
	// saving handle
	bexch_hlist[bexch_hptr] = bexchange;
	bexch_hmode[bexch_hptr] = exch_mode;
	bexch_hptr++;

	return bexch_hptr - 1;
}

void get_bexch_handle(BExchange** bexchange, int* exch_mode, int exch_id)
{
	*bexchange = bexch_hlist[exch_id];
	*exch_mode = bexch_hmode[exch_id];
}

void remove_bexch_handle(int exch_id)
{
	int k;
	for (k = exch_id; k < bexch_hptr - 1; k++) {
		bexch_hlist[k] = bexch_hlist[k + 1];
		bexch_hmode[k] = bexch_hmode[k + 1];
	}
	if (bexch_hptr > 0) bexch_hptr--;
}
// -------------------------------------------------------------------------- //

// Transposition handle list interface
// -------------------------------------------------------------------------- //
int save_transp_handle(Transposition *transp, int exch_mode)
{
	// saving handle
	transp_hlist[transp_hptr] = transp;
	transp_hmode[transp_hptr] = exch_mode;
	transp_hptr++;

	return transp_hptr - 1;
}

void get_transp_handle(Transposition** transp, int* exch_mode, int exch_id)
{
	*transp = transp_hlist[exch_id];
	*exch_mode = transp_hmode[exch_id];
}

void remove_transp_handle(int exch_id)
{
	int k;
	for (k = exch_id; k < transp_hptr - 1; k++) {
		transp_hlist[k] = transp_hlist[k + 1];
		transp_hmode[k] = transp_hmode[k + 1];
	}
	if (transp_hptr > 0) transp_hptr--;
}
// -------------------------------------------------------------------------- //