package com.vaguehope.onosendai.ui;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ColumnTitleStrip;
import android.support.v4.view.ColumnTitleStrip.ColumnClickListener;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast;

import com.vaguehope.onosendai.C;
import com.vaguehope.onosendai.R;
import com.vaguehope.onosendai.config.Account;
import com.vaguehope.onosendai.config.Column;
import com.vaguehope.onosendai.config.Config;
import com.vaguehope.onosendai.config.InternalColumnType;
import com.vaguehope.onosendai.config.Prefs;
import com.vaguehope.onosendai.images.HybridBitmapCache;
import com.vaguehope.onosendai.images.ImageLoadRequest;
import com.vaguehope.onosendai.images.ImageLoader;
import com.vaguehope.onosendai.images.ImageLoaderUtils;
import com.vaguehope.onosendai.model.ScrollState;
import com.vaguehope.onosendai.model.Tweet;
import com.vaguehope.onosendai.notifications.Notifications;
import com.vaguehope.onosendai.provider.ProviderMgr;
import com.vaguehope.onosendai.provider.ProviderMgr.ProviderMgrProvider;
import com.vaguehope.onosendai.storage.DbClient;
import com.vaguehope.onosendai.storage.DbInterface;
import com.vaguehope.onosendai.storage.DbProvider;
import com.vaguehope.onosendai.ui.LocalSearchDialog.OnTweetListener;
import com.vaguehope.onosendai.ui.pref.AdvancedPrefFragment;
import com.vaguehope.onosendai.ui.pref.FetchingPrefFragment;
import com.vaguehope.onosendai.ui.pref.FiltersPrefFragment;
import com.vaguehope.onosendai.ui.pref.OsPreferenceActivity;
import com.vaguehope.onosendai.ui.pref.UiPrefFragment;
import com.vaguehope.onosendai.update.AlarmReceiver;
import com.vaguehope.onosendai.update.BatteryNotify;
import com.vaguehope.onosendai.update.UpdateService;
import com.vaguehope.onosendai.util.BatteryHelper;
import com.vaguehope.onosendai.util.DialogHelper;
import com.vaguehope.onosendai.util.LogWrapper;
import com.vaguehope.onosendai.util.MultiplexingOnPageChangeListener;
import com.vaguehope.onosendai.util.NetHelper;
import com.vaguehope.onosendai.util.exec.ExecUtils;
import com.vaguehope.onosendai.util.exec.ExecutorEventListener;
import com.vaguehope.onosendai.util.exec.TrackingAsyncTask;
import com.vaguehope.onosendai.widget.SidebarAwareViewPager;

public class MainActivity extends FragmentActivity implements ImageLoader, DbProvider, ProviderMgrProvider, OnSharedPreferenceChangeListener {

	public static final String ARG_FOCUS_COLUMN_ID = "focus_column_id";

	private static final LogWrapper LOG = new LogWrapper("MA");

	private Prefs prefs;
	private Config conf;
	private ProviderMgr providerMgr;
	private HybridBitmapCache imageCache;
	private ExecutorStatus executorStatus;
	private ExecutorService localEs;
	private ExecutorService netEs;
	private MessageHandler msgHandler;
	private boolean columnsRtl;

	private ColumnTitleStrip columnTitleStrip;
	private SidebarAwareViewPager viewPager;
	private VisiblePageSelectionListener pageSelectionListener;
	private final SparseArray<TweetListFragment> activePages = new SparseArray<TweetListFragment>();

	private boolean prefsChanged = false;

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

