package leigh.conflux;

import leigh.eo.EO;
import leigh.eo.EOLoop;
import leigh.mecha.math.IntIntervals;
import leigh.mecha.sort.SortPolicy;

import java.util.List;
import java.util.Locale;

/**
 * Classes implementing this interface provide a Conflux DataFrame, a specialized data structure designed for
 * interactive data exploration.
 * <p>
 * As a design note, there is zero requirement that the object stored within the DataFrame be homogeneous.
 *
 * @author Alex Leigh
 */
public interface DataFrame {
    int size();

    EO get(int idx);

    void replaceData(EOLoop data);

    void clearFilters();


    /**
     * Set the sort policy for this frame. To remove sorting and return to the natural order of the data,
     * pass <code>null</code>. This will not actually sort the view.
     * <p>
     * Once the sort policy has been set into the dataframe, do not modify it. The policy will be used in the
     * future by the frame when certain operations are performed (like re-filtering or updating the underlying
     * data). Additionally, if the policy is modified outside of the class at a later time, it will not trigger
     * a sort within the frame. To re-sort the frame, call this method with a new policy.
     *
     * @param policy The policy or <code>null</code>
     */
    void setSortPolicy(SortPolicy<EO> policy);

    /**
     * Set a quick filter for the given key. Setting the filter does not apply it to the data, so the view remains
     * unchanged after this method is called. To apply the filters, call <code>applyFilters()</code>.
     */
    void setQuickFilter(String key, String filter);

    EOLoop applyFilters(EOLoop secondary);

    /**
     * Apply all outstanding filters and sort the frame. This produces an updated version of the view.
     */
    void process() throws Exception;

    /**
     * Get the current selection, if any. This method will always return a {@link IntIntervals} object, it may simply
     * be empty. There is no guarantee that the resulting object has been compacted. To change the selection the
     * caller may modify the returned object.
     */
    IntIntervals getSelection();

    /**
     * Return the current state of the view in the form of a read-only list.
     *
     * @return The view.
     */
    List<EO> getView();

    /**
     * Create a new empty EO in the frame. This implicitly adds it to the end of the view regardless of the current
     * filter parameters.
     *
     * @return
     */
    EO create(String type);

    void add(EO obj);

    /**
     * Remove an object from the frame, given its view index. An object of the given index must exist in the
     * frame.
     *
     * @param viewIdx The view index of the object to remove.
     */
    void delete(int viewIdx);

    /**
     * Return the objects in the view which are currently selected. If no objects are selected, an empty list is
     * returned.
     */
    List<EO> getSelected();

    /**
     * Return the {@link Locale} associated with this dataframe.
     */
    Locale getLocale();

    void deleteSelected();
}
