content: package im.actor.sdk.core.audio;
  
  import android.content.Context;
  
  import com.droidkit.opus.OpusLib;
  
  import java.util.ArrayList;
  
  import im.actor.runtime.actors.Actor;
  import im.actor.runtime.actors.ActorCreator;
  import im.actor.runtime.actors.ActorRef;
  import im.actor.runtime.actors.ActorSystem;
  import im.actor.runtime.actors.Props;
  
  public class AudioPlayerActor extends Actor {
  
      private ActorRef androidPlayerActor;
      private ActorRef opusPlayerActor;
  
      private OpusLib opusLib;
  
      private boolean isInited;
      private AudioPlayerCallback callback;
      private boolean usedAndroid;
      private Context context;
      private String currenFile;
      private ArrayList<AudioPlayerCallback> callbacks;
  
      @Override
      public void preStart() {
          androidPlayerActor = ActorSystem.system().actorOf(Props.create(new ActorCreator() {
              @Override
              public AndroidPlayerActor create() {
                  return new AndroidPlayerActor(context, callback);
              }
          }), "actor/android_player");
          opusPlayerActor = ActorSystem.system().actorOf(Props.create(new ActorCreator() {
              @Override
              public OpusPlayerActor create() {
                  return new OpusPlayerActor(callback);
              }
          }), "actor/opus_player");
      }
  
      public AudioPlayerActor(Context context) {
          this.context = context;
          opusLib = new OpusLib();
          callbacks = new ArrayList<AudioPlayerCallback>();
          this.callback = new AudioPlayerCallback() {
              @Override
              public void onStart(String fileName) {
                  for (AudioPlayerCallback callback : callbacks) {
                      callback.onStart(fileName);
                  }
              }
  
              @Override
              public void onStop(String fileName) {
                  for (AudioPlayerCallback callback : callbacks) {
                      callback.onStop(fileName);
                  }
              }
  
              @Override
              public void onPause(String fileName, float progress) {
                  for (AudioPlayerCallback callback : callbacks) {
                      callback.onPause(fileName, progress);
                  }
              }
  
              @Override
              public void onProgress(String fileName, float progress) {
                  for (AudioPlayerCallback callback : callbacks) {
                      callback.onProgress(fileName, progress);
                  }
              }
  
              @Override
              public void onError(String fileName) {
                  for (AudioPlayerCallback callback : callbacks) {
                      callback.onError(fileName);
                  }
              }
          };
      }
  
      protected void onPlayMessage(String fileName) {
          ;
          currenFile = fileName;
          if (isInited) {
              onStopMessage();
          }
  
          this.usedAndroid = opusLib.isOpusFile(fileName) <= 0;
          this.isInited = true;
  
          if (usedAndroid) {
              androidPlayerActor.send(new AndroidPlayerActor.Play(fileName));
              opusPlayerActor.send(new OpusPlayerActor.Stop());
          } else {
              androidPlayerActor.send(new AndroidPlayerActor.Stop());
              opusPlayerActor.send(new OpusPlayerActor.Play(fileName));
          }
      }
  
      protected void onStopMessage() {
          if (isInited) {
              if (usedAndroid) {
                  androidPlayerActor.send(new AndroidPlayerActor.Stop());
              } else {
                  opusPlayerActor.send(new OpusPlayerActor.Stop());
              }
          } else {
              for (AudioPlayerCallback callback : callbacks) {
                  callback.onStop(null);
              }
          }
          isInited = false;
      }
  
      protected void onToggleMessage(String fileName) {
          if (isInited) {
              if (currenFile == fileName) {
                  if (usedAndroid) {
                      androidPlayerActor.send(new AndroidPlayerActor.Toggle(fileName));
                  } else {
                      opusPlayerActor.send(new OpusPlayerActor.Toggle(fileName));
                  }
              } else {
                  onStopMessage();
              }
          }
  
          if (!isInited) {
              onPlayMessage(fileName);
          }
      }
  
      protected void addCallback(AudioPlayerActor.AudioPlayerCallback callback) {
          callbacks.add(callback);
      }
  
      protected void removeCallback(AudioPlayerActor.AudioPlayerCallback callback) {
          callbacks.remove(callback);
      }
  
      protected void onSeek(float position, String fileName) {
          currenFile = fileName;
          this.isInited = true;
          if (usedAndroid) {
              //androidPlayerActor.send(new AndroidPlayerActor.Toggle(fileName));
          } else {
              opusPlayerActor.send(new OpusPlayerActor.Seek(position, fileName));
          }
  
      }
  
  
      public interface AudioPlayerCallback {
          void onStart(String fileName);
  
          void onStop(String fileName);
  
          void onPause(String fileName, float progress);
  
          void onProgress(String fileName, float progress);
  
          void onError(String fileName);
      }
  
      @Override
      public void onReceive(Object message) {
          if (message instanceof Play) {
              onPlayMessage(((Play) message).getFilename());
          } else if (message instanceof Stop) {
              onStopMessage();
          } else if (message instanceof Toggle) {
              onToggleMessage(((Toggle) message).getFilename());
          } else if (message instanceof RegisterCallback) {
              addCallback(((RegisterCallback) message).getCallback());
          } else if (message instanceof RemoveCallback) {
              removeCallback(((RemoveCallback) message).getCallback());
          } else if (message instanceof Seek) {
              onSeek(((Seek) message).getPosition(), ((Seek) message).getFilename());
          }
      }
  
      public static class Play {
          String filename;
  
          public Play(String filename) {
              this.filename = filename;
          }
  
          public String getFilename() {
              return filename;
          }
      }
  
      public static class Stop {
  
      }
  
      public static class Toggle {
          String filename;
  
          public Toggle(String filename) {
              this.filename = filename;
          }
  
          public String getFilename() {
              return filename;
          }
      }
  
      public static class RegisterCallback {
          AudioPlayerActor.AudioPlayerCallback callback;
  
          public RegisterCallback(AudioPlayerActor.AudioPlayerCallback callback) {
              this.callback = callback;
          }
  
          public AudioPlayerActor.AudioPlayerCallback getCallback() {
              return callback;
          }
      }
  
      public static class RemoveCallback {
          AudioPlayerActor.AudioPlayerCallback callback;
  
          public RemoveCallback(AudioPlayerActor.AudioPlayerCallback callback) {
              this.callback = callback;
          }
  
          public AudioPlayerActor.AudioPlayerCallback getCallback() {
              return callback;
          }
      }
  
      public static class Seek {
          float position;
          String filename;
  
          public Seek(float position, String filename) {
              this.position = position;
              this.filename = filename;
          }
  
          public String getFilename() {
              return filename;
          }
  
          public float getPosition() {
              return position;
          }
      }
  }