package dr.inference.model;
import dr.evolution.tree.NodeRef;
import dr.evolution.util.Taxon;
import dr.evomodel.tree.TreeModel;
import dr.xml.*;

/**
 * @author Alexander Fisher
 */
public class MaskFromTree {
    // needs to take in a tip from the tree
    // needs to be 'essentially' a mask parameter
    // can currently work by just auto masking root branch
    // will need access to the tree
    public static final String MASK_FROM_TREE = "maskFromTree";
//    public static final String TREE = "tree";

    public MaskFromTree() {

    }


    // **************************************************************
    // XMLObjectParser
    // **************************************************************

    public static XMLObjectParser PARSER = new AbstractXMLObjectParser() {

        public String getParserName() {
            return MASK_FROM_TREE;
        }

        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

            TreeModel tree = (TreeModel) xo.getChild(TreeModel.class);

            Taxon referenceTaxon = (Taxon) xo.getChild(Taxon.class);


            MaskFromTree maskFromTree = new MaskFromTree();
            return maskFromTree;
        }

        //************************************************************************
        // AbstractXMLObjectParser implementation
        //************************************************************************

        public XMLSyntaxRule[] getSyntaxRules() { return rules; }

        private XMLSyntaxRule[] rules = new XMLSyntaxRule[] {
//                new StringAttributeRule(TRAIT_NAME, "The name to be given to the trait to be simulated"),
//                AttributeRule.newBooleanRule(CLONE),
//                AttributeRule.newDoubleRule(INITIAL_VALUE),
                new ElementRule(TreeModel.class),
                new ElementRule(Taxon.class)
        };

        public String getParserDescription() {
            return "Simulates a trait on a tree";
        }

        public Class getReturnType() { return MaskFromTree.class; }
    };

}

@@ -118,24 +118,76 @@
 .TreeModel;%0A
+import dr.inferencexml.model.MaskedParameterParser;%0A
 import dr.xm
@@ -561,43 +561,941 @@
 e%22;%0A
-%0A    public MaskFromTree() %7B%0A%0A    %7D
+    private TreeModel tree;%0A    private Taxon taxon;%0A    private boolean ancestralMaskBranchKnown = false;%0A    private Parameter mask;%0A%0A    public MaskFromTree(TreeModel tree, Taxon referenceTaxon) %7B%0A        this.tree = tree;%0A        this.taxon = referenceTaxon;%0A        int numBranches = tree.getNodeCount() - 1;%0A        this.mask = new Parameter.Default(numBranches, 1.0);%0A        updateMask();%0A    %7D%0A%0A    Parameter getAncestralMaskBranch() %7B%0A        if (!ancestralMaskBranchKnown) %7B updateMask(); %7D%0A        return (mask);%0A    %7D%0A%0A    void updateMask() %7B%0A       int nodeNumber =  tree.getTaxonIndex(taxon.getId());%0A       NodeRef node = tree.getNode(nodeNumber);%0A       NodeRef root = tree.getRoot();%0A       while(tree.getParent(node) != root)%7B%0A           node = tree.getParent(node);%0A       %7D%0A        int maskIndex = node.getNumber();%0A        mask.setParameterValue(maskIndex, 0.0);%0A        ancestralMaskBranchKnown = true;%0A    %7D%0A%0A
 %0A%0A%0A 
@@ -2098,16 +2098,36 @@
 romTree(
+tree, referenceTaxon
 );%0A     
@@ -2515,233 +2515,8 @@
 %5D %7B%0A
-//                new StringAttributeRule(TRAIT_NAME, %22The name to be given to the trait to be simulated%22),%0A//                AttributeRule.newBooleanRule(CLONE),%0A//                AttributeRule.newDoubleRule(INITIAL_VALUE),%0A
     
@@ -2689,30 +2689,83 @@
 rn %22
-Simulates a trait on a
+Masks ancestral (off-root) branch to a specific reference taxon on a random
  tre

add the key method