<?php
/**
 * Created by PhpStorm.
 * User: muntashir
 * Date: 9/28/17
 * Time: 10:26 PM
 */

namespace PHPPhylogeneticTrees;
/**
 * Class NJCluster
 *
 * Neighbour clusters or trees, built by the neighbour joining algorithm
 *
 * @package PHPPhylogeneticTrees
 */
class NJCluster extends Cluster {
    /** @var int|null Length of edges to the children, if any */
    protected $d_left, $d_right;

    function __construct($lab, $d_mat, NJCluster $left = null, $dleft = null, NJCluster $right = null, $dright = null) { // Leaves = single sequences // $dmat = []
        $this->lab    = is_array($lab) ? array_sum($lab) : $lab;
        $this->label  = $lab;
        $this->d_matrix = $d_mat;
        $this->left   = $left;
        $this->d_left = $dleft;
        $this->right  = $right;
        $this->d_right= $dright;
        $this->card   = ($left === null) ? 1 : $left->card + $right->card;
    }

    public function getNewick($labels) {
	return "(". $this->scanForNewick($labels). ");";
    }
    public function scanForNewick($labels) {
	$left = "";
	if(is_array($this->left->label)) {
		$left .= "(". $this->left->scanForNewick($labels). ")";
	} else {
		 $left .= $labels[$this->left->label - 1];
	}
//	$left .= ":". $this->d_left;
	$left .= ":". $this->precisionNumDigit($this->d_left, 6);

	$rignt = "";
	if(is_array($this->right->label)) {
		$rignt .= "(". $this->right->scanForNewick($labels). ")";
	} else {
		$rignt .= $labels[$this->right->label - 1];
	}
//	$rignt .= ":". $this->d_right;
	$rignt .= ":". $this->precisionNumDigit($this->d_right, 6);

	return $left. ",". $rignt;
//	return ($this->d_left < $this->d_right) ? $left. ",". $rignt : $rignt. ",". $left;
//	return ($this->d_left < $this->d_right) ? $rignt. ",". $left : $left. ",". $rignt;
    }
    private function precisionNumDigit($num, $prec) {
	if($num == 0) return "0";	// exactly, "$num===0.0"

	$convNumStr = "";
	if($num > 1) {
		$convNumStr = sprintf("%.". ($prec - 1). "f", $num);
	} else {
		$numStr = sprintf("%.15f", $num);
		$numLen = strlen($numStr);
		$essDisitStart = false;
		$essDigitCount = 0;
		$convNumStr = "";
		for($i=0; $i<$numLen; $i++) {
			$digitStr = $numStr[$i];
			if(!$essDisitStart && $digitStr !== "0" && $digitStr !== ".") $essDisitStart = true;
			$convNumStr .= $digitStr; 
			if($essDisitStart) {
				$essDigitCount++;
				if($essDigitCount >= $prec) break;
			}
		}
	}
	return preg_replace('/0+$/', '', $convNumStr);
    }
}
