/***************************************************************************
    copyright            : (C) 2003-2006 by Robby Stephenson
    email                : robby@periapsis.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of version 2 of the GNU General Public License as  *
 *   published by the Free Software Foundation;                            *
 *                                                                         *
 ***************************************************************************/

#ifndef TELLICO_FILTER_H
#define TELLICO_FILTER_H

#include "datavectors.h"

#include <ksharedptr.h>

#include <tqptrlist.h>
#include <tqstring.h>

namespace Tellico {
  namespace Data {
    class Entry;
  }

/**
 * @author Robby Stephenson
 */
class FilterRule {

public:
  /**
   * Operators for comparison of field and contents.
   * If you change the order or contents of the enum: do not forget
   * to change matches() and @ref FilterRuleWidget::initLists(), too.
   */
  enum Function {
    FuncContains=0, FuncNotContains,
    FuncEquals, FuncNotEquals,
    FuncRegExp, FuncNotRegExp
  };

  FilterRule();
  FilterRule(const TQString& fieldName, const TQString& text, Function func);

  /**
   * A rule is empty if the pattern text is empty
   */
  bool isEmpty() const { return m_pattern.isEmpty(); }
  /**
   * This is the primary function of the rule.
   *
   * @return Returns true if the entry is matched by the rule.
   */
  bool matches(Data::EntryPtr entry) const;

  /**
   * Return filter function. This can be any of the operators
   * defined in @ref Function.
   */
  Function function() const { return m_function; }
  /**
   * Set filter function.
   */
  void setFunction(Function func) { m_function = func; }
  /**
   * Return field name
   */
  const TQString& fieldName() const { return m_fieldName; }
  /**
   * Set field name
   */
  void setFieldName(const TQString& fieldName) { m_fieldName = fieldName; }
  /**
   * Return pattern
   */
  const TQString& pattern() const { return m_pattern; }
  /**
   * Set pattern
   */
//  void setPattern(const TQString& pattern) { m_pattern = pattern; }

private:
  bool equals(Data::EntryPtr entry) const;
  bool contains(Data::EntryPtr entry) const;
  bool matchesRegExp(Data::EntryPtr entry) const;

  TQString m_fieldName;
  Function m_function;
  TQString m_pattern;
};

/**
 * Borrows from KMSearchPattern by Marc Mutz
 *
 * @author Robby Stephenson
 */
class Filter : public TQPtrList<FilterRule>, public KShared {

public:
  enum FilterOp {
    MatchAny,
    MatchAll
  };
  typedef KSharedPtr<Filter> Ptr;

  Filter(FilterOp op) : TQPtrList<FilterRule>(), m_op(op) { setAutoDelete(true); }
  Filter(const Filter& other);

  void setMatch(FilterOp op) { m_op = op; }
  FilterOp op() const { return m_op; }
  bool matches(Data::EntryPtr entry) const;

  void setName(const TQString& name) { m_name = name; }
  const TQString& name() const { return m_name; }

  uint count() const { return TQPtrList<FilterRule>::count(); } // disambiguate

private:
  Filter& operator=(const Filter& other);

  FilterOp m_op;
  TQString m_name;
};

} // end namespace
#endif
