using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Diagnostics;

namespace TradeBlotter.Helper
{
  public class FilterEvaluator<T> where T : IConvertible, IComparable
  {
    public enum Expression { Equal, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual, Invalid };
    private T value;
    private bool isValid = false;
    private Expression expression = Expression.Invalid;
    private String defaultExpression;
    private bool isEnabled = false;
    private bool debugMode = false;
    private String filterName;

    public FilterEvaluator(String filterName,String filterExpression)
    {
      this.filterName = filterName;
      defaultExpression = filterExpression;
      SetExpression(filterExpression);
    }
    public bool IsEnabled
    {
      get { return isEnabled; }
      set { isEnabled = value; }
    }
    public bool DebugMode
    {
      get { return debugMode; }
      set { debugMode = value; }
    }
    public void UseDefault()
    {
      SetExpression(defaultExpression);
    }
    public bool SetExpression(String filterExpression)
    {
      try
      {
        if (filterExpression == null)
        {
          isValid = false;
          return false; 
        }
        if (filterExpression.StartsWith("<="))
        {
          expression = Expression.LessThanOrEqual;
          value = (T)Convert.ChangeType(filterExpression.Substring(2), typeof(T));
        }
        else if (filterExpression.StartsWith(">="))
        {
          expression = Expression.GreaterThanOrEqual;
          value = (T)Convert.ChangeType(filterExpression.Substring(2), typeof(T));
        }
        else if (filterExpression.StartsWith("="))
        {
          expression = Expression.Equal;
          value = (T)Convert.ChangeType(filterExpression.Substring(1), typeof(T));
        }
        else if (filterExpression.StartsWith("<"))
        {
          expression = Expression.LessThan;
          value = (T)Convert.ChangeType(filterExpression.Substring(1), typeof(T));
        }
        else if (filterExpression.StartsWith(">"))
        {
          expression = Expression.GreaterThan;
          value = (T)Convert.ChangeType(filterExpression.Substring(1), typeof(T));
        }
        else
        {
          expression = Expression.Equal;
          value = (T)Convert.ChangeType(filterExpression, typeof(T));
        }
        isValid = true;
        return true;
      }
      catch (Exception)
      {
        isValid = false;
        return false;
      }
    }
    public bool IsValid
    {
      get { return isValid; }
    }
    public bool Evaluate(T value)
    {
      if (!IsValid ||!IsEnabled) return true;
      switch (expression)
      {
        case Expression.Equal:
          if (debugMode) Debug.WriteLine(value.ToString() + "==" + this.value + ":" + value.Equals(this.value).ToString());
          return value.Equals(this.value);
        case Expression.LessThan:
          if (debugMode) Debug.WriteLine(value.ToString() + "<" + this.value + ":" + (value.CompareTo(this.value)<0).ToString());
          return value.CompareTo(this.value) < 0 ? true : false;
        case Expression.GreaterThan:
          if (debugMode) Debug.WriteLine(value.ToString() + ">" + this.value + ":" + (value.CompareTo(this.value)>0).ToString());
          return value.CompareTo(this.value) > 0 ? true : false;
        case Expression.LessThanOrEqual:
          if (debugMode) Debug.WriteLine(value.ToString() + "<=" + this.value + ":" + (value.CompareTo(this.value)<=0).ToString());
          return value.CompareTo(this.value) <= 0 ? true : false;
        case Expression.GreaterThanOrEqual:
          if (debugMode) Debug.WriteLine(value.ToString() + ">=" + this.value + ":" + (value.CompareTo(this.value)>=0).ToString());
          return value.CompareTo(this.value) >= 0 ? true : false;
        default:
          return false;
      }
    }
  }
}
