/*
 * 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.log4j.chainsaw;

import org.apache.log4j.chainsaw.components.loggernamepanel.LoggerNameModel;
import org.apache.log4j.rule.Rule;

import java.beans.PropertyChangeListener;
import java.util.List;


/**
 * To allow pluggable TableModel implementations for Chainsaw, this interface has been factored out.
 * <p>
 * This interface is still subject to change.
 *
 * @author Paul Smith &lt;psmith@apache.org&gt;
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 * @author Stephen Pain
 */
public interface EventContainer extends SortTableModel, LoggerNameModel {
    /**
     * Adds an EventCountListener, to be notified when the # of events changes
     *
     * @param listener
     */
    void addEventCountListener(EventCountListener listener);

    void addPropertyChangeListener(PropertyChangeListener l);

    void addPropertyChangeListener(
        String propertyName, PropertyChangeListener l);

    /**
     * Adds a NewKeyListener to be notified when unique Key (Property keys)
     * arrive into this EventContainer
     *
     * @param l
     */
    void addNewKeyListener(NewKeyListener l);

    /**
     * Removes a listener from being notified of NewKey events.
     *
     * @param l
     */
    void removeNewKeyListener(NewKeyListener l);

    /**
     * Clears the model completely
     */
    void clearModel();

    List<LoggingEventWrapper> getMatchingEvents(Rule rule);

    /**
     * Configures this model to use Cyclic or non-cyclic models.
     * This method should fire a property Change event if
     * it involves an actual change in the underlying model.
     * <p>
     * This method does nothing if there is no change in property.
     *
     * @param cyclic
     */
    void setCyclic(boolean cyclic);

    /**
     * If this container is in Cyclic mode, returns the Size of the cyclic buffer,
     * otherwise this method throws an IllegalStateException, when in unlimited
     * mode, this method has no meaning.
     *
     * @return int size of the cyclic buffer
     * @throws IllegalStateException if this containers isCyclic() method returns false.
     */
    int getMaxSize();

    /**
     * Locates a row number, starting from startRow, matching the rule provided
     *
     * @param rule
     * @param startRow
     * @param searchForward
     */
    int locate(Rule rule, int startRow, boolean searchForward);

    /**
     * Returns a copied list of all the event in the model.
     */
    List<LoggingEventWrapper> getAllEvents();

    /**
     * Returns a copied list containing the events in the model with filter applied
     */
    List<LoggingEventWrapper> getFilteredEvents();

    /**
     * Returns the total number of events currently in the model (all, not just filtered)
     *
     * @return size
     */
    int size();

    /**
     * Returns the vector representing the row.
     */
    LoggingEventWrapper getRow(int row);

    /**
     * Adds a row to the model.
     *
     * @param e event
     * @return flag representing whether or not the row is being displayed (not filtered)
     */
    boolean isAddRow(LoggingEventWrapper e);

    /**
     * Fire appropriate table update events for the range.
     */
    void fireTableEvent(int begin, int end, int count);

    /**
     * A row was updated
     *
     * @param row
     * @param checkForNewColumns
     */
    void fireRowUpdated(int row, boolean checkForNewColumns);

    /**
     * Allow a forced notification of the EventCountListeners
     */
    void notifyCountListeners();

    /**
     * Force a re-processing of the table layout
     */
    void reFilter();

    /**
     * Sets the RuleMediator in operation
     *
     * @param ruleMediator
     */
    void setRuleMediator(RuleMediator ruleMediator);

    /**
     * Returns the index of the LoggingEventWrapper
     *
     * @param loggingEventWrapper
     */
    int getRowIndex(LoggingEventWrapper loggingEventWrapper);

    /**
     * Remove property from all events in container
     *
     * @param propName the property name to remove
     */
    void removePropertyFromEvents(String propName);

    /**
     * Evaluate all events against the find rule
     *
     * @param findRule
     */
    int updateEventsWithFindRule(Rule findRule);

    /**
     * Determine next row with a non-default color
     *
     * @param currentRow
     * @param forward
     * @return
     */
    int findColoredRow(int currentRow, boolean forward);

    /**
     * Return the visible search match count
     *
     * @return
     */
    int getSearchMatchCount();
}
