gt: 				throw new IllegalArgumentException();
context: /*
   *  Freeplane - mind map editor
   *  Copyright (C) 2008 Dimitry Polivaev
   *
   *  This file author is Dimitry Polivaev
   *
   *  This program is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 2 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package org.freeplane.features.filter.condition;
  
  import java.util.Date;
  
  
  import org.freeplane.core.io.xml.TreeXmlWriter;
  import org.freeplane.core.resources.ResourceController;
  import org.freeplane.core.util.TextUtils;
  import org.freeplane.core.util.TypeReference;
  import org.freeplane.features.filter.ExactStringMatchingStrategy;
  import org.freeplane.features.filter.StringMatchingStrategy;
  import org.freeplane.features.format.FormattedDate;
  import org.freeplane.features.format.FormattedNumber;
  import org.freeplane.features.format.IFormattedObject;
  import org.freeplane.n3.nanoxml.XMLElement;
  
  /**
   * Adapter for Conditions which compare values (</<=/>/>=/=/!=)
   * 
   * @author ?
   *
   */
  abstract public class CompareConditionAdapter extends ASelectableCondition {
  	public static final String OBJECT = "OBJECT";
  	public static final String MATCH_CASE = "MATCH_CASE";
  	public static final String MATCH_APPROXIMATELY = "MATCH_APPROXIMATELY";
  	public static final String VALUE = "VALUE";
  	private Comparable<?> conditionValue;
  	final private boolean matchCase;
  	final protected boolean matchApproximately;
  	final StringMatchingStrategy stringMatchingStrategy;
  	private int comparisonResult;
  	private boolean error;
  	
  	abstract public boolean isEqualityCondition();
  
  	@SuppressWarnings("deprecation")
  	protected CompareConditionAdapter(final Object value, final boolean matchCase, final boolean matchApproximately) {
  		super();
  		this.matchCase = matchCase;
  		this.matchApproximately = matchApproximately;
  		stringMatchingStrategy = matchApproximately ? StringMatchingStrategy.DEFAULT_APPROXIMATE_STRING_MATCHING_STRATEGY :
  			new ExactStringMatchingStrategy();
  		final ResourceController resourceController = ResourceController.getResourceController();
  		if(value instanceof String && resourceController.getBooleanProperty("compare_as_number") && TextUtils.isNumber((String) value)) {
  			Number number = TextUtils.toNumber((String) value);
  			if(number instanceof Comparable<?>){
  				conditionValue = (Comparable<?>) number;
  			}
  			return;
  		}
  		if(value instanceof FormattedNumber){
  		    conditionValue = (FormattedNumber)value;
  		    return;
  		}
  		    
  		if(value instanceof FormattedDate){
  			final FormattedDate date = (FormattedDate) value;
  			if(date.containsTime() || 
  					date.getHours() == 0 && date.getMinutes() == 0 && date.getSeconds() == 0) {
  				conditionValue = date;
              }
              else{
                  final Date reducedDate = new Date(date.getYear(), date.getMonth(), date.getDate());
  	 	            conditionValue = new FormattedDate(reducedDate.getTime(), date.getDateFormat());
  			}
  			return;
  		}
  		conditionValue = value.toString();
  		
  	}
  
  	protected CompareConditionAdapter(final Double value) {
  		super();
  		this.matchCase = false;
  		this.matchApproximately = false;
  		conditionValue = value;
  		stringMatchingStrategy = matchApproximately ? StringMatchingStrategy.DEFAULT_APPROXIMATE_STRING_MATCHING_STRATEGY :
  			new ExactStringMatchingStrategy();
  	}
  
  	protected CompareConditionAdapter(final Long value) {
  		super();
  		this.matchCase = false;
  		this.matchApproximately = false;
  		conditionValue = value;
  		stringMatchingStrategy = matchApproximately ? StringMatchingStrategy.DEFAULT_APPROXIMATE_STRING_MATCHING_STRATEGY :
  			new ExactStringMatchingStrategy();
  	}
  
  	@Override
  	public void fillXML(final XMLElement child) {
  		super.fillXML(child);
  		if(conditionValue instanceof IFormattedObject){
  			child.setAttribute(OBJECT, TypeReference.toSpec(conditionValue));
  		}
  		else
  			child.setAttribute(CompareConditionAdapter.VALUE, conditionValue.toString());
  		child.setAttribute(CompareConditionAdapter.MATCH_CASE, TreeXmlWriter.BooleanToXml(matchCase));
  		child.setAttribute(CompareConditionAdapter.MATCH_APPROXIMATELY, TreeXmlWriter.BooleanToXml(matchApproximately));
  	}
  
  	protected void compareTo(final Object transformedContent) throws NumberFormatException {
  		error = false;
  		comparisonResult = Integer.signum(compareToData(transformedContent));
  	}
  
  	private int compareToData(final Object transformedContent) {
  	    if (conditionValue instanceof FormattedNumber && transformedContent instanceof Number){
  	        return -((FormattedNumber)conditionValue).compareTo((Number)transformedContent);
  	    }
  		if (conditionValue instanceof Number && transformedContent instanceof String) {
  			try {
  				Number number = TextUtils.toNumber((String)transformedContent); 
  		        if (conditionValue instanceof FormattedNumber){
  		            return -((FormattedNumber)conditionValue).compareTo(number);
  		        }
  				if(number instanceof Long)
  					return compareTo((Long)number);
  				if(number instanceof Double)
  					return compareTo((Double)number);
  			}
  			catch (final NumberFormatException fne) {
  			};
  			error = true;
  			return 0;
  		}
  		if (conditionValue instanceof FormattedDate) {
  			if (transformedContent instanceof FormattedDate) {
  				return compareTo((FormattedDate)transformedContent);
  			}
  			error = true;
  			return 0;
  		}
  		
  		final String valueAsString = conditionValue.toString();
  		final String text = transformedContent.toString();
  		if (isEqualityCondition())
  		{
  			return stringMatchingStrategy.matches(valueAsString, text, false, matchCase) ? 0 : -1;
  		}
  		else
  		{
  			return matchCase ? text.compareTo(valueAsString) : text.compareToIgnoreCase(valueAsString);
  		}
      }
  
  	protected int getComparisonResult() {
      	return comparisonResult;
      }
  
  	protected boolean isComparisonOK() {
      	return ! error;
      }
  
  	private int compareTo(final Double value) {
  	    return value.compareTo(((Number) conditionValue).doubleValue());
      }
  
  	protected int compareTo(final Long value) {
  	    return value.compareTo((Long) conditionValue);
      }
  
  	@SuppressWarnings("deprecation")
      private int compareTo(final Date value) {
  		if (((FormattedDate) conditionValue).containsTime() || (value.getHours() == 0 && value.getMinutes() == 0 && value.getSeconds() == 0))
  			return value.compareTo((Date) conditionValue);
  		return new Date(value.getYear(), value.getMonth(), value.getDate()).compareTo((Date) conditionValue);
  	}
  
  	public String createDescription(final String attribute, final int comparationResult, final boolean succeed) {
  		String simpleCondition;
  		switch (comparationResult) {
  			case -1:
  				simpleCondition = succeed ? ConditionFactory.FILTER_LT : ConditionFactory.FILTER_GE;
  				break;
  			case 0:
  				simpleCondition = TextUtils.getText(succeed ? ConditionFactory.FILTER_IS_EQUAL_TO
  				        : ConditionFactory.FILTER_IS_NOT_EQUAL_TO);
  				break;
  			case 1:
  				simpleCondition = succeed ? ConditionFactory.FILTER_GT : ConditionFactory.FILTER_LE;
  				break;
  			default:
  