package org.xbmc.android.remote.business.cm;
import java.util.ArrayList;
import java.util.List;
import org.xbmc.android.jsonrpc.api.AbstractCall;
import org.xbmc.android.jsonrpc.api.call.AudioLibrary;
import org.xbmc.android.jsonrpc.api.call.Player;
import org.xbmc.android.jsonrpc.api.call.Player.GetActivePlayers;
import org.xbmc.android.jsonrpc.api.call.Player.GetActivePlayers.GetActivePlayersResult;
import org.xbmc.android.jsonrpc.api.call.Player.Seek;
import org.xbmc.android.jsonrpc.api.call.Playlist;
import org.xbmc.android.jsonrpc.api.call.VideoLibrary;
import org.xbmc.android.jsonrpc.api.model.GlobalModel.Time;
import org.xbmc.android.jsonrpc.api.model.ListModel;
import org.xbmc.android.jsonrpc.api.model.ListModel.AllItems;
import org.xbmc.android.jsonrpc.api.model.ListModel.BaseItem;
import org.xbmc.android.jsonrpc.api.model.PlayerModel;
import org.xbmc.android.jsonrpc.api.model.PlayerModel.PropertyValue;
import org.xbmc.android.jsonrpc.api.model.PlaylistModel;
import org.xbmc.android.util.StringUtil;
import org.xbmc.api.business.DataResponse;
import org.xbmc.api.business.IControlManager;
import org.xbmc.api.data.IControlClient;
import org.xbmc.api.data.IControlClient.ICurrentlyPlaying;
import org.xbmc.api.info.PlayStatus;
import org.xbmc.api.type.MediaType;
import org.xbmc.api.type.SeekType;
import android.content.Context;
import android.util.Log;
public class ControlManager extends AbstractManager implements IControlManager {
public void playFile(DataResponse<Boolean> response, String filename,
Context context) {
call(new Player.Open(new PlaylistModel.Item(
new PlaylistModel.Item.File(filename))),
new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
}
public void playFolder(DataResponse<Boolean> response, final String foldername,
String playlistType, Context context) {
call(new Player.Open(new PlaylistModel.Item(
new PlaylistModel.Item.Directory(foldername))),
new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
}
public void queueFolder(DataResponse<Boolean> response, String foldername,
String playlistType, Context context) {
call(new Playlist.Add(Integer.parseInt(playlistType), new PlaylistModel.Item(
new PlaylistModel.Item.Directory(foldername))),
new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
}
public void playUrl(DataResponse<Boolean> response, String url,
Context context) {
playFile(response, url, context);
}
public void seek(final DataResponse<Boolean> response, SeekType type,
final int progress, final Context context) {
callRaw(new Player.GetActivePlayers(),
new ApiHandler<Integer, GetActivePlayers.GetActivePlayersResult>() {
@Override
public Integer handleResponse(
AbstractCall<GetActivePlayersResult> apiCall) {
ArrayList<GetActivePlayersResult> results = apiCall
.getResults();
if (results.size() == 0) {
return 0;
}
GetActivePlayersResult result = results.get(results.size() - 1);
final int playerid = result.playerid;
call(new Player.Seek(playerid, (double) progress),
new ApiHandler<Boolean, Seek.SeekResult>() {
@Override
public Boolean handleResponse(
AbstractCall<Seek.SeekResult> apiCall) {
// Seek.SeekResult result =
// apiCall.getResule();
// result.
// TODO: This could update the position
// directly
return Boolean.TRUE;
}
}, response, context);
return result.playerid;
}
}, context);
}
public void updateLibrary(DataResponse<Boolean> response, String mediaType,
Context context) {
if ("music".equals(mediaType)) {
call(new AudioLibrary.Scan(""), new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
} else if ("pictures".equals(mediaType)) {
//?
} else if ("video".equals(mediaType)) {
call(new VideoLibrary.Scan(""), new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
}
}
public void showPicture(DataResponse<Boolean> response, String filename,
Context context) {
playFile(response, filename, context);
}
public void getCurrentlyPlaying(
final DataResponse<ICurrentlyPlaying> response,
final Context context) {
callRaw(new Player.GetActivePlayers(),
new ApiHandler<Integer, GetActivePlayers.GetActivePlayersResult>() {
@Override
public Integer handleResponse(
AbstractCall<GetActivePlayersResult> apiCall) {
ArrayList<GetActivePlayersResult> results = apiCall
.getResults();
if (results.size() == 0) {
return 0;
}
GetActivePlayersResult result = results.get(results.size() - 1);
final int playerid = result.playerid;
callRaw(new Player.GetProperties(playerid, "time",
"speed", "position","totaltime", "percentage"),
new ApiHandler<Boolean, PlayerModel.PropertyValue>() {
@Override
public Boolean handleResponse(
AbstractCall<PropertyValue> apiCall) {
final PropertyValue propertyValue = apiCall
.getResult();
call(new Player.GetItem(playerid,
BaseItem.ALBUMARTIST,
BaseItem.FILE,
BaseItem.DURATION,
BaseItem.ARTIST,
BaseItem.ALBUM,
BaseItem.THUMBNAIL,
BaseItem.SHOWTITLE,
BaseItem.SEASON,
BaseItem.EPISODE,
BaseItem.FANART,
BaseItem.RUNTIME,
BaseItem.TAGLINE,
BaseItem.TITLE,
BaseItem.GENRE),
new ApiHandler<ICurrentlyPlaying, ListModel.AllItems>() {
@Override
public ICurrentlyPlaying handleResponse(
AbstractCall<AllItems> apiCall) {
return getCurrentlyPlaying(
apiCall.getResult(),
propertyValue);
}
}, response, context);
return Boolean.TRUE;
}
}, context);
return result.playerid;
}
}, context);
}
private ICurrentlyPlaying getCurrentlyPlaying(
final ListModel.AllItems item, final PropertyValue propertyValue) {
if (item == null)
return IControlClient.NOTHING_PLAYING;
if (item.file != null && item.file.contains("Nothing Playing")) {
return IControlClient.NOTHING_PLAYING;
} else {
return new IControlClient.ICurrentlyPlaying() {
private static final long serialVersionUID = 5036994329211476714L;
public String getTitle() {
if ("song".equals(item.type)) {
return item.label;
} else if ("episode".equals(item.type)) {
return item.showtitle;
} else if ("movie".equals(item.type)) {
return item.title;
}
String[] path = item.file.split("/");
return path[path.length - 1];
}
public int getTime() {
return parseTime(propertyValue.time);
}
public int getPlayStatus() {
return PlayStatus.parse(propertyValue.speed);
}
public int getPlaylistPosition() {
return propertyValue.position;
}
public float getPercentage() {
return propertyValue.percentage.floatValue();
}
public String getFilename() {
return item.file;
}
public int getDuration() {
return parseTime(propertyValue.totaltime);
}
public String getArtist() {
if ("song".equals(item.type)) {
List<String> albumArtist = item.albumartist;
if (albumArtist.size() > 0) {
return albumArtist.get(0);
}
if (item.artist.size() > 0) {
return item.artist.get(0);
}
} else if ("episode".equals(item.type)) {
if (Integer.valueOf(item.season) == 0) {
return "Specials / Episode " + item.episode;
} else {
return "Season " + item.season + " / Episode "
+ item.episode;
}
} else if ("movie".equals(item.type)) {
return StringUtil.join(" / ", item.genre);
} else if ("picture".equals(item.type)) {
return "Image";
}
return "";
}
public String getAlbum() {
if ("song".equals(item.type)) {
return item.album;
} else if ("episode".equals(item.type)) {
return item.title;
} else if ("movie".equals(item.type)) {
String title = item.tagline;
if (title != null) {
return title;
}
}
String[] path = item.file.replaceAll("\\\\", "/").split("/");
if (path.length<2)
return "";
return path[path.length - 2];
}
public int getMediaType() {
return MediaType.MUSIC;
}
public boolean isPlaying() {
return propertyValue.speed > 0;
}
public int getHeight() {
return 0;
}
public int getWidth() {
return 0;
}
private int parseTime(Time time) {
int hours = time.hours;
// int milliseconds =
// time.get("milliseconds").getIntValue();
int minutes = time.minutes;
int seconds = time.seconds;
return (hours * 3600) + (minutes * 60) + seconds;
}
public String getThumbnail() {
return item.thumbnail;
}
public String getFanart() {
return item.fanart;
}
};
}
}
/**
* getPlaylistId only returns Music or Video currently so it's useful for playlist management
*/
public void getPlaylistId(DataResponse<Integer> response, Context context) {
call(new Player.GetActivePlayers(),
new ApiHandler<Integer, GetActivePlayers.GetActivePlayersResult>() {
@Override
public Integer handleResponse(
AbstractCall<GetActivePlayersResult> apiCall) {
ArrayList<GetActivePlayersResult> results = apiCall
.getResults();
if (results.size() == 0) {
return 0;
}
GetActivePlayersResult result = results.get(0);
return result.playerid;
}
}, response, context);
}
public void setPlaylistId(DataResponse<Boolean> response, int id,
Context context) {
response.value = Boolean.TRUE;
onFinish(response);
}
public void setPlaylistPos(final DataResponse<Boolean> response, final int position,
final Context context) {
getPlaylistId(new DataResponse<Integer>() {
@Override
public void run() {
call(new Player.GoTo(value, position),
new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
}
}, context);
}
public void clearPlaylist(DataResponse<Boolean> response,
String playlistId, Context context) {
call(new Playlist.Clear(Integer.parseInt(playlistId)),
new ApiHandler<Boolean, String>() {
@Override
public Boolean handleResponse(AbstractCall<String> apiCall) {
return "OK".equals(apiCall.getResult());
}
}, response, context);
}
public void setGuiSetting(DataResponse<Boolean> response, int setting,
String value, Context context) {
// TODO Auto-generated method stub
}
public void getVolume(DataResponse<Integer> response, Context context) {
// TODO Auto-generated method stub
}
public void sendText(DataResponse<Boolean> response, String text,
Context context) {
// TODO Auto-generated method stub
}
}