﻿/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library 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 Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied. 
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 * 
 * Author					Change						                Date
 * ******************************************************************************
 * Eyal Seagull		Conditional Formatting            2012-04-03
 *******************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using OfficeOpenXml.Utils;
using System.Xml;
using OfficeOpenXml.ConditionalFormatting.Contracts;
using System.Text.RegularExpressions;
using System.Drawing;

namespace OfficeOpenXml.ConditionalFormatting
{
  /// <summary>
  /// Collection of <see cref="ExcelConditionalFormattingRule"/>.
  /// This class is providing the API for EPPlus conditional formatting.
  /// </summary>
  /// <remarks>
  /// <para>
  /// The public methods of this class (Add[...]ConditionalFormatting) will create a ConditionalFormatting/CfRule entry in the worksheet. When this
  /// Conditional Formatting has been created changes to the properties will affect the workbook immediately.
  /// </para>
  /// <para>
  /// Each type of Conditional Formatting Rule has diferente set of properties.
  /// </para>
  /// <code>
  /// // Add a Three Color Scale conditional formatting
  /// var cf = worksheet.ConditionalFormatting.AddThreeColorScale(new ExcelAddress("A1:C10"));
  /// // Set the conditional formatting properties
  /// cf.LowValue.Type = ExcelConditionalFormattingValueObjectType.Min;
  /// cf.LowValue.Color = Color.White;
  /// cf.MiddleValue.Type = ExcelConditionalFormattingValueObjectType.Percent;
  /// cf.MiddleValue.Value = 50;
  /// cf.MiddleValue.Color = Color.Blue;
  /// cf.HighValue.Type = ExcelConditionalFormattingValueObjectType.Max;
  /// cf.HighValue.Color = Color.Black;
  /// </code>
  /// </remarks>
  public class ExcelConditionalFormattingCollection
    : XmlHelper,
    IEnumerable<IExcelConditionalFormattingRule>
  {
    /****************************************************************************************/

    #region Private Properties
    private List<IExcelConditionalFormattingRule> _rules = new List<IExcelConditionalFormattingRule>();
    private ExcelWorksheet _worksheet = null;
    #endregion Private Properties

    /****************************************************************************************/

    #region Constructors
    /// <summary>
    /// Initialize the <see cref="ExcelConditionalFormattingCollection"/>
    /// </summary>
    /// <param name="worksheet"></param>
    internal ExcelConditionalFormattingCollection(
      ExcelWorksheet worksheet)
      : base(
        worksheet.NameSpaceManager,
        worksheet.WorksheetXml.DocumentElement)
    {
      Require.Argument(worksheet).IsNotNull("worksheet");

      _worksheet = worksheet;
      SchemaNodeOrder = _worksheet.SchemaNodeOrder;

      // Look for all the <conditionalFormatting>
      var conditionalFormattingNodes = TopNode.SelectNodes(
        "//" + ExcelConditionalFormattingConstants.Paths.ConditionalFormatting,
        _worksheet.NameSpaceManager);

      // Check if we found at least 1 node
      if ((conditionalFormattingNodes != null)
        && (conditionalFormattingNodes.Count > 0))
      {
        // Foreach <conditionalFormatting>
        foreach (XmlNode conditionalFormattingNode in conditionalFormattingNodes)
        {
          // Check if @sqref attribute exists
          if (conditionalFormattingNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Sqref] == null)
          {
            throw new Exception(
              ExcelConditionalFormattingConstants.Errors.MissingSqrefAttribute);
          }

          // Get the @sqref attribute
          ExcelAddress address = new ExcelAddress(
            conditionalFormattingNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Sqref].Value);

          // Check for all the <cfRules> nodes and load them
          var cfRuleNodes = conditionalFormattingNode.SelectNodes(
            ExcelConditionalFormattingConstants.Paths.CfRule,
            _worksheet.NameSpaceManager);

          // Foreach <cfRule> inside the current <conditionalFormatting>
          foreach (XmlNode cfRuleNode in cfRuleNodes)
          {
            // Check if @type attribute exists
            if (cfRuleNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Type] == null)
            {
              throw new Exception(
                ExcelConditionalFormattingConstants.Errors.MissingTypeAttribute);
            }

            // Check if @priority attribute exists
            if (cfRuleNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Priority] == null)
            {
              throw new Exception(
                ExcelConditionalFormattingConstants.Errors.MissingPriorityAttribute);
            }

            // Get the <cfRule> main attributes
            string typeAttribute = ExcelConditionalFormattingHelper.GetAttributeString(
              cfRuleNode,
              ExcelConditionalFormattingConstants.Attributes.Type);

            int priority = ExcelConditionalFormattingHelper.GetAttributeInt(
              cfRuleNode,
              ExcelConditionalFormattingConstants.Attributes.Priority);

            // Transform the @type attribute to EPPlus Rule Type (slighty diferente)
            var type = ExcelConditionalFormattingRuleType.GetTypeByAttrbiute(
              typeAttribute,
              cfRuleNode,
              _worksheet.NameSpaceManager);

            // Create the Rule according to the correct type, address and priority
            var cfRule = ExcelConditionalFormattingRuleFactory.Create(
              type,
              address,
              priority,
              _worksheet,
              cfRuleNode);

            // Add the new rule to the list
            if(cfRule!=null)
              _rules.Add(cfRule);
          }
        }
      }
    }
    #endregion Constructors

    /****************************************************************************************/

    #region Methods
    /// <summary>
    /// 
    /// </summary>
    private void EnsureRootElementExists()
    {
      // Find the <worksheet> node
      if (_worksheet.WorksheetXml.DocumentElement == null)
      {
        throw new Exception(
          ExcelConditionalFormattingConstants.Errors.MissingWorksheetNode);
      }
    }

    /// <summary>
    /// GetRootNode
    /// </summary>
    /// <returns></returns>
    private XmlNode GetRootNode()
    {
      EnsureRootElementExists();
      return _worksheet.WorksheetXml.DocumentElement;
    }

    /// <summary>
    /// Validates address - not empty (collisions are allowded)
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    private ExcelAddress ValidateAddress(
      ExcelAddress address)
    {
      Require.Argument(address).IsNotNull("address");

      //TODO: Are there any other validation we need to do?
      return address;
    }

    /// <summary>
    /// Get the next priority sequencial number
    /// </summary>
    /// <returns></returns>
    private int GetNextPriority()
    {
      // Consider zero as the last priority when we have no CF rules
      int lastPriority = 0;

      // Search for the last priority
      foreach (var cfRule in _rules)
      {
        if (cfRule.Priority > lastPriority)
        {
          lastPriority = cfRule.Priority;
        }
      }

      // Our next priority is the last plus one
      return lastPriority + 1;
    }
    #endregion Methods

    /****************************************************************************************/

    #region IEnumerable<IExcelConditionalFormatting>
    /// <summary>
    /// Number of validations
    /// </summary>
    public int Count
    {
      get { return _rules.Count; }
    }

    /// <summary>
    /// Index operator, returns by 0-based index
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingRule this[int index]
    {
      get { return _rules[index]; }
      set { _rules[index] = value; }
    }

    /// <summary>
    /// Get the 'cfRule' enumerator
    /// </summary>
    /// <returns></returns>
    IEnumerator<IExcelConditionalFormattingRule> IEnumerable<IExcelConditionalFormattingRule>.GetEnumerator()
    {
      return _rules.GetEnumerator();
    }

    /// <summary>
    /// Get the 'cfRule' enumerator
    /// </summary>
    /// <returns></returns>
    IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
      return _rules.GetEnumerator();
    }

    /// <summary>
    /// Removes all 'cfRule' from the collection and from the XML.
    /// <remarks>
    /// This is the same as removing all the 'conditionalFormatting' nodes.
    /// </remarks>
    /// </summary>
    public void RemoveAll()
    {
      // Look for all the <conditionalFormatting> nodes
      var conditionalFormattingNodes = TopNode.SelectNodes(
        "//" + ExcelConditionalFormattingConstants.Paths.ConditionalFormatting,
        _worksheet.NameSpaceManager);

      // Remove all the <conditionalFormatting> nodes one by one
      foreach (XmlNode conditionalFormattingNode in conditionalFormattingNodes)
      {
        conditionalFormattingNode.ParentNode.RemoveChild(conditionalFormattingNode);
      }

      // Clear the <cfRule> item list
      _rules.Clear();
    }

    /// <summary>
    /// Remove a Conditional Formatting Rule by its object
    /// </summary>
    /// <param name="item"></param>
    public void Remove(
      IExcelConditionalFormattingRule item)
    {
      Require.Argument(item).IsNotNull("item");

      try
      {
        // Point to the parent node
        var oldParentNode = item.Node.ParentNode;

        // Remove the <cfRule> from the old <conditionalFormatting> parent node
        oldParentNode.RemoveChild(item.Node);

        // Check if the old <conditionalFormatting> parent node has <cfRule> node inside it
        if (!oldParentNode.HasChildNodes)
        {
          // Remove the old parent node
          oldParentNode.ParentNode.RemoveChild(oldParentNode);
        }

        _rules.Remove(item);
      }
      catch
      {
        throw new Exception(
          ExcelConditionalFormattingConstants.Errors.InvalidRemoveRuleOperation);
      }
    }

    /// <summary>
    /// Remove a Conditional Formatting Rule by its 0-based index
    /// </summary>
    /// <param name="index"></param>
    public void RemoveAt(
      int index)
    {
      Require.Argument(index).IsInRange(0, this.Count - 1, "index");

      Remove(this[index]);
    }

    /// <summary>
    /// Remove a Conditional Formatting Rule by its priority
    /// </summary>
    /// <param name="priority"></param>
    public void RemoveByPriority(
      int priority)
    {
      try
      {
        Remove(RulesByPriority(priority));
      }
      catch
      {
      }
    }

    /// <summary>
    /// Get a rule by its priority
    /// </summary>
    /// <param name="priority"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingRule RulesByPriority(
      int priority)
    {
      return _rules.Find(x => x.Priority == priority);
    }
    #endregion IEnumerable<IExcelConditionalFormatting>

    /****************************************************************************************/

    #region Conditional Formatting Rules
    /// <summary>
    /// Add rule (internal)
    /// </summary>
    /// <param name="type"></param>
    /// <param name="address"></param>
    /// <returns></returns>F
    internal IExcelConditionalFormattingRule AddRule(
      eExcelConditionalFormattingRuleType type,
      ExcelAddress address)
    {
      Require.Argument(address).IsNotNull("address");

      address = ValidateAddress(address);
      EnsureRootElementExists();

      // Create the Rule according to the correct type, address and priority
      IExcelConditionalFormattingRule cfRule = ExcelConditionalFormattingRuleFactory.Create(
        type,
        address,
        GetNextPriority(),
        _worksheet,
        null);

      // Add the newly created rule to the list
      _rules.Add(cfRule);

      // Return the newly created rule
      return cfRule;
    }

    /// <summary>
    /// Add AboveAverage Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingAverageGroup AddAboveAverage(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingAverageGroup)AddRule(
        eExcelConditionalFormattingRuleType.AboveAverage,
        address);
    }

    /// <summary>
    /// Add AboveOrEqualAverage Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingAverageGroup AddAboveOrEqualAverage(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingAverageGroup)AddRule(
        eExcelConditionalFormattingRuleType.AboveOrEqualAverage,
        address);
    }

    /// <summary>
    /// Add BelowAverage Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingAverageGroup AddBelowAverage(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingAverageGroup)AddRule(
        eExcelConditionalFormattingRuleType.BelowAverage,
        address);
    }

    /// <summary>
    /// Add BelowOrEqualAverage Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingAverageGroup AddBelowOrEqualAverage(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingAverageGroup)AddRule(
        eExcelConditionalFormattingRuleType.BelowOrEqualAverage,
        address);
    }

    /// <summary>
    /// Add AboveStdDev Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingStdDevGroup AddAboveStdDev(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingStdDevGroup)AddRule(
        eExcelConditionalFormattingRuleType.AboveStdDev,
        address);
    }

    /// <summary>
    /// Add BelowStdDev Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingStdDevGroup AddBelowStdDev(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingStdDevGroup)AddRule(
        eExcelConditionalFormattingRuleType.BelowStdDev,
        address);
    }

    /// <summary>
    /// Add Bottom Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTopBottomGroup AddBottom(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTopBottomGroup)AddRule(
        eExcelConditionalFormattingRuleType.Bottom,
        address);
    }

    /// <summary>
    /// Add BottomPercent Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTopBottomGroup AddBottomPercent(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTopBottomGroup)AddRule(
        eExcelConditionalFormattingRuleType.BottomPercent,
        address);
    }

    /// <summary>
    /// Add Top Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTopBottomGroup AddTop(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTopBottomGroup)AddRule(
        eExcelConditionalFormattingRuleType.Top,
        address);
    }

    /// <summary>
    /// Add TopPercent Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTopBottomGroup AddTopPercent(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTopBottomGroup)AddRule(
        eExcelConditionalFormattingRuleType.TopPercent,
        address);
    }

    /// <summary>
    /// Add Last7Days Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddLast7Days(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.Last7Days,
        address);
    }

    /// <summary>
    /// Add LastMonth Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddLastMonth(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.LastMonth,
        address);
    }

    /// <summary>
    /// Add LastWeek Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddLastWeek(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.LastWeek,
        address);
    }

    /// <summary>
    /// Add NextMonth Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddNextMonth(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.NextMonth,
        address);
    }

    /// <summary>
    /// Add NextWeek Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddNextWeek(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.NextWeek,
        address);
    }

    /// <summary>
    /// Add ThisMonth Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddThisMonth(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.ThisMonth,
        address);
    }

    /// <summary>
    /// Add ThisWeek Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddThisWeek(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.ThisWeek,
        address);
    }

    /// <summary>
    /// Add Today Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddToday(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.Today,
        address);
    }

    /// <summary>
    /// Add Tomorrow Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddTomorrow(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.Tomorrow,
        address);
    }

    /// <summary>
    /// Add Yesterday Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTimePeriodGroup AddYesterday(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTimePeriodGroup)AddRule(
        eExcelConditionalFormattingRuleType.Yesterday,
        address);
    }

    /// <summary>
    /// Add BeginsWith Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingBeginsWith AddBeginsWith(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingBeginsWith)AddRule(
        eExcelConditionalFormattingRuleType.BeginsWith,
        address);
    }

    /// <summary>
    /// Add Between Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingBetween AddBetween(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingBetween)AddRule(
        eExcelConditionalFormattingRuleType.Between,
        address);
    }

    /// <summary>
    /// Add ContainsBlanks Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingContainsBlanks AddContainsBlanks(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingContainsBlanks)AddRule(
        eExcelConditionalFormattingRuleType.ContainsBlanks,
        address);
    }

    /// <summary>
    /// Add ContainsErrors Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingContainsErrors AddContainsErrors(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingContainsErrors)AddRule(
        eExcelConditionalFormattingRuleType.ContainsErrors,
        address);
    }

    /// <summary>
    /// Add ContainsText Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingContainsText AddContainsText(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingContainsText)AddRule(
        eExcelConditionalFormattingRuleType.ContainsText,
        address);
    }

    /// <summary>
    /// Add DuplicateValues Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingDuplicateValues AddDuplicateValues(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingDuplicateValues)AddRule(
        eExcelConditionalFormattingRuleType.DuplicateValues,
        address);
    }

    /// <summary>
    /// Add EndsWith Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingEndsWith AddEndsWith(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingEndsWith)AddRule(
        eExcelConditionalFormattingRuleType.EndsWith,
        address);
    }

    /// <summary>
    /// Add Equal Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingEqual AddEqual(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingEqual)AddRule(
        eExcelConditionalFormattingRuleType.Equal,
        address);
    }

    /// <summary>
    /// Add Expression Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingExpression AddExpression(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingExpression)AddRule(
        eExcelConditionalFormattingRuleType.Expression,
        address);
    }

    /// <summary>
    /// Add GreaterThan Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingGreaterThan AddGreaterThan(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingGreaterThan)AddRule(
        eExcelConditionalFormattingRuleType.GreaterThan,
        address);
    }

    /// <summary>
    /// Add GreaterThanOrEqual Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingGreaterThanOrEqual AddGreaterThanOrEqual(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingGreaterThanOrEqual)AddRule(
        eExcelConditionalFormattingRuleType.GreaterThanOrEqual,
        address);
    }

    /// <summary>
    /// Add LessThan Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingLessThan AddLessThan(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingLessThan)AddRule(
        eExcelConditionalFormattingRuleType.LessThan,
        address);
    }

    /// <summary>
    /// Add LessThanOrEqual Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingLessThanOrEqual AddLessThanOrEqual(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingLessThanOrEqual)AddRule(
        eExcelConditionalFormattingRuleType.LessThanOrEqual,
        address);
    }

    /// <summary>
    /// Add NotBetween Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingNotBetween AddNotBetween(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingNotBetween)AddRule(
        eExcelConditionalFormattingRuleType.NotBetween,
        address);
    }

    /// <summary>
    /// Add NotContainsBlanks Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingNotContainsBlanks AddNotContainsBlanks(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingNotContainsBlanks)AddRule(
        eExcelConditionalFormattingRuleType.NotContainsBlanks,
        address);
    }

    /// <summary>
    /// Add NotContainsErrors Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingNotContainsErrors AddNotContainsErrors(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingNotContainsErrors)AddRule(
        eExcelConditionalFormattingRuleType.NotContainsErrors,
        address);
    }

    /// <summary>
    /// Add NotContainsText Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingNotContainsText AddNotContainsText(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingNotContainsText)AddRule(
        eExcelConditionalFormattingRuleType.NotContainsText,
        address);
    }

    /// <summary>
    /// Add NotEqual Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingNotEqual AddNotEqual(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingNotEqual)AddRule(
        eExcelConditionalFormattingRuleType.NotEqual,
        address);
    }

    /// <summary>
    /// Add Unique Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingUniqueValues AddUniqueValues(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingUniqueValues)AddRule(
        eExcelConditionalFormattingRuleType.UniqueValues,
        address);
    }

    /// <summary>
    /// Add ThreeColorScale Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingThreeColorScale AddThreeColorScale(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingThreeColorScale)AddRule(
        eExcelConditionalFormattingRuleType.ThreeColorScale,
        address);
    }

    /// <summary>
    /// Add TwoColorScale Rule
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingTwoColorScale AddTwoColorScale(
      ExcelAddress address)
    {
      return (IExcelConditionalFormattingTwoColorScale)AddRule(
        eExcelConditionalFormattingRuleType.TwoColorScale,
        address);
    }

    /// <summary>
    /// Add ThreeIconSet Rule
    /// </summary>
    /// <param name="Address">The address</param>
    /// <param name="IconSet">Type of iconset</param>
    /// <returns></returns>
    public IExcelConditionalFormattingThreeIconSet<eExcelconditionalFormatting3IconsSetType> AddThreeIconSet(ExcelAddress Address, eExcelconditionalFormatting3IconsSetType IconSet)
    {
        var icon = (IExcelConditionalFormattingThreeIconSet<eExcelconditionalFormatting3IconsSetType>)AddRule(
            eExcelConditionalFormattingRuleType.ThreeIconSet,
            Address);
        icon.IconSet = IconSet;
        return icon;
    }
    /// <summary>
    /// Adds a FourIconSet rule
    /// </summary>
    /// <param name="Address"></param>
    /// <param name="IconSet"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingFourIconSet<eExcelconditionalFormatting4IconsSetType> AddFourIconSet(ExcelAddress Address, eExcelconditionalFormatting4IconsSetType IconSet)
    {
        var icon = (IExcelConditionalFormattingFourIconSet<eExcelconditionalFormatting4IconsSetType>)AddRule(
            eExcelConditionalFormattingRuleType.FourIconSet,
            Address);
        icon.IconSet = IconSet;
        return icon;
    }
    /// <summary>
    /// Adds a FiveIconSet rule
    /// </summary>
    /// <param name="Address"></param>
    /// <param name="IconSet"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingFiveIconSet AddFiveIconSet(ExcelAddress Address, eExcelconditionalFormatting5IconsSetType IconSet)
    {
        var icon = (IExcelConditionalFormattingFiveIconSet)AddRule(
            eExcelConditionalFormattingRuleType.FiveIconSet,
            Address);
        icon.IconSet = IconSet;
        return icon;
    }
    /// <summary>
    /// Adds a databar rule
    /// </summary>
    /// <param name="Address"></param>
    /// <param name="color"></param>
    /// <returns></returns>
    public IExcelConditionalFormattingDataBarGroup AddDatabar(ExcelAddress Address, Color color)
    {
        var dataBar = (IExcelConditionalFormattingDataBarGroup)AddRule(
            eExcelConditionalFormattingRuleType.DataBar,
            Address);
        dataBar.Color=color;
        return dataBar;
    }
    #endregion Conditional Formatting Rules

  }
}