		this.prefs = new Prefs(getBaseContext());
		if (!this.prefs.isConfigured()) {
			startActivity(new Intent(getApplicationContext(), SetupActivity.class));
			finish();
			return;
		}
		this.prefs.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.activity_main);

		try {
			this.conf = this.prefs.asConfig();
		}
		catch (final Exception e) { // No point continuing if any exception.
			LOG.wtf("Unparsable config.", e);
			DialogHelper.alertAndClose(this, e);
			return;
		}

		this.imageCache = new HybridBitmapCache(this, C.MAX_MEMORY_IMAGE_CACHE);

		if (this.prefs.getSharedPreferences().getBoolean(AdvancedPrefFragment.KEY_THREAD_INSPECTOR, false)) {
			final TextView jobStatus = (TextView) findViewById(R.id.jobStatus);
			jobStatus.setVisibility(View.VISIBLE);
			this.executorStatus = new ExecutorStatus(jobStatus);
		}

		this.localEs = ExecUtils.newBoundedCachedThreadPool(C.LOCAL_MAX_THREADS, new LogWrapper("LES"), this.executorStatus);
		this.netEs = ExecUtils.newBoundedCachedThreadPool(C.NET_MAX_THREADS, new LogWrapper("NES"), this.executorStatus);
		this.msgHandler = new MessageHandler(this);

		final float columnWidth = UiPrefFragment.readColumnWidth(this, this.prefs);
		this.columnsRtl = UiPrefFragment.readColumnsRtl(this.prefs);

		// If this becomes too memory intensive, switch to android.support.v4.app.FragmentStatePagerAdapter.
		final SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), this, columnWidth);
		this.viewPager = (SidebarAwareViewPager) findViewById(R.id.pager);
		this.pageSelectionListener = new VisiblePageSelectionListener(columnWidth);
		final MultiplexingOnPageChangeListener onPageChangeListener = new MultiplexingOnPageChangeListener(
				this.pageSelectionListener,
				new NotificationClearingPageSelectionListener(this));
		this.viewPager.setOnPageChangeListener(onPageChangeListener);
		this.viewPager.setAdapter(sectionsPagerAdapter);
		if (!showPageFromIntent(getIntent())) {
			if (this.columnsRtl) {
				gotoPage(0);
			}
			else {
				onPageChangeListener.onPageSelected(this.viewPager.getCurrentItem());
			}
		}

		final ActionBar ab = getActionBar();
		ab.setDisplayShowHomeEnabled(true);
		ab.setHomeButtonEnabled(true);
		ab.setDisplayShowTitleEnabled(false);
		ab.setDisplayShowCustomEnabled(true);

		this.columnTitleStrip = new ColumnTitleStrip(ab.getThemedContext());
		this.columnTitleStrip.setViewPager(this.viewPager);
		this.columnTitleStrip.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
		this.columnTitleStrip.setColumnClickListener(new TitleClickListener(this));
		ab.setCustomView(this.columnTitleStrip);

		AlarmReceiver.configureAlarms(this);
		new CheckBackgroundUpdatesRunning(this, this.executorStatus).executeOnExecutor(this.localEs);
	}

	@Override
	protected void onNewIntent (final Intent intent) {
		super.onNewIntent(intent);
		setIntent(intent);
		showPageFromIntent(intent);
	}

	@Override
	public void onResume () {
		super.onResume();
		resumeDb();

		if (this.prefsChanged) {
			finish();
			startActivity(getIntent());
			return;
		}

		startBgFetchVisibleColumnsIfConfigured();
	}

	@Override
	protected void onDestroy () {
		stopBgFetchVisibleColumns();
		if (this.prefs != null) this.prefs.getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
		if (this.providerMgr != null) this.providerMgr.shutdown();
		if (this.imageCache != null) this.imageCache.clean();
		if (this.netEs != null) this.netEs.shutdown();
		if (this.localEs != null) this.localEs.shutdown();
		disposeDb();
		super.onDestroy();
	}

	@Override
	public void onSharedPreferenceChanged (final SharedPreferences sharedPreferences, final String key) {
		this.prefsChanged = true;
	}

