package eu.jtzipi.project0.common;

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.event.EventType;

import static javafx.event.Event.ANY;

/**
 * Generic <em>section</em> to define an area bewtween two points.
 * <p>
 * This is a one dimensional abstraction of an area. For that reason we have to
 * listen on two events. The enter the section event and the leave the section
 * event.
 * <br>
 * Usefull not only for gui elements but as a general idea of a spatial area.
 * The original Section is therefore splitted into two subinterfaces. The
 * decoration part now is encapsulated in {@linkplain IDecoratable}.
 *
 * @author
 * @param <T> the generic type of this section
 */
@Roots( author = { "Gerrit Grunewald" },
        modified = true,
        links = { "https://github.com/HanSolo/Medusa" },
        modifiedWhy = "Decouple the mathematical idea of a section" )
public interface ISection<T> extends Comparable<ISection<T>> {

    /**
     * The begin of this section.
     *
     * @return
     */
    T getStart();

    /**
     * The end of this section.
     *
     * @return
     */
    T getEnd();

    /**
     * Check whether the argument is contained in this section.
     *
     * @param value
     *
     * @return
     */
    boolean isContained( T value );

    /**
     *
     * @return
     */
    EventHandler<? extends SectionEvent> getOnEntered();

    /**
     *
     * @return
     */
    EventHandler<? extends SectionEvent> getOnLeft();

    String BEAN_PROP_NAME_ON_SECTION_ENTERED = "onSectionEntered";
    String BEAN_PROP_NAME_ON_SECTION_LEFT = "onSectionLeft";

    /**
     * A section holds two events, the enter section and left section event.
     */
    public static class SectionEvent extends Event {

        /**
         * static global 'Enter the section'-Event
         */
        public static final EventType<SectionEvent> SECTION_ENTERED = new EventType<>( ANY, "SECTION_ENTERED" );
        /**
         * static global 'Leave the section'-Event
         */
        public static final EventType<SectionEvent> SECTION_LEFT = new EventType<>( ANY, "SECTION_LEFT" );

        private static final long serialVersionUID = 3100851543579960626L;

        // ******************** Constructors **********************************
        public SectionEvent( final Object source,
                             final EventTarget eventTarget,
                             final EventType<SectionEvent> eventType ) {
            super( source, eventTarget, eventType );
        }

    }
}
