/*
 * If.java
 *
 * Created on March 30, 2001, 11:06 AM
 */

package com.sns.tools.ant.taskdefs;

import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.*;
import java.util.*;

/**
 * IfTask tests a property for a particular relationship to the supplied test
 * data, and if the test passes, it executes one target.  If not, it can be 
 * configured to execute another one.
 *
 *Usage:
 *<pre>
 *  &lt;target name="foo"&gt;
 *      &lt;echo message="You are here."/&gt;
 *  &lt;/target&gt;
 *
 *  &lt;target name="bar"&gt;
 *      &lt;if property="prop" op="=" test="one" target="foo" else="next"/&gt;
 *  &lt;/target&gt;
 *
 *  &lt;target name="next"&gt;
 *      &lt;echo message="No, you are HERE."/&gt;
 *  &lt;/target&gt;
 *</pre>
 *
 *<ul><lt><b>Possible values for the op attribute are currently:</b>
 *<li><code>==</code>
 *<li><code>=</code>
 *<li><code>!=</code>
 *<li><code>&lt;</code><super>**</super>
 *<li><code>&gt;</code><super>**</super>
 *<li><code>&lt;=</code><super>**</super>
 *<li><code>&gt;=</code><super>**</super>
 *</ul>
 *<small><super>**</super>These operators assume the property value and the 
 * test data will both evaluate to doubles.</small>
 *
 * @author  <a href="mailto:John.D.Casey@mail.sprint.com">John Casey</a>
 * @version 1.0
 */
public class IfTask extends Taskdef {
    private String property;
    private String operator;
    private String test;
    private String ifTarget;
    private String elseTarget;
    private boolean caseSense = true;
    
    /**
     * Sets the property whose value you want to test.
     *
     *@param property The property name to test
     */
    public void setProperty(String property){
        this.property = property;
    }
    
    /**
     * Sets the operator to use in the comparison.
     *
     *@param op The operator to use.
     */
    public void setOp(String op){
        this.operator = op;
    }
    
    /**
     * Sets the test data to compare to the property value.
     *
     *@param test The test data.
     */
    public void setTest(String test){
        this.test = test;
    }
    
    /**
     * Sets the target to execute if the test passes.
     *
     *@param target The target name.
     */
    public void setTarget(String target){
        this.ifTarget = target;
    }
    
    /**
     * Sets the target name to execute if the test fails.
     *
     *@param target The target name.
     */
    public void setElse(String target){
        this.elseTarget = target;
    }
    
    /**
     * Sets the flag for whether to make a comparison that takes into account
     * case.  The default is for the match to be case-sensitive.
     *
     *@param caseSense Whether or not to check in a case-sensitive manner.
     */
    public void setCasesense(boolean caseSense){
        this.caseSense = caseSense;
    }
    
    /**
     * Execute the test.
     */
    public void execute() throws BuildException{
        if(property == null){throw new BuildException("property attribute must be set.");}
        if(ifTarget == null){throw new BuildException("target attribute must be set.");}

        String propVal = project.getProperty(property);
        if(propVal == null){propVal = project.getUserProperty(property);}
        
        if(operator == null){throw new BuildException("op attribute must be set.");}
        if((test != null) && (test.equals("null"))){test = null;}
        
        boolean result = false;

        if(propVal == null){
            if(test == null){result = true;}
            else{result = false;}
        }
        else if((operator.equals("=")) || (operator.equals("=="))){
            if((caseSense) && (propVal.equals(test))){result = true;}
            else if((!caseSense) && (propVal.equalsIgnoreCase(test))){result = true;}
            else{result = false;}
        }
        else if(operator.equals("!=")){
            if((caseSense) && (!propVal.equals(test))){result = true;}
            else if((!caseSense) && (!propVal.equalsIgnoreCase(test))){result = true;}
            else{result = false;}
        }
        else if(operator.equals("<")){
            try{
                double d1 = Double.parseDouble(propVal);
                if(test == null){result = false;}
                else{
                    double d2 = Double.parseDouble(test);
                    result = (d1 < d2);
                }
            }
            catch(NumberFormatException nfe){throw new BuildException(nfe);}
        }
        else if(operator.equals(">")){
            try{
                double d1 = Double.parseDouble(propVal);
                if(test == null){result = false;}
                else{
                    double d2 = Double.parseDouble(test);
                    result = (d1 > d2);
                }
            }
            catch(NumberFormatException nfe){throw new BuildException(nfe);}
        }
        else if(operator.equals("<=")){
            try{
                double d1 = Double.parseDouble(propVal);
                if(test == null){result = false;}
                else{
                    double d2 = Double.parseDouble(test);
                    result = (d1 <= d2);
                }
            }
            catch(NumberFormatException nfe){throw new BuildException(nfe);}
        }
        else if(operator.equals(">=")){
            try{
                double d1 = Double.parseDouble(propVal);
                if(test == null){result = false;}
                else{
                    double d2 = Double.parseDouble(test);
                    result = (d1 >= d2);
                }
            }
            catch(NumberFormatException nfe){throw new BuildException(nfe);}
        }
        else{
            throw new BuildException("Invalid operator in if statement!");
        }
        
        if(result){
            project.executeTarget(ifTarget);
        }
        else{
            if(elseTarget != null){project.executeTarget(elseTarget);}
        }
    }
}
