import toytree

"""
Explanation: Issue 32: add_sisters has strange behavior
I added the 'split' option to add_sister to allow adding a subtree as sister to another subtree. I think this is beyond the original goal of the function which was to add single tips sister to other single tips. To add a subtree to a subtree we need to create a new node, and thus we want to also be able to set the .dist of this node. Examples shown.
End of explanation
"""


# only using add_child to build a clade
anc = toytree.TreeNode.TreeNode(name="Anc")
anc.add_child(name="A")
anc.add_child(name="B")
print(anc)

# same as above using add_sister
anc = toytree.TreeNode.TreeNode(name="Anc")
anc.add_child(name="A")
anc.children[0].add_sister(name="B")
print(anc)

# but, adding a sister to a clade just creates polytomies...
anc = toytree.TreeNode.TreeNode(name="Anc")
anc.add_child(name="A")
anc.children[0].add_sister(name="B")
anc.children[0].add_sister(name="C")
print(anc)

# similarly adding a clade as sister to a clade does the same
anc1 = toytree.TreeNode.TreeNode(name="Anc1")
anc1.add_child(name="A")
anc1.children[0].add_sister(name="B")

anc2 = toytree.TreeNode.TreeNode(name="Anc2")
anc2.add_child(name="C")
anc2.children[0].add_sister(name="D")

anc = toytree.TreeNode.TreeNode('Anc')
anc.add_child(anc1)
anc.children[0].add_sister(anc2)

print(anc)

"""
Explanation: 'add_sister' in the context of treenodes
I think this is the intended use of add_sister. I agree the behavior is weird when adding a subtree instead of a single tip.
End of explanation
"""


# a subtree
new = toytree.tree(newick="(A:2,B:1):1;")
new.draw(ts='s', use_edge_lengths=True);

# create some other tree
tre = toytree.rtree.unittree(ntips=10, treeheight=10, seed=123)
tre.draw(ts='s');

# big tree
tre = toytree.rtree.unittree(ntips=10, treeheight=10, seed=123)

# add subtree to the big tree at node idx 10
node = tre.idx_dict[10]
node.add_sister(sister=new.treenode, name="X", dist=5);

# update toytree object for new node (always do this after mod'ing treenode structure)
tre._coords.update()

# draw new tree, hover to see node idx and names; it names node 12 'X'
tre.draw(ts='s', height=400, node_hover=True, use_edge_lengths=True);

"""
Explanation: Example with toytree
End of explanation
"""


# places new node (idx=14) at midpoint of split edge; names it 'newnode', node idx 12 is named "X"
tre = toytree.rtree.unittree(ntips=10, treeheight=10, seed=123)
tre.idx_dict[10].add_sister(sister=new.treenode, name="X", dist=None, split=True)
tre._coords.update()
tre.draw(ts='s', height=400, node_hover=True, use_edge_lengths=True);

# or, set newnode dist and split node dist explicitly
tre = toytree.rtree.unittree(ntips=10, treeheight=10, seed=123)
tre.idx_dict[10].add_sister(sister=new.treenode, name="X", dist=1.5, split=1.5)
tre._coords.update()
tre.draw(ts='s', height=400, node_hover=True, use_edge_lengths=True);

"""
Explanation: Using the 'split' argument instead to append clades sister to clades
End of explanation
"""


tre.get_mrca_idx_from_tip_labels(["A", "B"])

tre.get_mrca_idx_from_tip_labels(["r0", "r1"])

tre.get_mrca_idx_from_tip_labels(["r0", "r1", "A", "B"])

"""
Explanation: Get mrca returns the proper node idx
End of explanation
"""


