/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
package org.apache.poi.ss.usermodel;

/**
 * Represents autofiltering for the specified worksheet.
 *
 * <p>
 * Filtering data is a quick and easy way to find and work with a subset of data in a range of cells or table.
 * For example, you can filter to see only the values that you specify, filter to see the top or bottom values,
 * or filter to quickly see duplicate values.
 * </p>
 *
 * TODO YK: For now (Aug 2010) POI only supports setting a basic autofilter on a range of cells.
 * In future, when we support more auto-filter functions like custom criteria, sort, etc. we will add
 * corresponding methods to this interface.
 */
public interface AutoFilter {
    /**
     * Apply a custom filter
     *
     * <p>
     * A custom AutoFilter specifies an operator and a value.
     * There can be at most two customFilters specified, and in that case the parent element
     * specifies whether the two conditions are joined by 'and' or 'or'. For any cells whose
     * values do not meet the specified criteria, the corresponding rows shall be hidden from
     * view when the filter is applied.
     * </p>
     *
     * <p>
     * Example:
     * <blockquote><pre>
     *  AutoFilter filter = sheet.setAutoFilter(CellRangeAddress.valueOf("A1:F200"));
     *  filter.applyFilter(0, FilterOperator.GreaterThanOrEqual", "0.2");
     *  filter.applyFilter(1, FilterOperator.LessThanOrEqual"", "0.5");
     * </pre></blockquote>
     * </p>
     *
     * @param columnIndex 0-based column index
     * @param operator the operator to apply
     * @param criteria top or bottom value used in the filter criteria.
     *
     * TODO YK: think how to combine AutoFilter with with DataValidationConstraint, they are really close relatives
     * void applyFilter(int columnIndex, FilterOperator operator, String criteria);
     */


    /**
     * Apply a filter against a list of values
     *
     * <p>
     * Example:
     * <blockquote><pre>
     *  AutoFilter filter = sheet.setAutoFilter(CellRangeAddress.valueOf("A1:F200"));
     *  filter.applyFilter(0, "apache", "poi", "java", "api");
     * </pre></blockquote>
     * </p>
     *
     * @param columnIndex 0-based column index
     * @param values the filter values
     *
     * void applyFilter(int columnIndex, String ... values);
     */
    
}
