package com.sabdroidex.activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import com.android.actionbarcompat.ActionBarActivity;
import com.sabdroidex.R;
import com.sabdroidex.adapters.SABDroidExPagerAdapter;
import com.sabdroidex.controllers.sabnzbd.SABnzbdController;
import com.sabdroidex.data.DataCache;
import com.sabdroidex.data.JSONBased;
import com.sabdroidex.data.couchpotato.MovieList;
import com.sabdroidex.data.sabnzbd.History;
import com.sabdroidex.data.sabnzbd.Queue;
import com.sabdroidex.data.sabnzbd.SabnzbdStatus;
import com.sabdroidex.data.sickbeard.FuturePeriod;
import com.sabdroidex.data.sickbeard.Shows;
import com.sabdroidex.fragments.ComingFragment;
import com.sabdroidex.fragments.HistoryFragment;
import com.sabdroidex.fragments.MoviesFragment;
import com.sabdroidex.fragments.QueueFragment;
import com.sabdroidex.fragments.ShowsFragment;
import com.sabdroidex.fragments.dialogs.DialogFragmentManager;
import com.sabdroidex.interfaces.DialogFragmentManagerHolder;
import com.sabdroidex.interfaces.UpdateableActivity;
import com.sabdroidex.utils.ImageUtils;
import com.sabdroidex.utils.ImageUtils.NoMediaChecker;
import com.sabdroidex.utils.Preferences;
import com.sabdroidex.utils.SABDroidConstants;
import com.utils.Calculator;
import com.utils.FileUtil;
import com.utils.Formatter;
import com.viewpagerindicator.TabPageIndicator;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Set;
/**
* Main SabdroidEx Activity
*/
public class SABDroidEx extends ActionBarActivity implements UpdateableActivity, DialogFragmentManagerHolder {
private static final String TAG = SABDroidEx.class.getCanonicalName();
private static String APPLICATION_VERSION;
/**
* Listener for the search text field contents.
*/
private OnQueryTextListenerCompat queryTextListener = new OnQueryTextListenerCompat() {
@Override
public boolean onQueryTextChange(String newText) {
return super.onQueryTextChange(newText);
}
@Override
public boolean onQueryTextSubmit(String query) {
System.out.println(query);
return super.onQueryTextSubmit(query);
}
};
/**
* The Fragments that will take place in the ViewPager
*/
private QueueFragment queueFragment;
private HistoryFragment historyFragment;
private ShowsFragment showsFragment;
private ComingFragment comingFragment;
private MoviesFragment moviesFragment;
private DialogFragmentManager dialogFragmentManager;
/**
* Creating the elements of the screen
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "Starting SABDroidEx");
setContentView(R.layout.header);
SharedPreferences preferences = getSharedPreferences(SABDroidConstants.PREFERENCES_KEY, 0);
Preferences.update(preferences);
dialogFragmentManager = new DialogFragmentManager(this);
try {
APPLICATION_VERSION = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
}
catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
if (!Preferences.get(Preferences.VERSION).equals(APPLICATION_VERSION)) {
Log.i(TAG, "New version detected : Opening version popup");
FileUtil.deleteFile(Preferences.DATA_CACHE);
Preferences.put(Preferences.VERSION, APPLICATION_VERSION);
Preferences.setUpNewVersion();
dialogFragmentManager.showNewVersionDialog();
}
NoMediaChecker.check(Environment.getExternalStorageDirectory().getAbsolutePath());
ImageUtils.initImageWorker(getApplicationContext());
DataCache dataCache = readCacheData();
createLists(dataCache);
}
@Override
public void onNewIntent(final Intent newIntent) {
super.onNewIntent(newIntent);
Log.v(TAG, "New Intent received : " + newIntent.getAction());
final String queryAction = newIntent.getAction();
if (Intent.ACTION_SEARCH.equals(queryAction)) {
doSearchQuery(newIntent, "onNewIntent()");
}
}
/**
* Upon start a check is made to see if we received some data to open (normally an nzb file)
*/
@Override
protected void onStart() {
final Intent intent = getIntent();
if (intent != null) {
final Uri data = intent.getData();
if (data != null) {
Log.d(TAG, "Data received : " + data.toString());
String path = "";
if (data.getScheme().equalsIgnoreCase("content")) {
Cursor cursor = getContentResolver().query(data, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
path = cursor.getString(idx);
}
}
else {
path = data.getPath();
}
intent.setData(null);
dialogFragmentManager.showAddNzbFileDialog(path);
}
}
super.onStart();
}
@Override
protected void onPause() {
saveCacheData();
super.onPause();
}
/**
* @param queryIntent
* @param entryPoint
*/
private void doSearchQuery(final Intent queryIntent, final String entryPoint) {
Bundle bundle = queryIntent.getExtras();
Set<String> keySet = bundle.keySet();
System.out.println((String) bundle.get((String) keySet.toArray()[1]));
}
/**
* When the activity is stopped the status is saved so that data stays
* available off-line if the data cache has been enabled.
*/
protected void saveCacheData() {
if (Preferences.isEnabled(Preferences.DATA_CACHE)) {
/**
* Saving data for off line use.
*/
String FILENAME = Preferences.DATA_CACHE;
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(queueFragment.getDataCache());
oos.writeObject(historyFragment.getDataCache());
oos.writeObject(showsFragment.getDataCache());
oos.writeObject(comingFragment.getDataCache());
oos.writeObject(moviesFragment.getDataCache());
oos.flush();
}
catch (Exception e) {
Log.e(TAG, " " + e.getLocalizedMessage());
}
finally {
try {
oos.close();
fos.close();
}
catch (Exception e) {
// we do not care
}
}
}
super.onStop();
}
/**
* This method retrieves the data stored in the cache file.
*
* @return a DataCache object
*/
private DataCache readCacheData() {
// Creating default empty data.
// This is needed if the cache is disabled or cannot be accessed in a
// way or another
DataCache dataCache = new DataCache();
// Restoring data if the cache is enabled.
if (Preferences.isEnabled(Preferences.DATA_CACHE)) {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = openFileInput(Preferences.DATA_CACHE);
ois = new ObjectInputStream(fis);
// We read every object stored in the cache file and associate
// the to the correct field
// as we do not know the order of the objects this has to be
// done.
// (the user might only have enabled couchpotato and not
// sickbeard)
for (JSONBased element = null; (element = (JSONBased) ois.readObject()) != null; ) {
if (element instanceof Queue) {
dataCache.setQueue((Queue) element);
}
if (element instanceof History) {
dataCache.setHistory((History) element);
}
if (element instanceof Shows) {
dataCache.setShows((Shows) element);
}
if (element instanceof FuturePeriod) {
dataCache.setComing((FuturePeriod) element);
}
if (element instanceof MovieList) {
dataCache.setMovies((MovieList) element);
}
}
}
catch (Exception e) {
Log.e(TAG, "Cannot restore from cache");
}
finally {
try {
ois.close();
fis.close();
}
catch (Exception e) {
// we do not care
}
}
}
return dataCache;
}
/**
*
* Creating the whole ViewPager content If possible we pre-fill with tha
* data that was stored in the cache file
*
* @param dataCache the DataCache object
*/
private void createLists(DataCache dataCache) {
// Instantiating all the fragments that are needed
updateLabels(dataCache.getQueue());
queueFragment = new QueueFragment(dataCache.getQueue());
historyFragment = new HistoryFragment(dataCache.getHistory());
if (Preferences.isEnabled(Preferences.SICKBEARD)) {
showsFragment = new ShowsFragment(dataCache.getShows());
comingFragment = new ComingFragment(dataCache.getComing());
}
if (Preferences.isEnabled(Preferences.COUCHPOTATO)) {
moviesFragment = new MoviesFragment(dataCache.getMovies());
}
// Creation of the Adapter for the pager and adding all the fragments.
SABDroidExPagerAdapter pagerAdapter = new SABDroidExPagerAdapter(getApplicationContext(), getSupportFragmentManager());
pagerAdapter.addFragment(queueFragment);
pagerAdapter.addFragment(historyFragment);
if (Preferences.isEnabled(Preferences.SICKBEARD)) {
pagerAdapter.addFragment(showsFragment);
pagerAdapter.addFragment(comingFragment);
}
if (Preferences.isEnabled(Preferences.COUCHPOTATO)) {
pagerAdapter.addFragment(moviesFragment);
}
// Setting the adapter to the ViewPager and linking the Indicator to the
// pager.
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
pager.setPageMargin(5);
TabPageIndicator tabPageIndicator = (TabPageIndicator) findViewById(R.id.indicator);
tabPageIndicator.setViewPager(pager);
}
/**
* Refreshing the queue during startup or on user request. Asks to configure
* if still not done
*/
void manualRefresh() {
if (!Preferences.isSet(Preferences.SABNZBD_URL)) {
dialogFragmentManager.showSetupDialog();
return;
}
queueFragment.manualRefreshQueue();
historyFragment.manualRefreshHistory();
if (Preferences.isSet(Preferences.SICKBEARD_URL) && Preferences.isEnabled(Preferences.SICKBEARD)) {
if (showsFragment != null) {
showsFragment.manualRefreshShows();
}
if (comingFragment != null) {
comingFragment.manualRefreshComing();
}
}
if (Preferences.isSet(Preferences.COUCHPOTATO_URL) && Preferences.isEnabled(Preferences.COUCHPOTATO)) {
if (moviesFragment != null) {
moviesFragment.manualRefreshMovies();
}
}
getActionBarHelper().setRefreshActionItemState(true);
}
/**
* This method is used to refresh the contents of the status panel.
*/
@Override
public void updateLabels(SabnzbdStatus status) {
if (status == null) {
return;
}
try {
Double mbleft = Double.valueOf(status.getMbLeft());
Double kbpersec = Double.valueOf(status.getKbPerSec());
String mb = status.getMb();
String diskspace2 = status.getDiskSpace2();
((TextView) findViewById(R.id.freeSpace)).setText(Formatter.formatFull(diskspace2) + " " + getString(R.string.header_free_unit));
((TextView) findViewById(R.id.headerDownloaded)).setText(Formatter.formatShort(mbleft) + " / " + Formatter.formatShort(Double.parseDouble(mb)) + " MB");
((TextView) findViewById(R.id.headerSpeed)).setText(Formatter.formatShort(kbpersec) + " " + getString(R.string.header_speed_unit));
((TextView) findViewById(R.id.headerEta)).setText(Calculator.calculateETA(mbleft, kbpersec));
}
catch (Exception exception) {
Log.w(TAG, "Error Updating Labels");
}
}
/**
* This method is used to set the refresh button as active or not
*/
@Override
public void updateState(boolean showAsUpdate) {
getActionBarHelper().setRefreshActionItemState(showAsUpdate);
}
/**
* Setting up the Search View
*
* @param menu
*
* private void setupSearchView(Menu menu) { // Place an action
* bar item for searching. if (Build.VERSION.SDK_INT >=
* Build.VERSION_CODES.ICE_CREAM_SANDWICH) { MenuItem searchItem
* = menu.findItem(R.id.menu_search);
* searchItem.setShowAsActionFlags
* (MenuItem.SHOW_AS_ACTION_IF_ROOM |
* MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); } View
* searchView =
* SearchViewCompat.newSearchView(getApplicationContext()); if
* (searchView != null) {
* SearchViewCompat.setOnQueryTextListener(searchView,
* queryTextListener); MenuItem item =
* menu.findItem(R.id.menu_search);
* MenuItemCompat.setActionView(item, searchView); } }
*/
/**
* This creates the menu items as they will be by default
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main, menu);
// setupSearchView(menu);
return super.onCreateOptionsMenu(menu);
}
/**
* This is called each time the Menu Button or Menu UI Element is pressed.
* It allows to update the menu according to what we need
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (SABnzbdController.paused) {
menu.findItem(R.id.menu_play_pause).setTitle(R.string.menu_resume);
menu.findItem(R.id.menu_play_pause).setIcon(android.R.drawable.ic_media_play);
}
else {
menu.findItem(R.id.menu_play_pause).setTitle(R.string.menu_pause);
menu.findItem(R.id.menu_play_pause).setIcon(android.R.drawable.ic_media_pause);
}
if (!Debug.isDebuggerConnected()) {
menu.findItem(R.id.menu_clear).setVisible(true);
}
return super.onPrepareOptionsMenu(menu);
}
/**
* Handles item selections in the Menu
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_refresh:
manualRefresh();
break;
case R.id.menu_settings:
showSettings();
break;
case R.id.menu_play_pause:
pauseResume();
break;
case R.id.menu_add_nzb:
showAddDialog();
break;
case R.id.menu_search:
onSearchRequested();
break;
case R.id.menu_clear:
clearVersion();
break;
case R.id.menu_server_settings:
showServerSettings();
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Shows the Dialog to choose an Add option (Nzb, Show ...)
*/
private void showAddDialog() {
dialogFragmentManager.showAddDialog();
}
/**
* Clears the application version. For testing purposes.
*/
private void clearVersion() {
Preferences.put(Preferences.VERSION, "");
deleteFile(Preferences.DATA_CACHE);
}
/**
* Displaying the application settings
*/
private void showSettings() {
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
}
/**
* Displaying the Sabnzbd server settings
*/
private void showServerSettings() {
startActivity(new Intent(getApplicationContext(), ServerSettingsActivity.class));
}
/**
* This method invokes either the pause or resume functionality of sabnzbd
* regarding of the known status
*/
private void pauseResume() {
queueFragment.pauseResumeQueue();
}
@Override
public DialogFragmentManager getDialogFragmentManager() {
return dialogFragmentManager;
}
}