/* ____________________________________________*/

function TreeMatrix2TreeString (doLengths)
{
	treeString = "";
	p = 0;
	k = 0;
	m = treeNodes[0][1];
	n = treeNodes[0][0];
	d = treeString*(Rows(treeNodes)*25);

	while (m)
	{	
		if (m>p)
		{
			if (p)
			{
				d = treeString*",";
			}
			for (j=p;j<m;j=j+1)
			{
				d = treeString*"(";
			}
		}
		else
		{
			if (m<p)
			{
				for (j=m;j<p;j=j+1)
				{
					d = treeString*")";
				}
			}	
			else
			{
				d = treeString*",";
			}	
		}
		if (n<_NUMBER_OF_SEQUENCES)
		{
			GetString (nodeName, INFERENCE_DATA_SET, n);
			d = treeString*nodeName;
		}
		if (doLengths>.5)
		{
			nodeName = ":"+treeNodes[k][2];
			d = treeString*nodeName;
		}
		k=k+1;
		p=m;
		n=treeNodes[k][0];
		m=treeNodes[k][1];
	}

	for (j=m;j<p;j=j+1)
	{
		d = treeString*")";
	}
	
	d=treeString*0;
	return treeString;
}

/* ____________________________________________*/


DataSetFilter filteredData = CreateFilter (INFERENCE_DATA_SET,1,"","");

ChoiceList (methodIndex,"Negative Branch Lengths",1,SKIP_NONE,
			"Keep Negative","Negative Branch Lengths are Allowed.",
			"Force Zero","Negative Branch Lengths are Forced to 0.");			

if (methodIndex < 0)
{
	return 0;
}


distanceMatrix = {_NUMBER_OF_SEQUENCES,_NUMBER_OF_SEQUENCES};

DISTANCE_PROMPTS		= 1;
ExecuteAFile			(HYPHY_LIB_DIRECTORY+"TemplateBatchFiles"+DIRECTORY_SEPARATOR+"chooseDistanceFormula.def");
InitializeDistances		(0);
DISTANCE_PROMPTS		= 0;

for (i = 0; i<_NUMBER_OF_SEQUENCES; i=i+1)
{
	for (j = i+1; j<_NUMBER_OF_SEQUENCES; j = j+1)
	{
		distanceMatrix[i][j] = ComputeDistanceFormula (i,j);
	}
}

MESSAGE_LOGGING 		 	= 1;
cladesMade 					= 1;


if (_NUMBER_OF_SEQUENCES == 2)
{
	d1 = distanceMatrix[0][1]/2;
	treeNodes = {{0,1,d1__},
				 {1,1,d1__},
				 {2,0,0}};
				 
	cladesInfo = {{2,0}};
}
else
{
	if (_NUMBER_OF_SEQUENCES == 3)
	{
		d1 = (distanceMatrix[0][1]+distanceMatrix[0][2]-distanceMatrix[1][2])/2;
		d2 = (distanceMatrix[0][1]-distanceMatrix[0][2]+distanceMatrix[1][2])/2;
		d3 = (distanceMatrix[1][2]+distanceMatrix[0][2]-distanceMatrix[0][1])/2;
		treeNodes = {{0,1,d1__},
					 {1,1,d2__},
					 {2,1,d3__}
					 {3,0,0}};
					 
		cladesInfo = {{3,0}};		
	}
	else
	{	
		njm = (distanceMatrix > methodIndex)>=_NUMBER_OF_SEQUENCES;
			
		treeNodes 		= {2*(_NUMBER_OF_SEQUENCES+1),3};
		cladesInfo	    = {_NUMBER_OF_SEQUENCES-1,2};
		
		for (i=Rows(treeNodes)-1; i>=0; i=i-1)
		{
			treeNodes[i][0] = njm[i][0];
			treeNodes[i][1] = njm[i][1];
			treeNodes[i][2] = njm[i][2];
		}

		for (i=Rows(cladesInfo)-1; i>=0; i=i-1)
		{
			cladesInfo[i][0] = njm[i][3];
			cladesInfo[i][1] = njm[i][4];
		}
		
		njm = 0;
	}
}

distanceMatrix = 0;

/* now with the treeNodes matrix ready we can convert it into a Newick string */

treeString = TreeMatrix2TreeString (1);
UseModel (USE_NO_MODEL);
Tree Inferred_Tree = treeString; 

_all_sequence_matrix = {_NUMBER_OF_SEQUENCES,1};

for (i=0; i<_NUMBER_OF_SEQUENCES; i=i+1)
{
	_all_sequence_matrix [i][0] = i;
}

SpawnLikelihoodFunction ("_INF_LF_", "Inferred_Tree", INFERENCE_DATA_WINDOW, _all_sequence_matrix);

