/*******************************************************************************
 * 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.Collections;
using System.Collections.Generic;
using System.Xml;
using OfficeOpenXml.ConditionalFormatting.Contracts;
using OfficeOpenXml.Utils;

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> {
  private readonly List<IExcelConditionalFormattingRule> _rules = new();
  private readonly ExcelWorksheet _worksheet;

  /// <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(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(ExcelConditionalFormattingConstants.Errors._missingTypeAttribute);
          }

          // Check if @priority attribute exists
          if (cfRuleNode.Attributes[ExcelConditionalFormattingConstants.Attributes._priority]
              == null) {
            throw new(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);
          }
        }
      }
    }
  }

  private void EnsureRootElementExists() {
    // Find the <worksheet> node
    if (_worksheet.WorksheetXml.DocumentElement == null) {
      throw new(ExcelConditionalFormattingConstants.Errors._missingWorksheetNode);
    }
  }

  /// <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;
  }

  /// <summary>
  /// Number of validations
  /// </summary>
  public int Count => _rules.Count;

  /// <summary>
  /// Index operator, returns by 0-based index
  /// </summary>
  /// <param name="index"></param>
  /// <returns></returns>
  public IExcelConditionalFormattingRule this[int index] {
    get => _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 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(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, 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);
  }

  /// <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);
  }
}
