package m127.netwars.api.event;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;

/**
 * @author Megacrafter127
 * Signifies, that a method is an EventListener.
 * EventListener methods must:
 * <ul>
 * <li>Be public</li>
 * <li>Not be abstract</li>
 * <li>Have no type parameters</li>
 * <li>Have {@link Event} or a subclass of {@link Event} as their sole parameter.</li>
 * </ul>
 * EventListener methods should:
 * <ul>
 * <li>Be static</li>
 * <li>Never throw Exceptions</li>
 * </ul>
 */
@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface EventListener {
	/**
	 * @author Megacrafter127
	 * Specifies a field, which contains the instance, that should be used for a nonstatic EventListener.
	 * Instance fields must:
	 * <ul>
	 * <li>Be public</li>
	 * <li>Be static</li>
	 * <li>Not be <strong>null</strong></li>
	 * <li>Have their declaring class as their type</li>
	 * </ul>
	 * Instance fields should:
	 * <ul>
	 * <li>Be final</li>
	 * <li>Not be used, if possible</li>
	 * </ul>
	 */
	@Target(value = ElementType.FIELD)
	@Retention(value = RetentionPolicy.RUNTIME)
	public static @interface Instance {
		/**
		 * A list of the names of the EventListener methods this Instance field provides the scope for.
		 * @return A list of the names of the EventListener methods this Instance field provides the scope for.
		 */
		public String[] listeners();
	}
	
	/**
	 * Whether or not this EventListener should still be fired for cancelled Events.
	 * Unused if {@link #state()} is {@link EventState#CANCELABLE}.<br>
	 * Default: <strong>false</strong>
	 * @return Whether or not this EventListener should still be fired for cancelled Events.
	 */
	public boolean listenToCanceled() default false;
	/**
	 * The stage of an Event, in which this EventListener should be called.<br>
	 * Default: {@link EventState#POSTHANDLING}
	 * @return The stage of an Event, in which this EventListener should be called.
	 */
	public EventState state() default EventState.POSTHANDLING;
	/**
	 * The priority of this EventListener.
	 * An EventListener of priority x will always be called before an EventListener of priority y, if x>y.
	 * If x=y, the order, in which the EventListeners are called is unspecified, and the call may occur simultaneously in separate threads for the same Event.<br>
	 * Default: <strong>0</strong>
	 * @return The priority of this EventListener.
	 */
	public byte priority() default 0;
}
