// Copyright 2011 NPR
//
// 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 org.npr.android.util;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import org.npr.android.news.Playable;
import org.npr.android.util.PlaylistProvider.Items;
import org.npr.api.Story;
public class PlaylistRepository {
private final Context applicationContext;
private final ContentResolver contentResolver;
private static final String LOG_TAG = PlaylistProvider.class.getName();
public static final String PLAYLIST_CHANGED =
"org.npr.android.news.PLAYLIST_CHANGE";
public static final String PLAYLIST_CHANGE = "PLAYLIST_CHANGE";
public static final String PLAYLIST_ITEM_ADDED = "PLAYLIST_ITEM_ADDED";
public static final String PLAYLIST_ITEM_REMOVED = "PLAYLIST_ITEM_REMOVED";
public static final String PLAYLIST_CLEAR = "PLAYLIST_CLEAR";
public PlaylistRepository(Context applicationContext,
ContentResolver contentResolver) {
this.applicationContext = applicationContext;
this.contentResolver = contentResolver;
}
public long add(Story story) {
ContentValues values = new ContentValues();
values.put(Items.NAME, story.getTitle());
values.put(Items.URL, story.getPlayableUrl());
values.put(Items.IS_READ, false);
values.put(Items.STORY_ID, story.getId());
Story.Audio audio = story.getPlayable();
if (audio != null) {
values.put(Items.DURATION, audio.getDuration());
}
Log.d(LOG_TAG, "Adding playlist item to db");
Uri uri = contentResolver.insert(PlaylistProvider.CONTENT_URI, values);
Intent playlistChanged = new Intent(PLAYLIST_CHANGED);
playlistChanged.putExtra(PLAYLIST_CHANGE, PLAYLIST_ITEM_ADDED);
applicationContext.sendBroadcast(playlistChanged);
return ContentUris.parseId(uri);
}
public long insert(Story story, int position) {
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI,
null, null, null, PlaylistProvider.Items.PLAY_ORDER + " ASC");
if (c.moveToFirst()) {
do {
int order = c.getInt(c.getColumnIndex(PlaylistProvider.Items.PLAY_ORDER));
if (order >= position) {
long id = (long) c.getInt(c.getColumnIndex(PlaylistProvider
.Items._ID));
updateItemOrder(id, order + 1);
}
} while (c.moveToNext());
}
c.close();
ContentValues values = new ContentValues();
values.put(Items.NAME, story.getTitle());
values.put(Items.URL, story.getPlayableUrl());
values.put(Items.IS_READ, false);
values.put(Items.STORY_ID, story.getId());
values.put(Items.PLAY_ORDER, position);
Story.Audio audio = story.getPlayable();
if (audio != null) {
values.put(Items.DURATION, audio.getDuration());
}
Log.d(LOG_TAG, "Adding playlist item to db");
Uri uri = contentResolver.insert(PlaylistProvider.CONTENT_URI, values);
Intent playlistChanged = new Intent(PLAYLIST_CHANGED);
playlistChanged.putExtra(PLAYLIST_CHANGE, PLAYLIST_ITEM_ADDED);
applicationContext.sendBroadcast(playlistChanged);
return ContentUris.parseId(uri);
}
public void markAsRead(long id) {
Log.d(LOG_TAG, "Item with id " + id + " is being marked as read.");
Uri update = ContentUris.withAppendedId(PlaylistProvider.CONTENT_URI, id);
ContentValues values = new ContentValues();
values.put(Items.IS_READ, true);
contentResolver.update(update, values, null, null);
}
private PlaylistEntry retrievePlaylistItem(String selection,
String[] selectionArgs, String sort) {
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI,
null, selection, selectionArgs, sort);
String title, url, storyID;
long id;
int order;
if (c.moveToFirst()) {
id = c.getInt(c.getColumnIndex(PlaylistProvider.Items._ID));
title = c.getString(c.getColumnIndex(PlaylistProvider.Items.NAME));
url = c.getString(c.getColumnIndex(PlaylistProvider.Items.URL));
order = c.getInt(c.getColumnIndex(PlaylistProvider.Items.PLAY_ORDER));
storyID = c.getString(c.getColumnIndex(PlaylistProvider.Items.STORY_ID));
c.close();
return new PlaylistEntry(id, url, title, false, order, storyID);
}
c.close();
return null;
}
public int getItemCount() {
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI, null,
null, null, null);
int count = c.getCount();
c.close();
return count;
}
public int getReadCount() {
String selection = PlaylistProvider.Items.IS_READ + " = ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = "1";
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI, null,
selection, selectionArgs, null);
int count = c.getCount();
c.close();
return count;
}
public PlaylistEntry getPlaylistItemFromId(long id) {
return getPlaylistItemFromId(Long.toString(id));
}
public PlaylistEntry getPlaylistItemFromId(String id) {
if (id == null || id.equals("-1")) {
return null;
}
String selection = PlaylistProvider.Items._ID + " = ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = id;
return retrievePlaylistItem(selection, selectionArgs, null);
}
public PlaylistEntry getPlaylistItemFromStoryId(String storyId) {
String selection = PlaylistProvider.Items.STORY_ID + " = ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = storyId;
return retrievePlaylistItem(selection, selectionArgs, null);
}
public Playable getFirstUnreadEntry() {
String selection = PlaylistProvider.Items.IS_READ + " = ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = "0";
String sort = PlaylistProvider.Items.PLAY_ORDER + " asc";
PlaylistEntry playlistEntry = retrievePlaylistItem(selection,
selectionArgs, sort);
if (playlistEntry == null) {
return null;
} else {
return Playable.PlayableFactory.fromPlaylistEntry(playlistEntry);
}
}
public Playable getPreviousEntry(long id) {
PlaylistEntry entry = getPlaylistItemFromId(id);
if (entry == null || entry.playOrder == 0) {
return null;
}
String selection = PlaylistProvider.Items.PLAY_ORDER + " < ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = Integer.toString(entry.playOrder);
String sort = PlaylistProvider.Items.PLAY_ORDER + " desc";
PlaylistEntry playlistEntry = retrievePlaylistItem(selection,
selectionArgs, sort);
if (playlistEntry == null) {
return null;
} else {
return Playable.PlayableFactory.fromPlaylistEntry(playlistEntry);
}
}
public Playable getNextEntry(long id) {
PlaylistEntry entry = getPlaylistItemFromId(id);
if (entry == null) {
return null;
}
String selection = PlaylistProvider.Items.PLAY_ORDER + " > ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = Integer.toString(entry.playOrder);
String sort = PlaylistProvider.Items.PLAY_ORDER + " asc";
PlaylistEntry playlistEntry = retrievePlaylistItem(selection,
selectionArgs, null);
if (playlistEntry == null) {
return null;
} else {
return Playable.PlayableFactory.fromPlaylistEntry(playlistEntry);
}
}
private void updateItemOrder(long id, int newOrder) {
Uri update = ContentUris.withAppendedId(PlaylistProvider.CONTENT_URI, id);
ContentValues values = new ContentValues();
values.put(Items.PLAY_ORDER, newOrder);
contentResolver.update(update, values, null, null);
applicationContext.sendBroadcast(new Intent(PLAYLIST_CHANGED));
}
synchronized public void move(int from, int to) {
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI,
null, null, null, PlaylistProvider.Items.PLAY_ORDER + " ASC");
int itemCt = c.getCount();
if (from < 0 || from >= itemCt || from == to) {
return;
}
if (to < 0) {
to = 0;
} else if (to >= itemCt) {
to = itemCt - 1;
}
if (c.moveToFirst()) {
do {
long id = (long) c.getInt(c.getColumnIndex(PlaylistProvider
.Items._ID));
int order = c.getInt(c.getColumnIndex(PlaylistProvider.Items.PLAY_ORDER));
if (order == from) {
updateItemOrder(id, to);
} else {
if ((order >= from && order <= to) ||
(order >= to && order <= from)) {
updateItemOrder(id, from > to ? order + 1 : order - 1);
}
}
} while (c.moveToNext());
}
c.close();
}
public void clearAll() {
contentResolver.delete(PlaylistProvider.CONTENT_URI, null, null);
Intent playlistChanged = new Intent(PLAYLIST_CHANGED);
playlistChanged.putExtra(PLAYLIST_CHANGE, PLAYLIST_CLEAR);
applicationContext.sendBroadcast(playlistChanged);
}
public void clearPlayed() {
contentResolver.delete(PlaylistProvider.CONTENT_URI,
Items.IS_READ + "=1", null);
Intent playlistChanged = new Intent(PLAYLIST_CHANGED);
playlistChanged.putExtra(PLAYLIST_CHANGE, PLAYLIST_CLEAR);
applicationContext.sendBroadcast(playlistChanged);
}
public void delete(PlaylistEntry entry) {
contentResolver.delete(PlaylistProvider.CONTENT_URI,
Items._ID + "=?", new String[]{String.valueOf(entry.id)});
Intent playlistChanged = new Intent(PLAYLIST_CHANGED);
playlistChanged.putExtra(PLAYLIST_CHANGE, PLAYLIST_ITEM_REMOVED);
applicationContext.sendBroadcast(playlistChanged);
}
public boolean isFirstEntry(String id) {
if (id == null) {
return false;
}
PlaylistEntry entry = getPlaylistItemFromId(id);
if (entry == null) {
return false;
}
String selection = PlaylistProvider.Items.PLAY_ORDER + " < ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = Integer.toString(entry.playOrder);
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI, null,
selection, selectionArgs, null);
if (c.getCount() > 0) {
c.close();
return false;
} else {
c.close();
return true;
}
}
public boolean isLastEntry(String id) {
if (id == null) {
return false;
}
PlaylistEntry entry = getPlaylistItemFromId(id);
if (entry == null) {
return false;
}
String selection = PlaylistProvider.Items.PLAY_ORDER + " > ?";
String[] selectionArgs = new String[1];
selectionArgs[0] = Integer.toString(entry.playOrder);
Cursor c = contentResolver.query(PlaylistProvider.CONTENT_URI, null,
selection, selectionArgs, null);
if (c.getCount() > 0) {
c.close();
return false;
} else {
c.close();
return true;
}
}
}