<commit_before>package org.intellimate.izou.sdk.frameworks.music.player.template;

import org.intellimate.izou.events.EventListenerModel;
import org.intellimate.izou.events.EventModel;
import org.intellimate.izou.identification.Identifiable;
import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.identification.IdentificationManager;
import org.intellimate.izou.resource.ResourceBuilderModel;
import org.intellimate.izou.resource.ResourceModel;
import org.intellimate.izou.sdk.Context;
import org.intellimate.izou.sdk.frameworks.common.resources.SelectorResource;
import org.intellimate.izou.sdk.frameworks.music.Capabilities;
import org.intellimate.izou.sdk.frameworks.music.events.PlayerCommand;
import org.intellimate.izou.sdk.frameworks.music.events.PlayerError;
import org.intellimate.izou.sdk.frameworks.music.events.StartMusicRequest;
import org.intellimate.izou.sdk.frameworks.music.events.StopMusic;
import org.intellimate.izou.sdk.frameworks.music.player.*;
import org.intellimate.izou.sdk.frameworks.music.resources.*;
import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.MuteEvent;
import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.StopEvent;
import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.UnMuteEvent;
import org.intellimate.izou.sdk.frameworks.presence.events.LeavingEvent;
import org.intellimate.izou.sdk.output.OutputPlugin;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * use this class to actually play music.
 * <p>
 * <b>How to use it:</b><br>
 * Usage is pretty straightforward. Extend this class an override the abstract methods.<br>
 *  - To register further commands, use the getCommandHandler() method in the constructor.<br>
 *  - To start playing, use the PlayerController.startPlaying() methods, never call the play() method directly!
 * Also, don't call the stopSound() method directly, use stopMusicPlayback().
 * All basic methods are implemented in this class,but to code special behaviour fell free to explore the other
 * classes and interfaces.<br>
 * Note: the playback automatically stops when the user left.<br>
 * </p>
 * @author LeanderK
 * @version 1.0
 */
public abstract class Player<T> extends OutputPlugin<T> implements MusicProvider, ResourceBuilderModel, MusicHelper, EventListenerModel {
    private Playlist playlist = new Playlist(new ArrayList<>());
    private Volume volume = Volume.createVolume(50).orElse(null);
    private Progress progress = new Progress(0,0);
    private PlaybackState playbackState = PlaybackState.PLAY;
    private final Capabilities capabilities;
    private CompletableFuture<?> playingThread = null;
    private final boolean runsInPlay;
    private boolean isRunning = false;
    private boolean isPlaying = false;
    private final List<Identifiable> activators;
    private final CommandHandler commandHandler;
    private final InformationProvider informationProvider;
    private final boolean isUsingJava;
    final Lock lock = new ReentrantLock();
    Condition blockRequest = null;

    /**
     * creates a new output-plugin with a new id
     *  @param context context
     * @param id      the id of the new output-plugin. The ID of the InformationProvider is also based on this id
     *                (id + ".InformationProvider")
     * @param runsInPlay whether the termination of the play method should be treated as the termination the
     *                   music (STOP not PAUSE)
     * @param activators the activators which are able to start the Player if the Player is not able to start from
     *                   request from other addons
     * @param providesTrackInfo whether the Player provides TrackInfo
     * @param playbackShuffle whether the player is able to provide the info that the playback is shuffling
     * @param playbackRepeat whether the player is able to provide the info that the playback is repeating
     * @param playbackRepeatSong whether the player is able to provide the info that the playback is repeating the song
     * @param isUsingJava true if using java, false if not (and for example a C-library)
     */
    public Player(Context context, String id, boolean runsInPlay, List<Identifiable> activators,
                  boolean providesTrackInfo, boolean playbackShuffle, boolean playbackRepeat,
                  boolean playbackRepeatSong, boolean isUsingJava) {
        super(context, id);
        this.runsInPlay = runsInPlay;
        this.activators = activators;
        this.isUsingJava = isUsingJava;
        capabilities = new Capabilities();
        if (providesTrackInfo)
            capabilities.setProvidesTrackInfo(true);
        if (playbackShuffle)
            capabilities.setPlaybackShuffle(true);
        if (playbackRepeat)
            capabilities.setPlaybackRepeat(true);
        if (playbackRepeatSong)
            capabilities.setPlaybackRepeatSong(true);
        commandHandler = createCommandHandler();
        informationProvider = new InformationProvider(getContext(), getID(), this,
                commandHandler);
        getContext().getEvents().registerEventListener(Collections.singletonList(LeavingEvent.ID), this);
    }

