/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2003-2006 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   All rights reserved                                                    **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the Eclipse Public License 1.0 which accompanies this     **
 **   distribution, and is available at:                                     **
 **   http://www.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl - initial API and implementation (bpasero@rssowl.org)         **
 **                                                                          **
 **  **********************************************************************  */

package net.sourceforge.rssowl.util.search;

import net.sourceforge.rssowl.util.shop.RegExShop;

import java.util.ArrayList;
import java.util.Hashtable;

/**
 * The ParsedSearch class takes a SearchDefinition as Input to parse. In case
 * the definition tells to use the Pattern directly as regular expression, the
 * Pattern is not parsed. In the other case, the given Pattern is parsed for the
 * Search-Keywords "AND", "OR" and "NOT", which may be used to specify the
 * Search.<br>
 * The Result of the parsing are two Lists, one for the must- and one for the
 * must-not include keywords.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class ParsedSearch {
  private ArrayList mustContain;
  private ArrayList mustNotContain;
  private SearchDefinition searchDefinition;

  /**
   * Instantiate a new ParsedSearch.
   * 
   * @param searchDefinition The Definition of this Search.
   */
  private ParsedSearch(SearchDefinition searchDefinition) {
    this.searchDefinition = searchDefinition;
  }

  /**
   * Parse the given Search Definition.
   * 
   * @param searchDefinition The Definition of this Search.
   * @return ParsedSearch The parsed Search from the given definition.
   */
  public static ParsedSearch parseFrom(SearchDefinition searchDefinition) {
    ParsedSearch parsedSearch = new ParsedSearch(searchDefinition);

    /** This is not a RegEx Search, therefor parse the pattern */
    if (!searchDefinition.isPatternRegEx()) {

      /** Escape possible regular expression values */
      String pattern = RegExShop.escapeRegEx(searchDefinition.getPattern());

      /** Parse Pattern */
      Hashtable parsedPattern = SearchPatternParser.parsePattern(pattern);

      /** Retrieve the list with must-contain Keywords */
      ArrayList mustContainList = SearchPatternParser.generateRegEx((ArrayList) parsedPattern.get(SearchPatternParser.MUST_CONTAIN_KEY), searchDefinition.isWholeWord());
      parsedSearch.setMustContain(mustContainList);

      /** Retrieve the list with must-not-contain Keywords */
      ArrayList mustNotContainList = (ArrayList) parsedPattern.get(SearchPatternParser.MUSTNOT_CONTAIN_KEY);
      parsedSearch.setMustNotContain(mustNotContainList);
    }

    return parsedSearch;
  }

  /**
   * Get the List with must-contain Keywords.
   * 
   * @return ArrayList A List of regular expressions that must match the
   * NewsItem in the defined Scope.
   */
  public ArrayList getMustContain() {
    return mustContain;
  }

  /**
   * Get the List with must-not-contain Keywords.
   * 
   * @return ArrayList A List of regular expressions that must not match the
   * NewsItem in the defined Scope.
   */
  public ArrayList getMustNotContain() {
    return mustNotContain;
  }

  /**
   * Get the Search Defintion.
   * 
   * @return SearchDefinition The Definition of this Search.
   */
  public SearchDefinition getSearchDefinition() {
    return searchDefinition;
  }

  /**
   * Check wether this search is a plain regular expression search.
   * 
   * @return TRUE if the Pattern should not be parsed but used as regular
   * expression directly.
   */
  public boolean isRegExSearch() {
    return searchDefinition.isPatternRegEx();
  }

  /**
   * Set the List with must-contain Keywords.
   * 
   * @param mustContain A List of regular expressions that must match the
   * NewsItem in the defined Scope.
   */
  private void setMustContain(ArrayList mustContain) {
    this.mustContain = mustContain;
  }

  /**
   * Set the List with must-not-contain Keywords.
   * 
   * @param mustNotContain A List of regular expressions that must not match the
   * NewsItem in the defined Scope.
   */
  private void setMustNotContain(ArrayList mustNotContain) {
    this.mustNotContain = mustNotContain;
  }
}