#include "../pnheaders/matrix.h"
#include "spnbox.h"

inline static void FreeMatrixSafe(matrix* m)
{
	/*If type is zero, it means the matrix hasn't been allocated.*/
	if (m->type) DeallocateMatrix(m);
}

inline static void FreeMemorySafe(void* m)
{
	/*Don't attempt to free a non-null pointer.*/
	if (m) free(m);
}
	
void DeallocateSupervis(supervis_r *data)
{
	FreeMatrixSafe(&data->Dfm);
	FreeMatrixSafe(&data->Dfp);
	memset(data, 0, sizeof(supervis_r));
}

void DeallocateIpslv(ipslv_r *data)
{
	FreeMemorySafe(data->solution);
	memset(data, 0, sizeof(ipslv_r));
}

void DeallocateIpsolve(ipsolve_r *data)
{
	FreeMemorySafe(data->res);
	memset(data, 0, sizeof(ipsolve_r));
}

void DeallocateIlpadm(ilpadm_r *data)
{
	FreeMatrixSafe(&data->La);
	FreeMatrixSafe(&data->R1);
	FreeMatrixSafe(&data->R2);
	FreeMemorySafe(data->ba);
	FreeMemorySafe(data->dhow);
	memset(data, 0, sizeof(ilpadm));
}

void DeallocateMroadm(mroadm_r* data)
{
	DeallocateIlpadm((ilpadm_r*) data);
}

void DeallocateLinenf(linenf_r *data)
{
	FreeMatrixSafe(&data->Dfm);
	FreeMatrixSafe(&data->Dfp);
	FreeMatrixSafe(&data->Lf);
	FreeMatrixSafe(&data->Cf);
	FreeMemorySafe(data->ms0);
	FreeMemorySafe(data->dhow);
	FreeMemorySafe(data->bf);
	memset(data, 0, sizeof(linenf_r));
}

void DeallocateMsplit(msplit_r *data)
{
	int i;
	if (data->Df.type && data->TDf)
	{
		for (i = 0; i < NumberOfColumns(data->Df); i++)
		{
			FreeMemorySafe(data->TDf[i]);
		}
	}
	FreeMemorySafe(data->TDf);
	FreeMemorySafe(data->iplf);
	FreeMemorySafe(data->TDfCount);
	FreeMatrixSafe(&data->Df);
	FreeMatrixSafe(&data->Dfm);
	FreeMatrixSafe(&data->Dfp);
	FreeMatrixSafe(&data->Mf);
	FreeMatrixSafe(&data->L0f);
	FreeMatrixSafe(&data->Lf);
	memset(data, 0, sizeof(msplit_r));
}

void DeallocateNltrans(nltrans_r *data)
{
	FreeMemorySafe(data->dtr);
	memset(data, 0, sizeof(nltrans_r));
}

void DeallocatePn2acpn(pn2acpn_r *data)
{
	FreeMatrixSafe(&data->Df);
	FreeMatrixSafe(&data->Dmf);
	FreeMatrixSafe(&data->Dpf);
	FreeMatrixSafe(&data->MXF);
	FreeMatrixSafe(&data->L0F);
	FreeMatrixSafe(&data->LF);
	FreeMemorySafe(data->iplf);
	memset(data, 0, sizeof(pn2acpn_r));
}

void DeallocatePn2eacpn(pn2eacpn_r *data)
{
	int i;
	if (data->Df.type && data->TD)
	{
		for (i = 0; i < NumberOfColumns(data->Df); i++)
		{
			FreeMemorySafe(data->TD[i]);
		}
	}
	FreeMemorySafe(data->TD);
	FreeMemorySafe(data->TDCount);
	FreeMemorySafe(data->iplf);
	
	FreeMatrixSafe(&data->Df);
	FreeMatrixSafe(&data->Dmf);
	FreeMatrixSafe(&data->Dpf);
	FreeMatrixSafe(&data->MXF);
	FreeMatrixSafe(&data->L0F);
	FreeMatrixSafe(&data->LF);
	memset(data, 0, sizeof(pn2eacpn_r));
}

void DeallocateChkcons(chkcons_r *data)
{
	FreeMemorySafe(data->res);
	memset(data, 0, sizeof(chkcons_r));
}

void DeallocateReduce(reduce_r *data)
{
	FreeMatrixSafe(&data->Lf);
	FreeMemorySafe(data->Bf);
	FreeMemorySafe(data->indf);
	memset(data, 0, sizeof(reduce_r));
}

void DeallocateActn(actn_r *data)
{
	FreeMatrixSafe(&data->Dma);
	FreeMatrixSafe(&data->Dpa);
	FreeMatrixSafe(&data->Dmra);
	FreeMatrixSafe(&data->Dpra);
	FreeMemorySafe(data->TA);
	memset(data, 0, sizeof(actn_r));
}

void DeallocateTactn(tactn_r *data)
{
	DeallocateActn(data);
}

void DeallocateIssiph(issiph_r *data)
{
	FreeMemorySafe(data->flag);
}

void DeallocateAsiph(asiph_r *data)
{
	FreeMatrixSafe(&data->MS);
	FreeMatrixSafe(&data->NMS);
}

void DeallocateAdmcon(admcon_r *data)
{
	FreeMemorySafe(data->l);
}

void DeallocateDp(dp_r *data)
{
	FreeMatrixSafe(&data->Lf);
	FreeMemorySafe(data->Bf);
	FreeMatrixSafe(&data->L0f);
	FreeMemorySafe(data->B0f);
}