    /**
     * creates a new output-plugin with a new id
     *  @param context context
     * @param id      the id of the new output-plugin. The ID of the InformationProvider is also based on this id
     *                (id + ".InformationProvider")
     * @param runsInPlay whether the termination of the play method should be treated as the termination the
     *                   music (STOP not PAUSE)
     * @param activator the activator which is able to start the Player if the Player is not able to start from
     *                   request from other addons
     * @param providesTrackInfo whether the Player provides TrackInfo
     * @param playbackShuffle whether the player is able to provide the info that the playback is shuffling
     * @param playbackRepeat whether the player is able to provide the info that the playback is repeating
     * @param playbackRepeatSong whether the player is able to provide the info that the playback is repeating the song
     * @param isUsingJava true if using java, false if not (and for example a C-library)
     */
    @SuppressWarnings("unused")
    public Player(Context context, String id, boolean runsInPlay, Identifiable activator, boolean providesTrackInfo,
                  boolean playbackShuffle, boolean playbackRepeat, boolean playbackRepeatSong, boolean isUsingJava) {
        this(context, id, runsInPlay, Collections.singletonList(activator), providesTrackInfo,
                playbackShuffle, playbackRepeat, playbackRepeatSong, isUsingJava);
    }

    /**
     * creates a new output-plugin with a new id
     *  @param context context
     * @param id      the id of the new output-plugin
     * @param runsInPlay whether the termination of the play method should be treated as the termination of playing the
     *                   music
     * @param playRequestTrackInfo whether the player is able to process PlayRequests with TrackInfo
     * @param providesTrackInfo whether the Player provides TrackInfo
     * @param playbackShuffle whether the player is able to provide the info that the playback is shuffling
     * @param playbackRepeat whether the player is able to provide the info that the playback is repeating
     * @param playbackRepeatSong whether the player is able to provide the info that the playback is repeating the song
     * @param isUsingJava true if using java, false if not (and for example a C-library)
     */
    @SuppressWarnings("unused")
    public Player(Context context, String id, boolean runsInPlay, boolean playRequestTrackInfo, boolean providesTrackInfo,
                  boolean playbackShuffle, boolean playbackRepeat, boolean playbackRepeatSong, boolean isUsingJava) {
        super(context, id);
        this.runsInPlay = runsInPlay;
        this.isUsingJava = isUsingJava;
        activators = null;
        capabilities = new Capabilities(context);
        capabilities.setPlayRequestOutside(true);
        if (playRequestTrackInfo)
            capabilities.setPlayRequestDetailed(true);
        if (providesTrackInfo)
            capabilities.setProvidesTrackInfo(true);
        if (playbackShuffle)
            capabilities.setPlaybackShuffle(true);<commit_msg>fixed deprecating<commit_after>package org.intellimate.izou.sdk.frameworks.music.player.template;

import org.intellimate.izou.events.EventListenerModel;
import org.intellimate.izou.events.EventModel;
import org.intellimate.izou.identification.Identifiable;
import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.identification.IdentificationManager;
import org.intellimate.izou.resource.ResourceBuilderModel;
import org.intellimate.izou.resource.ResourceModel;
import org.intellimate.izou.sdk.Context;
import org.intellimate.izou.sdk.frameworks.common.resources.SelectorResource;
import org.intellimate.izou.sdk.frameworks.music.Capabilities;
import org.intellimate.izou.sdk.frameworks.music.events.PlayerCommand;
import org.intellimate.izou.sdk.frameworks.music.events.PlayerError;
import org.intellimate.izou.sdk.frameworks.music.events.StartMusicRequest;
import org.intellimate.izou.sdk.frameworks.music.events.StopMusic;
import org.intellimate.izou.sdk.frameworks.music.player.*;
import org.intellimate.izou.sdk.frameworks.music.resources.*;
import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.MuteEvent;
import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.StopEvent;
import org.intellimate.izou.sdk.frameworks.permanentSoundOutput.events.UnMuteEvent;
import org.intellimate.izou.sdk.frameworks.presence.events.LeavingEvent;
import org.intellimate.izou.sdk.output.OutputPlugin;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * use this class to actually play music.
 * <p>
 * <b>How to use it:</b><br>
 * Usage is pretty straightforward. Extend this class an override the abstract methods.<br>
 *  - To register further commands, use the getCommandHandler() method in the constructor.<br>
 *  - To start playing, use the PlayerController.startPlaying() methods, never call the play() method directly!
 * Also, don't call the stopSound() method directly, use stopMusicPlayback().
 * All basic methods are implemented in this class,but to code special behaviour fell free to explore the other
 * classes and interfaces.<br>
 * Note: the playback automatically stops when the user left.<br>
 * </p>
 * @author LeanderK
 * @version 1.0
 */
public abstract class Player<T> extends OutputPlugin<T> implements MusicProvider, ResourceBuilderModel, MusicHelper, EventListenerModel {
    private Playlist playlist = new Playlist(new ArrayList<>());
    private Volume volume = Volume.createVolume(50).orElse(null);
    private Progress progress = new Progress(0,0);
    private PlaybackState playbackState = PlaybackState.PLAY;
    private final Capabilities capabilities;
    private CompletableFuture<?> playingThread = null;
    private final boolean runsInPlay;
    private boolean isRunning = false;
    private boolean isPlaying = false;
    private final List<Identifiable> activators;
    private final CommandHandler commandHandler;
    private final InformationProvider informationProvider;
    private final boolean isUsingJava;
    final Lock lock = new ReentrantLock();
    Condition blockRequest = null;

    /**
     * creates a new output-plugin with a new id
     *  @param context context
     * @param id      the id of the new output-plugin. The ID of the InformationProvider is also based on this id
     *                (id + ".InformationProvider")
     * @param runsInPlay whether the termination of the play method should be treated as the termination the
     *                   music (STOP not PAUSE)
     * @param activators the activators which are able to start the Player if the Player is not able to start from
     *                   request from other addons
     * @param providesTrackInfo whether the Player provides TrackInfo
     * @param playbackShuffle whether the player is able to provide the info that the playback is shuffling
     * @param playbackRepeat whether the player is able to provide the info that the playback is repeating
     * @param playbackRepeatSong whether the player is able to provide the info that the playback is repeating the song
     * @param isUsingJava true if using java, false if not (and for example a C-library)
     */
    public Player(Context context, String id, boolean runsInPlay, List<Identifiable> activators,
                  boolean providesTrackInfo, boolean playbackShuffle, boolean playbackRepeat,
                  boolean playbackRepeatSong, boolean isUsingJava) {
        super(context, id);
        this.runsInPlay = runsInPlay;
        this.activators = activators;
        this.isUsingJava = isUsingJava;
        capabilities = new Capabilities();
        if (providesTrackInfo)
            capabilities.setProvidesTrackInfo(true);
        if (playbackShuffle)
            capabilities.setPlaybackShuffle(true);
        if (playbackRepeat)
            capabilities.setPlaybackRepeat(true);
        if (playbackRepeatSong)
            capabilities.setPlaybackRepeatSong(true);
        commandHandler = createCommandHandler();
        informationProvider = new InformationProvider(getContext(), getID(), this,
                commandHandler);
        getContext().getEvents().registerEventListener(Collections.singletonList(LeavingEvent.ID), this);
    }

    /**
     * creates a new output-plugin with a new id
     *  @param context context
     * @param id      the id of the new output-plugin. The ID of the InformationProvider is also based on this id
     *                (id + ".InformationProvider")
     * @param runsInPlay whether the termination of the play method should be treated as the termination the
     *                   music (STOP not PAUSE)
     * @param activator the activator which is able to start the Player if the Player is not able to start from
     *                   request from other addons
     * @param providesTrackInfo whether the Player provides TrackInfo
     * @param playbackShuffle whether the player is able to provide the info that the playback is shuffling
     * @param playbackRepeat whether the player is able to provide the info that the playback is repeating
     * @param playbackRepeatSong whether the player is able to provide the info that the playback is repeating the song
     * @param isUsingJava true if using java, false if not (and for example a C-library)
     */
    @SuppressWarnings("unused")
    public Player(Context context, String id, boolean runsInPlay, Identifiable activator, boolean providesTrackInfo,
                  boolean playbackShuffle, boolean playbackRepeat, boolean playbackRepeatSong, boolean isUsingJava) {
        this(context, id, runsInPlay, Collections.singletonList(activator), providesTrackInfo,
                playbackShuffle, playbackRepeat, playbackRepeatSong, isUsingJava);
    }

    /**
     * creates a new output-plugin with a new id
     *  @param context context
     * @param id      the id of the new output-plugin
     * @param runsInPlay whether the termination of the play method should be treated as the termination of playing the
     *                   music
     * @param playRequestTrackInfo whether the player is able to process PlayRequests with TrackInfo
     * @param providesTrackInfo whether the Player provides TrackInfo
     * @param playbackShuffle whether the player is able to provide the info that the playback is shuffling
     * @param playbackRepeat whether the player is able to provide the info that the playback is repeating
     * @param playbackRepeatSong whether the player is able to provide the info that the playback is repeating the song
     * @param isUsingJava true if using java, false if not (and for example a C-library)
     */
    @SuppressWarnings("unused")
    public Player(Context context, String id, boolean runsInPlay, boolean playRequestTrackInfo, boolean providesTrackInfo,
                  boolean playbackShuffle, boolean playbackRepeat, boolean playbackRepeatSong, boolean isUsingJava) {
        super(context, id);
        this.runsInPlay = runsInPlay;
        this.isUsingJava = isUsingJava;
        activators = null;
        capabilities = new Capabilities();
        capabilities.setPlayRequestOutside(true);
        if (playRequestTrackInfo)
            capabilities.setPlayRequestDetailed(true);
        if (providesTrackInfo)
            capabilities.setProvidesTrackInfo(true);
        if (playbackShuffle)
            capabilities.setPlaybackShuffle(true);
{'fraction_non_alphanumeric': 0.06914064754429503, 'fraction_numerical': 0.0006925607433485312, 'mean_word_length': 3.6036131774707756, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6206471', 'n_tokens_mistral': 4514, 'n_tokens_neox': 4362, 'n_words': 1526}