/**
   * Show the Edit bookmark dialog for a particular url. If the url is bookmarked multiple times
   * this will just edit the first instance it finds.
   *
   * @param url The url of the bookmark to edit. The dialog will look up other information like the
   *     id, current title, or keywords associated with this url. If the url isn't bookmarked, the
   *     dialog will fail silently. If the url is bookmarked multiple times, this will only show
   *     information about the first it finds.
   */
  public void show(final String url) {
    final ContentResolver cr = mContext.getContentResolver();
    final BrowserDB db = BrowserDB.from(mContext);
    (new UIAsyncTask.WithoutParams<Bookmark>(ThreadUtils.getBackgroundHandler()) {
          @Override
          public Bookmark doInBackground() {
            final Cursor cursor = db.getBookmarkForUrl(cr, url);
            if (cursor == null) {
              return null;
            }

            Bookmark bookmark = null;
            try {
              cursor.moveToFirst();
              bookmark =
                  new Bookmark(
                      cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID)),
                      cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.TITLE)),
                      cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.URL)),
                      cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.KEYWORD)));
            } finally {
              cursor.close();
            }
            return bookmark;
          }

          @Override
          public void onPostExecute(Bookmark bookmark) {
            if (bookmark == null) {
              return;
            }

            show(bookmark.id, bookmark.title, bookmark.url, bookmark.keyword);
          }
        })
        .execute();
  }
  /**
   * Show the Edit bookmark dialog for a set of data. This will show the dialog whether a bookmark
   * with this url exists or not, but the results will NOT be saved if the id is not a valid
   * bookmark id.
   *
   * @param id The id of the bookmark to change. If there is no bookmark with this ID, the dialog
   *     will fail silently.
   * @param title The initial title to show in the dialog
   * @param url The initial url to show in the dialog
   * @param keyword The initial keyword to show in the dialog
   */
  public void show(final int id, final String title, final String url, final String keyword) {
    final Context context = mContext;

    AlertDialog.Builder editPrompt = new AlertDialog.Builder(context);
    final View editView = LayoutInflater.from(context).inflate(R.layout.bookmark_edit, null);
    editPrompt.setTitle(R.string.bookmark_edit_title);
    editPrompt.setView(editView);

    final EditText nameText = ((EditText) editView.findViewById(R.id.edit_bookmark_name));
    final EditText locationText = ((EditText) editView.findViewById(R.id.edit_bookmark_location));
    final EditText keywordText = ((EditText) editView.findViewById(R.id.edit_bookmark_keyword));
    nameText.setText(title);
    locationText.setText(url);
    keywordText.setText(keyword);

    final BrowserDB db = BrowserDB.from(mContext);
    editPrompt.setPositiveButton(
        R.string.button_ok,
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int whichButton) {
            (new UIAsyncTask.WithoutParams<Void>(ThreadUtils.getBackgroundHandler()) {
                  @Override
                  public Void doInBackground() {
                    String newUrl = locationText.getText().toString().trim();
                    String newKeyword = keywordText.getText().toString().trim();

                    db.updateBookmark(
                        context.getContentResolver(),
                        id,
                        newUrl,
                        nameText.getText().toString(),
                        newKeyword);
                    return null;
                  }

                  @Override
                  public void onPostExecute(Void result) {
                    SnackbarBuilder.builder((Activity) context)
                        .message(R.string.bookmark_updated)
                        .duration(Snackbar.LENGTH_LONG)
                        .buildAndShow();
                  }
                })
                .execute();
          }
        });

    editPrompt.setNegativeButton(
        R.string.button_cancel,
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int whichButton) {
            // do nothing
          }
        });

    final AlertDialog dialog = editPrompt.create();

    // Create our TextWatchers
    LocationTextWatcher locationTextWatcher = new LocationTextWatcher(dialog);
    KeywordTextWatcher keywordTextWatcher = new KeywordTextWatcher(dialog);

    // Cross reference the TextWatchers
    locationTextWatcher.setPairedTextWatcher(keywordTextWatcher);
    keywordTextWatcher.setPairedTextWatcher(locationTextWatcher);

    // Add the TextWatcher Listeners
    locationText.addTextChangedListener(locationTextWatcher);
    keywordText.addTextChangedListener(keywordTextWatcher);

    dialog.show();
  }