content: /*
   * Copyright (C) 2012 Andrew Neal
   * Copyright (C) 2014 The CyanogenMod Project
   * Copyright (C) 2015 Naman Dwivedi
   *
   * Licensed under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with the
   * License. You may obtain a copy of the License at
   * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
   * or agreed to in writing, software distributed under the License is
   * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied. See the License for the specific language
   * governing permissions and limitations under the License.
   */
  
  package com.wm.remusic.service;
  
  import android.app.Activity;
  import android.content.ComponentName;
  import android.content.ContentResolver;
  import android.content.ContentUris;
  import android.content.ContentValues;
  import android.content.Context;
  import android.content.ContextWrapper;
  import android.content.Intent;
  import android.content.ServiceConnection;
  import android.database.Cursor;
  import android.net.Uri;
  import android.os.IBinder;
  import android.os.RemoteException;
  import android.provider.MediaStore;
  import android.util.Log;
  import android.widget.Toast;
  
  import com.wm.remusic.MediaAidlInterface;
  import com.wm.remusic.R;
  import com.wm.remusic.info.MusicInfo;
  
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.WeakHashMap;
  
  public class MusicPlayer {
  
      private static final WeakHashMap<Context, ServiceBinder> mConnectionMap;
      private static final long[] sEmptyList;
      public static MediaAidlInterface mService = null;
      private static ContentValues[] mContentValuesCache = null;
  
      static {
          mConnectionMap = new WeakHashMap<Context, ServiceBinder>();
          sEmptyList = new long[0];
      }
  
      public static final ServiceToken bindToService(final Context context,
                                                     final ServiceConnection callback) {
  
          Activity realActivity = ((Activity) context).getParent();
          if (realActivity == null) {
              realActivity = (Activity) context;
          }
          final ContextWrapper contextWrapper = new ContextWrapper(realActivity);
          contextWrapper.startService(new Intent(contextWrapper, MediaService.class));
          final ServiceBinder binder = new ServiceBinder(callback,
                  contextWrapper.getApplicationContext());
          if (contextWrapper.bindService(
                  new Intent().setClass(contextWrapper, MediaService.class), binder, 0)) {
              mConnectionMap.put(contextWrapper, binder);
              return new ServiceToken(contextWrapper);
          }
          return null;
      }
  
      public static void unbindFromService(final ServiceToken token) {
          if (token == null) {
              return;
          }
          final ContextWrapper mContextWrapper = token.mWrappedContext;
          final ServiceBinder mBinder = mConnectionMap.remove(mContextWrapper);
          if (mBinder == null) {
              return;
          }
          mContextWrapper.unbindService(mBinder);
          if (mConnectionMap.isEmpty()) {
              mService = null;
          }
      }
  
      public static final boolean isPlaybackServiceConnected() {
          return mService != null;
      }
  
      public static void next() {
          try {
              if (mService != null) {
                  mService.next();
              }
          } catch (final RemoteException ignored) {
          }
      }
  
      public static void initPlaybackServiceWithSettings(final Context context) {
          setShowAlbumArtOnLockscreen(true);
      }
  
      public static void setShowAlbumArtOnLockscreen(final boolean enabled) {
          try {
              if (mService != null) {
                  mService.setLockscreenAlbumArt(enabled);
              }
          } catch (final RemoteException ignored) {
          }
      }
  
      public static void asyncNext(final Context context) {
          final Intent previous = new Intent(context, MediaService.class);
          previous.setAction(MediaService.NEXT_ACTION);
          context.startService(previous);
      }
  
      public static void previous(final Context context, final boolean force) {
          final Intent previous = new Intent(context, MediaService.class);
          if (force) {
              previous.setAction(MediaService.PREVIOUS_FORCE_ACTION);
          } else {
              previous.setAction(MediaService.PREVIOUS_ACTION);
          }
          context.startService(previous);
      }
  
      public static void playOrPause() {
          try {
              if (mService != null) {
                  if (mService.isPlaying()) {
                      mService.pause();
                  } else {
                      mService.play();
                  }
              }
          } catch (final Exception ignored) {
          }
      }
  
  
      public static boolean isTrackLocal() {
          try {
              if (mService != null) {
                  return mService.isTrackLocal();
              }
          } catch (RemoteException e) {
              e.printStackTrace();
          }
          return false;
      }
  
      public static void cycleRepeat() {
          try {
              if (mService != null) {
                  if (mService.getShuffleMode() == MediaService.SHUFFLE_NORMAL) {
                      mService.setShuffleMode(MediaService.SHUFFLE_NONE);
                      mService.setRepeatMode(MediaService.REPEAT_CURRENT);
                      return;
                  } else {
  
                      switch (mService.getRepeatMode()) {
                          case MediaService.REPEAT_CURRENT:
                              mService.setRepeatMode(MediaService.REPEAT_ALL);
                              break;
                          case MediaService.REPEAT_ALL:
                              mService.setShuffleMode(MediaService.SHUFFLE_NORMAL);
  //                        if (mService.getShuffleMode() != MediaService.SHUFFLE_NONE) {
  //                            mService.setShuffleMode(MediaService.SHUFFLE_NONE);
  //                        }
                              break;
  
                      }
                  }
  
              }
          } catch (final RemoteException ignored) {
          }
      }
  
      public static void cycleShuffle() {
          try {
              if (mService != null) {
                  switch (mService.getShuffleMode()) {
                      case MediaService.SHUFFLE_NONE:
                          mService.setShuffleMode(MediaService.SHUFFLE_NORMAL);
                          if (mService.getRepeatMode() == MediaService.REPEAT_CURRENT) {
                              mService.setRepeatMode(MediaService.REPEAT_ALL);
                          }
                          break;
                      case MediaService.SHUFFLE_NORMAL:
                          mService.setShuffleMode(MediaService.SHUFFLE_NONE);
                          break;
  //                    case MediaService.SHUFFLE_AUTO:
  //                        mService.setShuffleMode(MediaService.SHUFFLE_NONE);
  //                        break;
                      default:
                          break;
                  }
              }
          } catch (final RemoteException ignored) {
          }
      }
  
      public static final boolean isPlaying() {
          if (mService != null) {
              try {
                  return mService.isPlaying();
              } catch (final RemoteException ignored) {
              }
          }
          return false;
      }
  
      public static final int getShuffleMode() {
          if (mService != null) {
              try {
                  return mService.getShuffleMode();
              } catch (final RemoteException ignored) {
              }
          }
          return 0;
      }
  
      public static void setShuffleMode(int mode) {
          try {
              if (mService != null) {
                  mService.setShuffleMode(mode);
              }
          } catch (RemoteException ignored) {
  
          }
      }
  
      public static final int getRepeatMode() {
          if (mService != null) {
              try {
                  return mService.getRepeatMode();
              } catch (final RemoteException ignored) {
              }
          }
          return 0;
      }
  
      public static final String getTrackName() {
          if (mService != null) {
              try {
                  return mService.getTrackName();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final String getArtistName() {
          if (mService != null) {
              try {
                  return mService.getArtistName();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final String getAlbumName() {
          if (mService != null) {
              try {
                  return mService.getAlbumName();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final String getAlbumPath() {
          if (mService != null) {
              try {
                  return mService.getAlbumPath();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final String[] getAlbumPathAll() {
          if (mService != null) {
              try {
                  return mService.getAlbumPathtAll();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final long getCurrentAlbumId() {
          if (mService != null) {
              try {
                  return mService.getAlbumId();
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final long getCurrentAudioId() {
          if (mService != null) {
              try {
                  return mService.getAudioId();
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final MusicTrack getCurrentTrack() {
          if (mService != null) {
              try {
                  return mService.getCurrentTrack();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final MusicTrack getTrack(int index) {
          if (mService != null) {
              try {
                  return mService.getTrack(index);
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final long getNextAudioId() {
          if (mService != null) {
              try {
                  return mService.getNextAudioId();
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final long getPreviousAudioId() {
          if (mService != null) {
              try {
                  return mService.getPreviousAudioId();
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final long getCurrentArtistId() {
          if (mService != null) {
              try {
                  return mService.getArtistId();
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final int getAudioSessionId() {
          if (mService != null) {
              try {
                  return mService.getAudioSessionId();
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final long[] getQueue() {
          try {
              if (mService != null) {
                  return mService.getQueue();
              } else {
              }
          } catch (final RemoteException ignored) {
          }
          return sEmptyList;
      }
  
      public static final HashMap<Long, MusicInfo> getPlayinfos() {
          try {
              if (mService != null) {
                  return (HashMap<Long, MusicInfo>) mService.getPlayinfos();
              } else {
              }
          } catch (final RemoteException ignored) {
          }
          return null;
      }
  
      public static final long getQueueItemAtPosition(int position) {
          try {
              if (mService != null) {
                  return mService.getQueueItemAtPosition(position);
              } else {
              }
          } catch (final RemoteException ignored) {
          }
          return -1;
      }
  
      public static final int getQueueSize() {
          try {
              if (mService != null) {
                  return mService.getQueueSize();
              } else {
              }
          } catch (final RemoteException ignored) {
          }
          return 0;
      }
  
      public static final int getQueuePosition() {
          try {
              if (mService != null) {
                  return mService.getQueuePosition();
              }
          } catch (final RemoteException ignored) {
          }
          return 0;
      }
  
      public static void setQueuePosition(final int position) {
          if (mService != null) {
              try {
                  mService.setQueuePosition(position);
              } catch (final RemoteException ignored) {
              }
          }
      }
  
      public static final int getQueueHistorySize() {
          if (mService != null) {
              try {
                  return mService.getQueueHistorySize();
              } catch (final RemoteException ignored) {
              }
          }
          return 0;
      }
  
      public static final int getQueueHistoryPosition(int position) {
          if (mService != null) {
              try {
                  return mService.getQueueHistoryPosition(position);
              } catch (final RemoteException ignored) {
              }
          }
          return -1;
      }
  
      public static final int[] getQueueHistoryList() {
          if (mService != null) {
              try {
                  return mService.getQueueHistoryList();
              } catch (final RemoteException ignored) {
              }
          }
          return null;
      }
  
      public static final int removeTrack(final long id) {
          try {
              if (mService != null) {
                  return mService.removeTrack(id);
              }
          } catch (final RemoteException ingored) {
          }
          return 0;
      }
  
      public static final boolean removeTrackAtPosition(final long id, final int position) {
          try {
              if (mService != null) {
                  return mService.removeTrackAtPosition(id, position);
              }
          } catch (final RemoteException ingored) {
          }
          return false;
      }
  
      public static void moveQueueItem(final int from, final int to) {
          try {
              if (mService != null) {
                  mService.moveQueueItem(from, to);
              } else {
              }
          } catch (final RemoteException ignored) {
          }
      }
  
      public static synchronized void playAll(final HashMap<Long, MusicInfo> infos, final long[] list, int position, final boolean forceShuffle) {
          if (list == null || list.length == 0 || mService == null) {
              return;
          }
          try {
              if (forceShuffle) {
                  mService.setShuffleMode(MediaService.SHUFFLE_NORMAL);
              }
              final long currentId = mService.getAudioId();
              long playId = list[position];
              Log.e("currentId", currentId + "");
              final int currentQueuePosition = getQueuePosition();
              if (position != -1) {
                  final long[] playlist = getQueue();
                  if (Arrays.equals(list, playlist)) {
                      if (currentQueuePosition == position && currentId == list[position]) {
                          mService.play();
                          return;
                      } else {
                          mService.setQueuePosition(position);
                          return;
                      }
  
                  }
              }
              if (position < 0) {
                  position = 0;
              }
              mService.open(infos, list, forceShuffle ? -1 : position);
              mService.play();
              Log.e("time", System.currentTimeMillis() + "");
          } catch (final RemoteException ignored) {
          } catch (IllegalStateException e) {
              e.printStackTrace();
          }
      }
  
      public static void playNext(Context context, final HashMap<Long, MusicInfo> map, final long[] list) {
          if (mService == null) {
              return;
          }
          try {
              int current = -1;
              long[] result = list;
  
              for (int i = 0; i < list.length; i++) {
                  if (MusicPlayer.getCurrentAudioId() == list[i]) {
                      current = i;
                  } else {
                      MusicPlayer.removeTrack(list[i]);
                  }
              }
  
  //            if( current != -1){
  //                ArrayList lists = new ArrayList();
  //                for(int i = 0; i<list.length;i++){
  //                    if(i != current){
  //                        lists.add(list[i]);
  //                    }
  //                }
  //                result = new long[list.length - 1];
  //                for(int i = 0;i<lists.size();i++){
  //                     result[i] = (long) lists.get(i);
  //                }
  //            }
  
              mService.enqueue(list, map, MediaService.NEXT);
  
              Toast.makeText(context, R.string.next_play, Toast.LENGTH_SHORT).show();
          } catch (final RemoteException ignored) {
          }
      }
  
      public static String getPath() {
          if (mService == null) {
              return null;
          }
          try {
              return mService.getPath();
  
          } catch (Exception e) {
  
          }
          return null;
      }
  
      public static void stop() {
          try {
              mService.stop();
          } catch (Exception e) {
  
          }
      }
  
      public static final int getSongCountForAlbumInt(final Context context, final long id) {
          int songCount = 0;
          if (id == -1) {
              return songCount;
          }
  
          Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, id);
          Cursor cursor = context.getContentResolver().query(uri,
                  new String[]{MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS}, null, null, null);
          if (cursor != null) {
              cursor.moveToFirst();
              if (!cursor.isAfterLast()) {
                  if (!cursor.isNull(0)) {
                      songCount = cursor.getInt(0);
                  }
              }
              cursor.close();
              cursor = null;
          }
  
          return songCount;
      }
  
      public static final String getReleaseDateForAlbum(final Context context, final long id) {
          if (id == -1) {
              return null;
          }
          Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, id);
          Cursor cursor = context.getContentResolver().query(uri, new String[]{
                  MediaStore.Audio.AlbumColumns.FIRST_YEAR
          }, null, null, null);
          String releaseDate = null;
          if (cursor != null) {
              cursor.moveToFirst();
              if (!cursor.isAfterLast()) {
                  releaseDate = cursor.getString(0);
              }
              cursor.close();
              cursor = null;
          }
          return releaseDate;
      }
  
      public static void seek(final long position) {
          if (mService != null) {
              try {
                  mService.seek(position);
              } catch (final RemoteException ignored) {
              }
          }
      }
  
      public static void seekRelative(final long deltaInMs) {
          if (mService != null) {
              try {
                  mService.seekRelative(deltaInMs);
              } catch (final RemoteException ignored) {
              } catch (final IllegalStateException ignored) {
  
              }
          }
      }
  
      public static final long position() {
          if (mService != null) {
              try {
                  return mService.position();
              } catch (final RemoteException ignored) {
              } catch (final IllegalStateException ex) {
  
              }
          }
          return 0;
      }
  
      public static final int secondPosition() {
          if (mService != null) {
              try {
                  return mService.secondPosition();
              } catch (final RemoteException ignored) {
              } catch (final IllegalStateException ex) {
  
              }
          }
          return 0;
      }
  
      public static final long duration() {
          if (mService != null) {
              try {
                  return mService.duration();
              } catch (final RemoteException ignored) {
              } catch (final IllegalStateException ignored) {
  
              }
          }
          return 0;
      }
  
      public static void clearQueue() {
  
          try {
              if(mService != null)
              mService.removeTracks(0, Integer.MAX_VALUE);
          } catch (final RemoteException ignored) {
          }
      }
  
      public static void addToQueue(final Context context, final long[] list, long sourceId) {
          if (mService == null) {
              return;
          }
          try {
              mService.enqueue(list, null, MediaService.LAST);
              //final String message = makeLabel(context, R.plurals.NNNtrackstoqueue, list.length);
              //Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
          } catch (final RemoteException ignored) {
          }
      }
  
  
      public static void addToPlaylist(final Context context, final long[] ids, final long playlistid) {
          final int size = ids.length;
          final ContentResolver resolver = context.getContentResolver();
          final String[] projection = new String[]{
                  "max(" + "play_order" + ")",
          };
          final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistid);
          Cursor cursor = null;
          int base = 0;
  
          try {
              cursor = resolver.query(uri, projection, null, null, null);
  
              if (cursor != null && cursor.moveToFirst()) {
                  base = cursor.getInt(0) + 1;
              }
          } finally {
              if (cursor != null) {
                  cursor.close();
                  cursor = null;
              }
          }
  
          int numinserted = 0;
          for (int offSet = 0; offSet < size; offSet += 1000) {
              makeInsertItems(ids, offSet, 1000, base);
              numinserted += resolver.bulkInsert(uri, mContentValuesCache);
          }
  
      }
  
      public static void makeInsertItems(final long[] ids, final int offset, int len, final int base) {
          if (offset + len > ids.length) {
              len = ids.length - offset;
          }
  
          if (mContentValuesCache == null || mContentValuesCache.length != len) {
              mContentValuesCache = new ContentValues[len];
          }
          for (int i = 0; i < len; i++) {
              if (mContentValuesCache[i] == null) {
                  mContentValuesCache[i] = new ContentValues();
              }
              mContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
              mContentValuesCache[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, ids[offset + i]);
          }
      }
  
      public static final long createPlaylist(final Context context, final String name) {
          if (name != null && name.length() > 0) {
              final ContentResolver resolver = context.getContentResolver();
              final String[] projection = new String[]{
                      MediaStore.Audio.PlaylistsColumns.NAME
              };
              final String selection = MediaStore.Audio.PlaylistsColumns.NAME + " = '" + name + "'";
              Cursor cursor = resolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
                      projection, selection, null, null);
              if (cursor.getCount() <= 0) {
                  final ContentValues values = new ContentValues(1);
                  values.put(MediaStore.Audio.PlaylistsColumns.NAME, name);
                  final Uri uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
                          values);
                  return Long.parseLong(uri.getLastPathSegment());
              }
              if (cursor != null) {
                  cursor.close();
                  cursor = null;
              }
              return -1;
          }
          return -1;
      }
  
      public static void exitService() {
  //        if (mService == null) {
  //            return;
  //        }
          try {
              mConnectionMap.clear();
              Log.e("exitmp", "Destroying service");
              mService.exit();
          } catch (Exception e) {
          }
      }
  
      public static void timing(int time) {
          if (mService == null) {
              return;
          }
          try {
              mService.timing(time);
          } catch (Exception e) {
  
          }
      }
  
      public static final class ServiceBinder implements ServiceConnection {
          private final ServiceConnection mCallback;
          private final Context mContext;
  
  
          public ServiceBinder(final ServiceConnection callback, final Context context) {
              mCallback = callback;
              mContext = context;
          }
  
          @Override
          public void onServiceConnected(final ComponentName className, final IBinder service) {
              mService = MediaAidlInterface.Stub.asInterface(service);
              if (mCallback != null) {
                  mCallback.onServiceConnected(className, service);
              }
              initPlaybackServiceWithSettings(mContext);
          }
  
          @Override
          public void onServiceDisconnected(final ComponentName className) {
              if (mCallback != null) {
                  mCallback.onServiceDisconnected(className);
              }
              mService = null;
          }
      }
  
      public static final class ServiceToken {
          public ContextWrapper mWrappedContext;
  
          public ServiceToken(final ContextWrapper context) {
              mWrappedContext = context;
          }
      }
  
  
  }
  