//	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	private final CountDownLatch dbReadyLatch = new CountDownLatch(1);
	private DbClient bndDb;

	private void resumeDb () {
		if (this.bndDb == null) {
			LOG.d("Binding DB service...");
			final CountDownLatch latch = this.dbReadyLatch;
			final LogWrapper log = LOG;
			this.bndDb = new DbClient(this, LOG.getPrefix(), new Runnable() {
				@Override
				public void run () {
					latch.countDown();
					log.d("DB service bound.");
					setProviderMgr(new ProviderMgr(getDb()));
				}
			});
		}
	}

	private void disposeDb () {
		if (this.bndDb != null) this.bndDb.dispose();
	}

	private boolean waitForDbReady () {
		boolean dbReady = false;
		try {
			dbReady = this.dbReadyLatch.await(C.DB_CONNECT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
		}
		catch (final InterruptedException e) {/**/}
		if (!dbReady) LOG.e("Not updateing: Time out waiting for DB service to connect.");
		return dbReady;
	}

	@Override
	public DbInterface getDb () {
		final DbClient d = this.bndDb;
		if (d == null) return null;
		return d.getDb();
	}

//	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	Prefs getPrefs () {
		return this.prefs;
	}

	boolean isShowFiltered () {
		return this.prefs.getSharedPreferences().getBoolean(FiltersPrefFragment.KEY_SHOW_FILTERED, false);
	}

	Config getConf () {
		return this.conf;
	}

	public ExecutorEventListener getExecutorEventListener () {
		return this.executorStatus;
	}

	public Executor getLocalEs () {
		return this.localEs;
	}

	public Executor getNetEs () {
		return this.netEs;
	}

	@Override
	public ProviderMgr getProviderMgr () {
		if (!waitForDbReady()) throw new IllegalStateException("DB not bound.");
		return this.providerMgr;
	}

	void setProviderMgr (final ProviderMgr providerMgr) {
		this.providerMgr = providerMgr;
	}

	public HybridBitmapCache getImageCache () {
		return this.imageCache;
	}

	@Override
	public void loadImage (final ImageLoadRequest req) {
		ImageLoaderUtils.loadImage(this.imageCache, req, this.localEs, this.netEs, this.executorStatus);
	}

	public int convertPagePosition (final int argPosition) {
		if (!this.columnsRtl) return argPosition;
		final int count = this.viewPager.getAdapter().getCount();
		if (count < 1) return argPosition;
		return count - 1 - argPosition;
	}

	public boolean gotoPage (final int argPosition) {
		final int position = convertPagePosition(argPosition);
		if (this.viewPager.getCurrentItem() != position) {
			this.viewPager.setCurrentItem(position, false);
			return true;
		}
		return false;
	}

	public void gotoTweet (final int colId, final Tweet tweet) {
		gotoPage(getConf().getColumnPositionById(colId));
		final TweetListFragment page = getActivePageById(colId);
		if (page != null) page.scrollToTweet(tweet);
	}

	private boolean showPageFromIntent (final Intent intent) {
		if (intent.hasExtra(ARG_FOCUS_COLUMN_ID)) {
			final int pos = this.conf.getColumnPositionById(intent.getIntExtra(ARG_FOCUS_COLUMN_ID, 0));
			if (pos >= 0) return gotoPage(pos);
		}
		return false;
	}

	protected TweetListFragment getActivePageById (final int colId) {
		return this.activePages.get(colId);
	}

	protected void onFragmentResumed (final int columnId, final TweetListFragment page) {
		this.activePages.put(columnId, page);
	}

	protected void onFragmentPaused (final int columnId) {
		this.activePages.remove(columnId);
	}

	protected ScrollState getColumnScroll (final int columnId) {
		final TweetListFragment page = getActivePageById(columnId);
		if (page == null) return null;
		return page.getCurrentScroll();
	}

	@Override
	public void onBackPressed () {
		for (int i = 0; i < this.activePages.size(); i++) {
			final TweetListFragment page = this.activePages.valueAt(i);
			if (this.pageSelectionListener.isVisible(convertPagePosition(page.getColumnPosition())) && page.getSidebar().closeSidebar()) return;
		}
		super.onBackPressed();
	}

	public List<Column> getVisibleColumns () {
		final List<Column> ret = new ArrayList<Column>();
		for (int i = 0; i < this.conf.getColumnCount(); i++) {
			if (this.pageSelectionListener.isVisible(convertPagePosition(i))) ret.add(this.conf.getColumnByPosition(i));
		}
		return ret;
	}

	public int[] getVisibleColumnIds () {
		final List<Column> pages = getVisibleColumns();
		final int[] ret = new int[pages.size()];
		for (int i = 0; i < pages.size(); i++) {
			ret[i] = pages.get(i).getId();
		}
		return ret;
	}

