package dr.evomodelxml;

import dr.xml.*;
import dr.evolution.datatype.Microsatellite;
import dr.evomodel.substmodel.*;
import dr.inference.model.Parameter;

import java.util.logging.Logger;

/**
 * @author Chieh-Hsi Wu
 * Date: 5/06/2009
 *
 * Parser for Asymmetric Quadratic Model
 */
public class AsymQuadModelParser extends AbstractXMLObjectParser{

    public static final String EXPANSION_CONSTANT = "ExpansionConstant";
    public static final String CONTRACTION_CONSTANT = "ContractionConstant";
    public static final String EXPANSION_LIN = "ExpansionLinear";
    public static final String CONTRACTION_LIN = "ContractionLinear";
    public static final String EXPANSION_QUAD = "ExpansionQuad";
    public static final String CONTRACTION_QUAD = "ContractionQuad";

    public String getParserName() {
        return "ASYMQUADModel";
    }
        

    //AbstractXMLObjectParser implementation
    public Object parseXMLObject(XMLObject xo) throws XMLParseException {
        
        Microsatellite microsatellite = (Microsatellite) xo.getChild(Microsatellite.class);

        Parameter expanConst = processModelParameter(xo, EXPANSION_CONSTANT);

        Parameter expanLin = processModelParameter(xo, EXPANSION_LIN);

        Parameter expanQuad = processModelParameter(xo, EXPANSION_QUAD);


        Parameter contractConst = processModelParameter(xo, CONTRACTION_CONSTANT);

        Parameter contractLin = processModelParameter(xo, CONTRACTION_LIN);

        Parameter contractQuad = processModelParameter(xo, CONTRACTION_QUAD);

        //get FrequencyModel
        FrequencyModel freqModel = null;
        if(xo.hasChildNamed(FrequencyModel.FREQUENCIES)){
            freqModel = (FrequencyModel)xo.getElementFirstChild(FrequencyModel.FREQUENCIES);
        }


        return new AsymmetricQuadraticModel(microsatellite, freqModel,
                expanConst, expanLin, expanQuad, contractConst, contractLin, contractQuad);
    }

    private Parameter processModelParameter(XMLObject xo,
                                          String parameterName)throws XMLParseException{
        Parameter param = null;
        if(xo.hasChildNamed(parameterName)){
            XMLObject paramXO = xo.getChild(parameterName);
            param =(Parameter) paramXO.getChild(Parameter.class);
            Logger.getLogger("dr.evoxml").info(
                    "\nUser has specified the parameter: "+ parameterName + " " + param.toString());
        }else{
            Logger.getLogger("dr.evoxml").info(
                    "\nUser has not specified the parameter:"+ parameterName+", default value will be used");
        }
        return param;
    }

    public String getParserDescription() {
        return "This element represents an instance of the stepwise mutation model of microsatellite evolution.";
    }

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

    private XMLSyntaxRule[] rules = new XMLSyntaxRule[]{
        new ElementRule(Microsatellite.class),
        new ElementRule(FrequencyModel.class,true),
        new ElementRule(EXPANSION_CONSTANT,new XMLSyntaxRule[]{new ElementRule(Parameter.class)},true),
        new ElementRule(CONTRACTION_CONSTANT,new XMLSyntaxRule[]{new ElementRule(Parameter.class)},true),
        new ElementRule(EXPANSION_LIN,new XMLSyntaxRule[]{new ElementRule(Parameter.class)},true),
        new ElementRule(CONTRACTION_LIN,new XMLSyntaxRule[]{new ElementRule(Parameter.class)},true),
        new ElementRule(EXPANSION_QUAD,new XMLSyntaxRule[]{new ElementRule(Parameter.class)},true),
        new ElementRule(CONTRACTION_QUAD,new XMLSyntaxRule[]{new ElementRule(Parameter.class)},true)
    };

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

    public static boolean requirePattern(){
        return true;
    }
}



@@ -228,28 +228,8 @@
 Wu%0D%0A
- * Date: 5/06/2009%0D%0A
  *%0D%0A
@@ -769,16 +769,76 @@
 nQuad%22;%0D
+%0A    public static final String IS_SUBMODEL = %22isSubmodel%22;%0D
 %0A%0D%0A    p
@@ -888,17 +888,41 @@
 urn 
-%22
+AsymmetricQuadraticModel.
 ASYMQUAD
 Mode
@@ -921,14 +921,14 @@
 QUAD
-Model%22
+_MODEL
 ;%0D%0A 
@@ -933,24 +933,16 @@
 %0A    %7D%0D%0A
-        
 %0D%0A%0D%0A    
@@ -1058,24 +1058,16 @@
 tion %7B%0D%0A
-        
 %0D%0A      
@@ -1382,26 +1382,24 @@
 N_QUAD);%0D%0A%0D%0A
-%0D%0A
         Para
@@ -1874,171 +1874,397 @@
 %0D%0A%0D%0A
-%0D%0A        return new AsymmetricQuadraticModel(microsatellite, freqModel,%0D%0A                expanConst, expanLin, expanQuad, contractConst, contractLin, contractQuad
+        boolean isSubmodel = xo.getAttribute(IS_SUBMODEL, false);%0D%0A%0D%0A        return new AsymmetricQuadraticModel(%0D%0A                microsatellite,%0D%0A                freqModel,%0D%0A                expanConst,%0D%0A                expanLin,%0D%0A                expanQuad,%0D%0A                contractConst,%0D%0A                contractLin,%0D%0A                contractQuad,%0D%0A                isSubmodel%0D%0A        
 );%0D%0A
@@ -3303,32 +3303,36 @@
 ule%5B%5D%7B%0D%0A        
+    
 new ElementRule(
@@ -3351,24 +3351,28 @@
 te.class),%0D%0A
+    
         new 
@@ -3404,32 +3404,36 @@
 l.class,true),%0D%0A
+    
         new Elem
@@ -3521,32 +3521,36 @@
 true),%0D%0A        
+    
 new ElementRule(
@@ -3632,32 +3632,36 @@
 true),%0D%0A        
+    
 new ElementRule(
@@ -3728,32 +3728,36 @@
 class)%7D,true),%0D%0A
+    
         new Elem
@@ -3842,32 +3842,36 @@
 true),%0D%0A        
+    
 new ElementRule(
@@ -3947,32 +3947,36 @@
 true),%0D%0A        
+    
 new ElementRule(
@@ -4051,16 +4051,77 @@
 )%7D,true)
+,%0D%0A            AttributeRule.newBooleanRule(IS_SUBMODEL,true)
 %0D%0A    %7D;
@@ -4292,14 +4292,12 @@
     %7D%0D%0A%7D%0D%0A%0D%0A
-%0D%0A

change to suit the new AymmetricQuadraticModel contructor.