001package org.intellimate.izou.sdk.frameworks.music.events;
002
003import org.intellimate.izou.events.EventModel;
004import org.intellimate.izou.identification.Identifiable;
005import org.intellimate.izou.identification.Identification;
006import org.intellimate.izou.sdk.events.CommonEvents;
007import org.intellimate.izou.sdk.events.Event;
008import org.intellimate.izou.sdk.frameworks.common.resources.SelectorResource;
009import org.intellimate.izou.sdk.frameworks.music.Capabilities;
010import org.intellimate.izou.sdk.frameworks.music.player.Playlist;
011import org.intellimate.izou.sdk.frameworks.music.player.TrackInfo;
012import org.intellimate.izou.sdk.frameworks.music.resources.PlaylistResource;
013import org.intellimate.izou.sdk.frameworks.music.resources.TrackInfoResource;
014import org.intellimate.izou.system.sound.SoundIDs;
015
016import java.util.Arrays;
017import java.util.List;
018import java.util.Optional;
019
020/**
021 * this events request the start of the music-playing
022 * @author LeanderK
023 * @version 1.0
024 */
025public class StartMusicRequest extends Event {
026    //TODO in izou
027    @SuppressWarnings("SpellCheckingInspection")
028    public static final String ID = "izou.music.events.startrequest";
029
030    /**
031     * Creates a new Event Object
032     *
033     * @param source      the source of the Event, most likely a this reference.
034     * @param isUsingJava true if the player is using java
035     * @throws IllegalArgumentException if one of the Arguments is null or empty
036     */
037    protected StartMusicRequest(Identification source, boolean isUsingJava) throws IllegalArgumentException {
038        super(CommonEvents.Type.RESPONSE_TYPE, source,
039                isUsingJava ? Arrays.asList(ID) : Arrays.asList(ID, SoundIDs.StartEvent.isUsingNonJava)
040        );
041    }
042
043    /**
044     * creates a new StartRequest
045     * @param source the caller
046     * @param target the target who should start playing
047     * @return the optional StartMusicRequest
048     */
049    public static Optional<StartMusicRequest> createStartMusicRequest(Identification source, Identification target) {
050        return createStartMusicRequest(source, target, (TrackInfo) null);
051    }
052
053    /**
054     * creates a new StartRequest
055     * @param source the caller
056     * @param target the target who should start playing
057     * @param trackInfo the track to play
058     * @return the optional StartMusicRequest
059     */
060    public static Optional<StartMusicRequest> createStartMusicRequest(Identification source, Identification target, TrackInfo trackInfo) {
061        return createStartMusicRequest(source, target, trackInfo, true);
062    }
063
064    /**
065     * creates a new StartRequest
066     * @param source the caller
067     * @param target the target who should start playing
068     * @param trackInfo the track to play
069     * @param isUsingJava true if the player is using java
070     * @return the optional StartMusicRequest
071     */
072    public static Optional<StartMusicRequest> createStartMusicRequest(Identification source, Identification target, TrackInfo trackInfo, boolean isUsingJava) {
073        if (target.equals(source))
074            return Optional.empty();
075        try {
076            StartMusicRequest request = new StartMusicRequest(source, isUsingJava);
077            request.addResource(new SelectorResource(source, target));
078            if (trackInfo != null)
079                request.addResource(new TrackInfoResource(target, trackInfo, source));
080            return Optional.of(request);
081        } catch (IllegalArgumentException e) {
082            return Optional.empty();
083        }
084    }
085
086    /**
087     * creates a new StartRequest
088     * @param source the caller
089     * @param target the target who should start playing
090     * @param playlist the playlist to play
091     * @return the optional StartMusicRequest
092     */
093    public static Optional<StartMusicRequest> createStartMusicRequest(Identification source, Identification target, Playlist playlist) {
094        return createStartMusicRequest(source, target, playlist, true);
095    }
096
097    /**
098     * creates a new StartRequest
099     * @param source the caller
100     * @param target the target who should start playing
101     * @param playlist the playlist to play
102     * @param isUsingJava true if the player is using java
103     * @return the optional StartMusicRequest
104     */
105    public static Optional<StartMusicRequest> createStartMusicRequest(Identification source, Identification target, Playlist playlist, boolean isUsingJava) {
106        if (target.equals(source))
107            return Optional.empty();
108        try {
109            StartMusicRequest request = new StartMusicRequest(source, isUsingJava);
110            request.addResource(new SelectorResource(source, target));
111            if (playlist != null)
112                request.addResource(new PlaylistResource(target, playlist, source));
113            return Optional.of(request);
114        } catch (IllegalArgumentException e) {
115            return Optional.empty();
116        }
117    }
118
119    /**
120     * verifies that the StartMusicRequest is correct and checks whether the you are meant to react to it
121     * @param eventModel the EventModel to check against
122     * @param player the identifiable
123     * @param capabilities the capabilities
124     * @param activators the activators which are able to start the player if it is not able to start from outside commands
125     * @return true if verified, false if not
126     */
127    public static boolean verify(EventModel eventModel, Capabilities capabilities, Identifiable player, List<Identifiable> activators) {
128        if (!eventModel.containsDescriptor(StartMusicRequest.ID))
129            return false;
130        if (!capabilities.handlesPlayRequestFromOutside()) {
131            if (activators.stream()
132                    .noneMatch(identifiable -> identifiable.isOwner(eventModel.getSource())))
133                return false;
134        }
135        if (!PlaylistResource.getPlaylist(eventModel).map(playlist -> playlist.verify(capabilities)).orElse(true)) {
136            return false;
137        }
138        return SelectorResource.isTarget(eventModel, player)
139                .orElse(false);
140    }
141}