//	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	@Override
	public boolean onCreateOptionsMenu (final Menu menu) {
		getMenuInflater().inflate(R.menu.listmenu, menu);

		/* FIXME apparently this.pageSelectionListener can sometimes be null here.
		 * Reported on Galaxy S5 stock firmware v6.0.1.
		 */
		if (this.pageSelectionListener != null && this.pageSelectionListener.getVisiblePageCount() > 1) {
			menu.findItem(R.id.mnuRefreshColumnNow).setTitle(R.string.main_menu_refresh_visible_columns);
		}

		return true;
	}

	@Override
	public boolean onOptionsItemSelected (final MenuItem item) {
		switch (item.getItemId()) {
			case android.R.id.home:
				new GotoMenu(this).onClick(this.columnTitleStrip); // TODO FIXME position it correctly under icon.
				return true;
			case R.id.mnuPost:
				showPost();
				return true;
			case R.id.mnuOutbox:
				showOutbox();
				return true;
			case R.id.mnuRefreshColumnNow:
				scheduleRefreshInteractive(getVisibleColumnIds());
				return true;
			case R.id.mnuRefreshAllNow:
				scheduleRefreshInteractive();
				return true;
			case R.id.mnuPreferences:
				startActivity(new Intent(this, OsPreferenceActivity.class));
				return true;
			case R.id.mnuLocalSearch:
				showLocalSearch();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	private void showPost () {
		showPost(getVisibleColumns(), null, -1);
	}

	protected void showPost (final Collection<Column> cols, final String initialBody, final int cursorPosition) {
		final Set<String> acIds = Column.uniqAccountIds(cols);
		final String accountId = acIds.size() == 1 ? acIds.iterator().next() : null;
		showPost(this.conf.getAccount(accountId), initialBody, cursorPosition);
	}

	private void showPost (final Account account, final String initialBody, final int cursorPosition) {
		final Intent intent = new Intent(this, PostActivity.class);
		if (account != null) intent.putExtra(PostActivity.ARG_ACCOUNT_ID, account.getId());
		if (initialBody != null) intent.putExtra(PostActivity.ARG_BODY, initialBody);
		if (cursorPosition >= 0) intent.putExtra(PostActivity.ARG_BODY_CURSOR_POSITION, cursorPosition);
		startActivity(intent);
	}

	private void showOutbox () {
		startActivity(new Intent(this, OutboxActivity.class));
	}

	/**
	 * return true if scheduled.
	 */
	protected boolean scheduleRefreshInteractive (final int... columnIds) {
		if (!NetHelper.connectionPresent(this)) {
			DialogHelper.alert(this, getString(R.string.main_no_internet_connection_available));
			return false;
		}
		scheduleRefresh(true, columnIds);
		return true;
	}

	protected void scheduleRefreshBackground (final int... columnIds) {
		if (!NetHelper.connectionPresent(this)) {
			Toast.makeText(this, R.string.main_no_internet_connection_available, Toast.LENGTH_SHORT).show();
			return;
		}
		scheduleRefresh(false, columnIds);
	}

	private void scheduleRefresh (final boolean manual, final int... columnIds) {
		final Intent intent = new Intent(this, UpdateService.class);
		if (manual) intent.putExtra(UpdateService.ARG_IS_MANUAL, true);
		if (columnIds != null && columnIds.length > 0) intent.putExtra(UpdateService.ARG_COLUMN_IDS, columnIds);
		startService(intent);

		if (manual) {
			final int count = columnIds == null ? 0 : columnIds.length;
			final String msg = count > 0
					? String.format(getString(R.string.main_refresh_columns_requested), count)
					: getString(R.string.main_refresh_all_columns_requested);
			Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
		}
	}

	public void showLocalSearch () {
		showLocalSearch(null);
	}

	public void showLocalSearch (final String searchTerms) {
		LocalSearchDialog.show(this, getConf(), this, this, new OnTweetListener() {
			@Override
			public void onTweet (final int colId, final Tweet tweet) {
				MainActivity.this.gotoTweet(colId, tweet);
			}
		}, searchTerms);
	}

//	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	protected void setTempColumnTitle (final int argPosition, final String title) {
		final int position = convertPagePosition(argPosition);
		this.columnTitleStrip.setTempColumnTitle(position, title);
	}

	private int progressIndicatorCounter = 0;

	/**
	 * Only call on UI thread.
	 */
	protected void progressIndicator (final boolean inProgress) {
		this.progressIndicatorCounter += (inProgress ? 1 : -1);
		setProgressBarIndeterminateVisibility(this.progressIndicatorCounter > 0);
	}

//	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	private enum Msgs {
		BG_FETCH_VISIBLE_COLUMNS;
		public static final Msgs values[] = values(); // Optimisation to avoid new array every time.
	}

	private static class MessageHandler extends Handler {

		private final WeakReference<MainActivity> parentRef;

		public MessageHandler (final MainActivity parent) {
			this.parentRef = new WeakReference<MainActivity>(parent);
		}

		@Override
		public void handleMessage (final Message msg) {
			final MainActivity parent = this.parentRef.get();
			if (parent != null) parent.msgOnUiThread(msg);
		}
	}

	protected void msgOnUiThread (final Message msg) {
		switch (Msgs.values[msg.what]) {
			case BG_FETCH_VISIBLE_COLUMNS:
				bgFetchVisibleColumns();
				break;
			default:
		}
	}

	private boolean frequentlyFetchVisibleColumns = false;

	private void startBgFetchVisibleColumnsIfConfigured () {
		if (this.frequentlyFetchVisibleColumns) return;
		this.frequentlyFetchVisibleColumns = isAnyFrequentFetchColumnsConfigured();
		if (this.frequentlyFetchVisibleColumns) {
			this.msgHandler.sendEmptyMessageDelayed(Msgs.BG_FETCH_VISIBLE_COLUMNS.ordinal(), TimeUnit.SECONDS.toMillis(C.FETCH_VISIBLE_INITIAL_SECONDS));
			LOG.i("Frequently fetch visible colunns enabled.");
		}
	}

	private void stopBgFetchVisibleColumns () {
		this.frequentlyFetchVisibleColumns = false;
	}

	private void bgFetchVisibleColumns () {
		if (!this.frequentlyFetchVisibleColumns) return;
		final int[] visibleColumnIds = getVisibleColumnIds();
		if (visibleColumnIds.length > 0) {
			scheduleRefreshBackground(visibleColumnIds);
			LOG.i("Requested fetch of visible colunns: %s.", Arrays.toString(visibleColumnIds));
		}
		else {
			LOG.i("No visible colunns to refresh refresh of: %s.", Arrays.toString(visibleColumnIds));
		}
		this.msgHandler.sendEmptyMessageDelayed(Msgs.BG_FETCH_VISIBLE_COLUMNS.ordinal(), TimeUnit.MINUTES.toMillis(C.FETCH_VISIBLE_INTERVAL_MIN));
	}

	private boolean isAnyFrequentFetchColumnsConfigured () {
		for (final Column col : this.conf.getColumns()) {
			if (col.getRefreshIntervalMins() > 0 && col.getRefreshIntervalMins() < C.FETCH_VISIBLE_THRESHOLD_MIN) return true;
		}
		return false;
	}

