<commit_before>package net.x4a42.volksempfaenger.ui;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import net.x4a42.volksempfaenger.R;
import net.x4a42.volksempfaenger.Utils;
import net.x4a42.volksempfaenger.data.DatabaseHelper;
import net.x4a42.volksempfaenger.net.DescriptionImageDownloader;
import net.x4a42.volksempfaenger.service.DownloadService;
import net.x4a42.volksempfaenger.service.PlaybackService;
import net.x4a42.volksempfaenger.service.PlaybackService.PlaybackBinder;
import net.x4a42.volksempfaenger.service.PlaybackService.PlayerListener;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

public class ViewEpisodeActivity extends BaseActivity implements
		OnClickListener, OnSeekBarChangeListener, ServiceConnection,
		PlayerListener {
	private SeekBar seekBar;
	private TextView textDuration;
	private TextView textPosition;
	private ImageButton buttonPlay, buttonBack, buttonForward;
	private boolean bound = false;
	private PlaybackService service;
	private boolean startedPlaying = false;
	private Handler updateHandler;

	private long id;
	private DatabaseHelper dbHelper;

	private ImageView podcastLogo;
	private TextView podcastTitle;
	private TextView podcastDescription;
	private TextView episodeTitle;
	private TextView episodeDescription;

	private String descriptionText;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Check if there is an ID
		Bundle extras = getIntent().getExtras();
		if (extras == null) {
			finish();
			return;
		}
		id = extras.getLong("id");
		if (id <= 0) {
			finish();
			return;
		}

		setContentView(R.layout.view_episode);

		dbHelper = DatabaseHelper.getInstance(this);

		podcastLogo = (ImageView) findViewById(R.id.podcast_logo);
		podcastTitle = (TextView) findViewById(R.id.podcast_title);
		podcastDescription = (TextView) findViewById(R.id.podcast_description);
		episodeTitle = (TextView) findViewById(R.id.episode_title);
		episodeDescription = (TextView) findViewById(R.id.episode_description);
		seekBar = (SeekBar) findViewById(R.id.seekBar1);
		buttonPlay = (ImageButton) findViewById(R.id.button_play);
		buttonBack = (ImageButton) findViewById(R.id.button_back);
		buttonForward = (ImageButton) findViewById(R.id.button_forward);
		textDuration = (TextView) findViewById(R.id.text_duration);
		textPosition = (TextView) findViewById(R.id.text_position);

		episodeDescription.setMovementMethod(LinkMovementMethod.getInstance());

		seekBar.setEnabled(false);
		buttonBack.setEnabled(false);
		buttonForward.setEnabled(false);

		buttonPlay.setOnClickListener(this);
		buttonBack.setOnClickListener(this);
		buttonForward.setOnClickListener(this);
		seekBar.setOnSeekBarChangeListener(this);

		Intent intent = new Intent(this, PlaybackService.class);
		startService(intent);
		bindService(intent, this, Context.BIND_AUTO_CREATE);
		updateHandler = new Handler();
	}

	@Override
	public void onPause() {
		super.onResume();
		updateHandler.removeCallbacks(updateSliderTask);
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		if (service != null && service.isPlaying()) {
			updateHandler.post(updateSliderTask);
		}

		Cursor c;

		// Update episode information

		c = dbHelper.getReadableDatabase().query(DatabaseHelper.Episode._TABLE,
				null, String.format("%s = ?", DatabaseHelper.Episode.ID),
				new String[] { String.valueOf(id) }, null, null, null);

		if (!c.moveToFirst()) {
			// ID does not exist
			finish();
			return;
		}

		long podcastId = c.getLong(c
				.getColumnIndex(DatabaseHelper.Episode.PODCAST));
		episodeTitle.setText(c.getString(c
				.getColumnIndex(DatabaseHelper.Episode.TITLE)));
		descriptionText = Utils.normalizeString(c.getString(c
				.getColumnIndex(DatabaseHelper.Episode.DESCRIPTION)));
		if (imageUrlMap == null) {
			episodeDescription.setText(Html.fromHtml(descriptionText,
					new ImageGetterPrefetch(), null));
			new ImagePrefetchTask().execute();
		} else {
			episodeDescription.setText(Html.fromHtml(descriptionText,
					new ImageGetter(), null));
		}

		c.close();

		File podcastLogoFile = Utils.getPodcastLogoFile(this, podcastId);
		if (podcastLogoFile.isFile()) {
			Bitmap podcastLogoBitmap = BitmapFactory.decodeFile(podcastLogoFile
					.getAbsolutePath());
			podcastLogo.setImageBitmap(podcastLogoBitmap);
		}

		// Update podcast information
		c = dbHelper.getReadableDatabase().query(DatabaseHelper.Podcast._TABLE,
				null, String.format("%s = ?", DatabaseHelper.Podcast.ID),
				new String[] { String.valueOf(podcastId) }, null, null, null,
				"1");

		if (!c.moveToFirst()) {
			// ID does not exist
			finish();
			return;
		}

		podcastTitle.setText(c.getString(c
				.getColumnIndex(DatabaseHelper.Podcast.TITLE)));
		podcastDescription.setText(c.getString(c
				.getColumnIndex(DatabaseHelper.Podcast.DESCRIPTION)));

		c.close();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		if (service != null) {
			unbindService(this);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.view_episode, menu);
		addGlobalMenu(menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		Cursor cursor;
		switch (item.getItemId()) {
		case R.id.item_download:
			intent = new Intent(this, DownloadService.class);
			cursor = dbHelper.getReadableDatabase().query(
					DatabaseHelper.Enclosure._TABLE,
					new String[] { DatabaseHelper.Enclosure.ID },
					String.format("%s = ?", DatabaseHelper.Enclosure.EPISODE),
					new String[] { String.valueOf(id) }, null, null, null);
			long[] v = null;
			if (cursor.getCount() != 0) {
				v = new long[cursor.getCount()];
				for (int i = 0; i < v.length; i++) {
					cursor.moveToNext();
					v[i] = cursor.getLong(0);
				}
			}
			cursor.close();
			intent.putExtra("id", v);
			startService(intent);
			Toast.makeText(this, R.string.message_download_queued,
					Toast.LENGTH_SHORT).show();
			return true;

		case R.id.item_mark_listened:
			return true;

		case R.id.item_delete:
			// TODO: confirmation dialog, AsyncTask
			cursor = dbHelper.getReadableDatabase().query(
					DatabaseHelper.Enclosure._TABLE,
					new String[] { DatabaseHelper.Enclosure.ID,
							DatabaseHelper.Enclosure.FILE },
					String.format("%s = ?", DatabaseHelper.Enclosure.EPISODE),
					new String[] { String.valueOf(id) }, null, null, null);
			ContentValues values = new ContentValues();
			while (cursor.moveToNext()) {
				String filename = cursor.getString(1);
				try {
					if (filename != null) {
						File f = new File(new URI(filename));
						if (f.isFile()) {
							f.delete();
						}
					}
				} catch (URISyntaxException e) {
					Log.w(getClass().getSimpleName(), "Exception handled", e);
				}
				values.put(DatabaseHelper.Enclosure.FILE, (String) null);
				values.put(DatabaseHelper.Enclosure.STATE,<commit_msg>ViewEpisodeActivity: Implemented "mark as listened" feature.<commit_after>package net.x4a42.volksempfaenger.ui;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import net.x4a42.volksempfaenger.R;
import net.x4a42.volksempfaenger.Utils;
import net.x4a42.volksempfaenger.data.DatabaseHelper;
import net.x4a42.volksempfaenger.net.DescriptionImageDownloader;
import net.x4a42.volksempfaenger.service.DownloadService;
import net.x4a42.volksempfaenger.service.PlaybackService;
import net.x4a42.volksempfaenger.service.PlaybackService.PlaybackBinder;
import net.x4a42.volksempfaenger.service.PlaybackService.PlayerListener;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

public class ViewEpisodeActivity extends BaseActivity implements
		OnClickListener, OnSeekBarChangeListener, ServiceConnection,
		PlayerListener {
	private SeekBar seekBar;
	private TextView textDuration;
	private TextView textPosition;
	private ImageButton buttonPlay, buttonBack, buttonForward;
	private boolean bound = false;
	private PlaybackService service;
	private boolean startedPlaying = false;
	private Handler updateHandler;

	private long id;
	private DatabaseHelper dbHelper;

	private ImageView podcastLogo;
	private TextView podcastTitle;
	private TextView podcastDescription;
	private TextView episodeTitle;
	private TextView episodeDescription;

	private String descriptionText;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Check if there is an ID
		Bundle extras = getIntent().getExtras();
		if (extras == null) {
			finish();
			return;
		}
		id = extras.getLong("id");
		if (id <= 0) {
			finish();
			return;
		}

		setContentView(R.layout.view_episode);

		dbHelper = DatabaseHelper.getInstance(this);

		podcastLogo = (ImageView) findViewById(R.id.podcast_logo);
		podcastTitle = (TextView) findViewById(R.id.podcast_title);
		podcastDescription = (TextView) findViewById(R.id.podcast_description);
		episodeTitle = (TextView) findViewById(R.id.episode_title);
		episodeDescription = (TextView) findViewById(R.id.episode_description);
		seekBar = (SeekBar) findViewById(R.id.seekBar1);
		buttonPlay = (ImageButton) findViewById(R.id.button_play);
		buttonBack = (ImageButton) findViewById(R.id.button_back);
		buttonForward = (ImageButton) findViewById(R.id.button_forward);
		textDuration = (TextView) findViewById(R.id.text_duration);
		textPosition = (TextView) findViewById(R.id.text_position);

		episodeDescription.setMovementMethod(LinkMovementMethod.getInstance());

		seekBar.setEnabled(false);
		buttonBack.setEnabled(false);
		buttonForward.setEnabled(false);

		buttonPlay.setOnClickListener(this);
		buttonBack.setOnClickListener(this);
		buttonForward.setOnClickListener(this);
		seekBar.setOnSeekBarChangeListener(this);

		Intent intent = new Intent(this, PlaybackService.class);
		startService(intent);
		bindService(intent, this, Context.BIND_AUTO_CREATE);
		updateHandler = new Handler();
	}

	@Override
	public void onPause() {
		super.onResume();
		updateHandler.removeCallbacks(updateSliderTask);
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		if (service != null && service.isPlaying()) {
			updateHandler.post(updateSliderTask);
		}

		Cursor c;

		// Update episode information

		c = dbHelper.getReadableDatabase().query(DatabaseHelper.Episode._TABLE,
				null, String.format("%s = ?", DatabaseHelper.Episode.ID),
				new String[] { String.valueOf(id) }, null, null, null);

		if (!c.moveToFirst()) {
			// ID does not exist
			finish();
			return;
		}

		long podcastId = c.getLong(c
				.getColumnIndex(DatabaseHelper.Episode.PODCAST));
		episodeTitle.setText(c.getString(c
				.getColumnIndex(DatabaseHelper.Episode.TITLE)));
		descriptionText = Utils.normalizeString(c.getString(c
				.getColumnIndex(DatabaseHelper.Episode.DESCRIPTION)));
		if (imageUrlMap == null) {
			episodeDescription.setText(Html.fromHtml(descriptionText,
					new ImageGetterPrefetch(), null));
			new ImagePrefetchTask().execute();
		} else {
			episodeDescription.setText(Html.fromHtml(descriptionText,
					new ImageGetter(), null));
		}

		c.close();

		File podcastLogoFile = Utils.getPodcastLogoFile(this, podcastId);
		if (podcastLogoFile.isFile()) {
			Bitmap podcastLogoBitmap = BitmapFactory.decodeFile(podcastLogoFile
					.getAbsolutePath());
			podcastLogo.setImageBitmap(podcastLogoBitmap);
		}

		// Update podcast information
		c = dbHelper.getReadableDatabase().query(DatabaseHelper.Podcast._TABLE,
				null, String.format("%s = ?", DatabaseHelper.Podcast.ID),
				new String[] { String.valueOf(podcastId) }, null, null, null,
				"1");

		if (!c.moveToFirst()) {
			// ID does not exist
			finish();
			return;
		}

		podcastTitle.setText(c.getString(c
				.getColumnIndex(DatabaseHelper.Podcast.TITLE)));
		podcastDescription.setText(c.getString(c
				.getColumnIndex(DatabaseHelper.Podcast.DESCRIPTION)));

		c.close();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		if (service != null) {
			unbindService(this);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.view_episode, menu);
		addGlobalMenu(menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		Cursor cursor;
		ContentValues values = new ContentValues();
		switch (item.getItemId()) {
		case R.id.item_download:
			intent = new Intent(this, DownloadService.class);
			cursor = dbHelper.getReadableDatabase().query(
					DatabaseHelper.Enclosure._TABLE,
					new String[] { DatabaseHelper.Enclosure.ID },
					String.format("%s = ?", DatabaseHelper.Enclosure.EPISODE),
					new String[] { String.valueOf(id) }, null, null, null);
			long[] v = null;
			if (cursor.getCount() != 0) {
				v = new long[cursor.getCount()];
				for (int i = 0; i < v.length; i++) {
					cursor.moveToNext();
					v[i] = cursor.getLong(0);
				}
			}
			cursor.close();
			intent.putExtra("id", v);
			startService(intent);
			Toast.makeText(this, R.string.message_download_queued,
					Toast.LENGTH_SHORT).show();
			return true;

		case R.id.item_mark_listened:
			values.put(DatabaseHelper.Enclosure.STATE, DatabaseHelper.Enclosure.STATE_LISTENED);
			values.put(DatabaseHelper.Enclosure.DURATION_LISTENED, 0);
			dbHelper.getWritableDatabase().update(
					DatabaseHelper.Enclosure._TABLE, values,
					String.format("%s = ?", DatabaseHelper.Enclosure.EPISODE),
					new String[] { String.valueOf(id) });
			return true;

		case R.id.item_delete:
			// TODO: confirmation dialog, AsyncTask
			cursor = dbHelper.getReadableDatabase().query(
					DatabaseHelper.Enclosure._TABLE,
					new String[] { DatabaseHelper.Enclosure.ID,
							DatabaseHelper.Enclosure.FILE },
					String.format("%s = ?", DatabaseHelper.Enclosure.EPISODE),
					new String[] { String.valueOf(id) }, null, null, null);
			while (cursor.moveToNext()) {
				String filename = cursor.getString(1);
				try {
					if (filename != null) {
						File f = new File(new URI(filename));
						if (f.isFile()) {
							f.delete();
						}
					}
				} catch (URISyntaxException e) {
					Log.w(getClass().getSimpleName(), "Exception handled", e);
				}
				values.put(DatabaseHelper.Enclosure.FILE, (String) null);
				values.put(DatabaseHelper.Enclosure.STATE,
{'fraction_non_alphanumeric': 0.11759041944996089, 'fraction_numerical': 0.004152374074742733, 'mean_word_length': 4.810489510489511, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 23, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '370982', 'n_tokens_mistral': 5860, 'n_tokens_neox': 5089, 'n_words': 988}