@Override
  public boolean onContextItemSelected(MenuItem item) {
    super.onContextItemSelected(item);
    AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
    final int index = menuInfo.position;

    switch (item.getItemId()) {
      case SectionMenuItems.PLAY:
        BooksHelper.playSection(this, book.getUri(), index);
        return true;
      case SectionMenuItems.DELETE:
        final Runnable uiPostDelete =
            new Runnable() {
              @Override
              public void run() {
                sectionsCursor.requery();
              }
            };
        Runnable runnable =
            new Runnable() {
              @Override
              public void run() {
                Book playerBook = Book.read(getContentResolver(), book.getUri());
                File file =
                    FileHelper.getFile(
                        getContentResolver(),
                        playerBook.getId(),
                        index,
                        false,
                        playerBook.getTitle(),
                        playerBook.getLibrivoxId());
                if (file.exists()) {
                  if (!file.delete()) {
                    Toast.makeText(
                        BookViewActivity.this,
                        R.string.errorDeletingSection,
                        LogHelper.TOAST_ERROR_DISPLAY_MS);
                  }
                }
                runOnUiThread(uiPostDelete);
              }
            };
        new Thread(runnable).start();
        return true;
      case SectionMenuItems.DOWNLOAD:
        BooksHelper.downloadSectionIfNeeded(this, book.getUri(), index);
        return true;
      default:
        Toast toast =
            Toast.makeText(
                getApplicationContext(), "Not yet implemented", LogHelper.TOAST_ERROR_DISPLAY_MS);
        toast.show();
    }
    return false;
  }
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.book_activity);

    installFlingHandler(findViewById(R.id.section_list));

    ListView sectionsList = (ListView) findViewById(R.id.section_list);

    registerForContextMenu(sectionsList);

    // add the book's main description view
    // to this listView as a header, so it scrolls nicely
    LayoutInflater inflater = LayoutInflater.from(this);
    View header = inflater.inflate(R.layout.book_description_view, null);
    sectionsList.addHeaderView(header);

    Intent intent = getIntent();
    Uri inputUri = intent.getData();

    Uri bookUri = getBookUri(inputUri);

    book = Book.read(getContentResolver(), bookUri);

    populateView();
    installURLClickHandlers();

    playButton = (Button) findViewById(R.id.play);

    final Button addToLibraryButton = (Button) findViewById(R.id.addToLibrary);
    final Button downloadButton = (Button) findViewById(R.id.download);
    final Button deleteButton = (Button) findViewById(R.id.delete);

    Runnable onSectionLoadCompleteRunnable =
        new Runnable() {
          @Override
          public void run() {
            // as sections are added, the downloadability state may change
            // (e.g., no sections would mean no need to download)
            // when done loading the sections, update the button text and
            // enable the button
            updateDownloadButton(downloadButton);
          }
        };
    backgroundSectionQueryHelper =
        new BackgroundQueryHelper(
            this,
            (ProgressBar) findViewById(R.id.section_progress),
            (TextView) findViewById(R.id.sectionLoadMessage),
            onSectionLoadCompleteRunnable,
            R.color.error);

    String bookId = bookUri.getPathSegments().get(1);
    // this has to go before any thing else that might fault the sections
    // cursor, for proper section loading progress notification
    populateSections(bookId);

    playButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View view) {
            Book playersBook = mBoundService != null ? mBoundService.getBook() : null;
            if (mBoundService != null
                && mBoundService.libriIsPlaying()
                && (playersBook != null && playersBook.getUri().equals(book.getUri()))) {
              mBoundService.userPause();
            } else {
              Runnable after =
                  new Runnable() {
                    @Override
                    public void run() {
                      transitionToLeft();
                    }
                  };
              BooksHelper.playBook(BookViewActivity.this, book.getUri(), true, after);

              book.refresh(getContentResolver());
              // throw new RuntimeException("Requery didn't work");
              updateDownloadButton(downloadButton);
            }
          }
        });

    final Runnable postDeleteActions =
        new Runnable() {
          @Override
          public void run() {
            Runnable runnable =
                new Runnable() {
                  @Override
                  public void run() {
                    book.refresh(getContentResolver());
                    sectionsCursor.requery();
                    // throw new
                    // RuntimeException("Requery didn't work");
                    calculateAndDisplayBookDurationAndSize();
                    updateDownloadButton(downloadButton);
                    updateDeleteButton(deleteButton);
                    updateAddToLibraryButtonText(addToLibraryButton);
                  }
                };
            runOnUiThread(runnable);
          }
        };

    updateDownloadButton(downloadButton);
    downloadButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View view) {
            Runnable runnable =
                new Runnable() {
                  @Override
                  public void run() {
                    final boolean needAnySections =
                        BooksHelper.needToDownloadAnySections(
                            BookViewActivity.this, book.getUri(), false);
                    Runnable updateLabel =
                        new Runnable() {
                          @Override
                          public void run() {
                            if (needAnySections) {
                              BooksHelper.downloadBookFiles(BookViewActivity.this, book.getUri());
                              postDeleteActions.run();
                            }
                          }
                        };
                    runOnUiThread(updateLabel);
                  }
                };
            new Thread(runnable).start();
          }
        });

    updateAddToLibraryButtonText(addToLibraryButton);
    addToLibraryButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            boolean isCurrentlyDownloaded = book.isInLibrary();
            if (isCurrentlyDownloaded) {
              BooksHelper.removeBookFromLibrary(
                  BookViewActivity.this, book.getUri(), postDeleteActions);
            } else {
              BooksHelper.addBookToLibrary(BookViewActivity.this, book.getUri());
              book.refresh(getContentResolver());
              updateAddToLibraryButtonText(addToLibraryButton);
            }
          }
        });

    updateDeleteButton(deleteButton);
    deleteButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            File bookDirectory = FileHelper.getBookDirectory(book);
            if (bookDirectory.exists()) {
              com.oakonell.libridroid.download.DownloadHelper.deleteDownloadsForBook(
                  BookViewActivity.this, book.getUri());
              BooksHelper.promptAndDeleteBookFiles(
                  BookViewActivity.this, book.getUri(), postDeleteActions);
            }
          }
        });
    doBindService(null);
  }