//	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	private static class SectionsPagerAdapter extends FragmentPagerAdapter {

		private final MainActivity host;
		private final float pageWidth;

		public SectionsPagerAdapter (final FragmentManager fm, final MainActivity host, final float pageWidth) {
			super(fm);
			this.host = host;
			this.pageWidth = pageWidth;
		}

		@Override
		public Fragment getItem (final int argPosition) {
			final int position = this.host.convertPagePosition(argPosition);
			final Column col = this.host.getConf().getColumnByPosition(position);
			final Fragment fragment = new TweetListFragment();
			final Bundle args = new Bundle();
			args.putInt(TweetListFragment.ARG_COLUMN_POSITION, position);
			args.putInt(TweetListFragment.ARG_COLUMN_ID, col.getId());
			args.putString(TweetListFragment.ARG_COLUMN_TITLE, col.getTitle());
			args.putBoolean(TweetListFragment.ARG_COLUMN_IS_LATER, InternalColumnType.LATER.matchesColumn(col));
			args.putString(TweetListFragment.ARG_COLUMN_SHOW_INLINEMEDIA, col.getInlineMediaStyle() != null ? col.getInlineMediaStyle().serialise() : null);
			args.putBoolean(TweetListFragment.ARG_SHOW_FILTERED, this.host.isShowFiltered());
			fragment.setArguments(args);
			return fragment;
		}

		@Override
		public int getCount () {
			return this.host.getConf().getColumns().size();
		}

		@Override
		public CharSequence getPageTitle (final int argPosition) {
			final int position = this.host.convertPagePosition(argPosition);
			return this.host.getConf().getColumnByPosition(position).getTitle();
		}

		@Override
		public float getPageWidth (final int position) {
			return this.pageWidth;
		}

	}

	private static class VisiblePageSelectionListener extends SimpleOnPageChangeListener {

		private int selectedPagePosition;
		private final int visiblePages;

		public VisiblePageSelectionListener (final float pageWidth) {
			this.visiblePages = (int) (1 / pageWidth);
		}

		@Override
		public void onPageSelected (final int position) {
			this.selectedPagePosition = position;
		}

		public int getVisiblePageCount () {
			return this.visiblePages;
		}

		public boolean isVisible (final int position) {
			return position >= this.selectedPagePosition && position < this.selectedPagePosition + this.visiblePages;
		}

	}

	private static class TitleClickListener implements ColumnClickListener {

		private final MainActivity host;

		public TitleClickListener (final MainActivity host) {
			this.host = host;
		}

		@Override
		public void onColumnTitleClick (final int argPosition) {
			final int position = this.host.convertPagePosition(argPosition);
			final Column col = this.host.getConf().getColumnByPosition(position);
			if (col == null) return;
			final TweetListFragment page = this.host.getActivePageById(col.getId());
			if (page == null) return;
			page.scrollJumpUp();
		}

	}

	private static class NotificationClearingPageSelectionListener extends SimpleOnPageChangeListener {

		private final MainActivity host;

		public NotificationClearingPageSelectionListener (final MainActivity host) {
			this.host = host;
		}

		@Override
		public void onPageSelected (final int argPosition) {
			final int position = this.host.convertPagePosition(argPosition);
			final Column col = this.host.getConf().getColumnByPosition(position);
			Notifications.clearColumn(this.host, col);
		}

	}

	private static class CheckBackgroundUpdatesRunning extends TrackingAsyncTask<Void, Void, Boolean> {

		private final Activity activity;

		public CheckBackgroundUpdatesRunning (final Activity activity, final ExecutorEventListener eventListener) {
			super(eventListener);
			this.activity = activity;
		}

		@Override
		protected Boolean doInBackgroundWithTracking (final Void... params) {
			final float bl = BatteryHelper.level(this.activity.getApplicationContext());
			return bl <= FetchingPrefFragment.readMinBatForUpdate(this.activity)
					&& !BatteryNotify.isOverrideEnabled(this.activity);
		}

		@Override
		protected void onPostExecute (final Boolean backgroudUpdatesDisabled) {
			if (backgroudUpdatesDisabled) {
				final View backgroundUpdateDetails = this.activity.findViewById(R.id.backgroudUpdateDetails);
				backgroundUpdateDetails.setVisibility(View.VISIBLE);
				this.activity.findViewById(R.id.backgroundUpdateOverride).setOnClickListener(new OnClickListener() {
					@Override
					public void onClick (final View v) {
						BatteryNotify.plusTime(CheckBackgroundUpdatesRunning.this.activity);
						backgroundUpdateDetails.setVisibility(View.GONE);
					}
				});
			}
		}

	}

}
