@Override
  public void onPrepareOptionsMenu(Menu menu) {
    currentMenu = menu;

    for (int index = 0; index < menu.size(); index++) {
      menu.getItem(index).setVisible(false);
    }

    MenuItem undo = menu.findItem(R.id.menu_undo);
    if (formulaEditorEditText == null || !formulaEditorEditText.getHistory().undoIsPossible()) {
      undo.setIcon(R.drawable.icon_undo_disabled);
      undo.setEnabled(false);
    } else {
      undo.setIcon(R.drawable.icon_undo);
      undo.setEnabled(true);
    }

    MenuItem redo = menu.findItem(R.id.menu_redo);
    if (formulaEditorEditText == null || !formulaEditorEditText.getHistory().redoIsPossible()) {
      redo.setIcon(R.drawable.icon_redo_disabled);
      redo.setEnabled(false);
    } else {
      redo.setIcon(R.drawable.icon_redo);
      redo.setEnabled(true);
    }

    menu.findItem(R.id.menu_undo).setVisible(true);
    menu.findItem(R.id.menu_redo).setVisible(true);
    getActivity().getActionBar().setDisplayShowTitleEnabled(true);
    getActivity().getActionBar().setTitle(getString(R.string.formula_editor_title));

    super.onPrepareOptionsMenu(menu);
  }
 private void handleCustomView() {
   if (showCustomView) {
     formulaEditorEditText.setVisibility(View.GONE);
     formulaEditorKeyboard.setVisibility(View.GONE);
   } else {
     formulaEditorEditText.setVisibility(View.VISIBLE);
     formulaEditorKeyboard.setVisibility(View.VISIBLE);
   }
 }
  @Override
  public View onCreateView(
      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    fragmentView = inflater.inflate(R.layout.fragment_formula_editor, container, false);
    fragmentView.setFocusableInTouchMode(true);
    fragmentView.requestFocus();

    context = getActivity();

    brickView = getBrickOrCustomView();
    formulaEditorBrick = (LinearLayout) fragmentView.findViewById(R.id.formula_editor_brick_space);
    setBrickViewSafe(brickView, false);

    formulaEditorEditText =
        (FormulaEditorEditText) fragmentView.findViewById(R.id.formula_editor_edit_field);

    formulaEditorKeyboard =
        (TableLayout) fragmentView.findViewById(R.id.formula_editor_keyboardview);
    formulaEditorEditText.init(this);

    fragmentView.getViewTreeObserver().addOnGlobalLayoutListener(this);

    setInputFormula(currentBrickField, SET_FORMULA_ON_CREATE_VIEW);

    setHasOptionsMenu(true);
    setUpActionBar();

    handleCustomView();

    return fragmentView;
  }
  private void exitFormulaEditorFragment() {
    if (formulaEditorEditText.hasChanges()) {
      AlertDialog.Builder builder = new CustomAlertDialogBuilder(getActivity());
      builder
          .setTitle(R.string.formula_editor_discard_changes_dialog_title)
          .setMessage(R.string.formula_editor_discard_changes_dialog_message)
          .setNegativeButton(
              R.string.no,
              new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                  showToast(R.string.formula_editor_changes_discarded, false);
                  currentFormula.setDisplayText(null);
                  onUserDismiss();
                }
              })
          .setPositiveButton(
              R.string.yes,
              new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                  if (saveFormulaIfPossible()) {
                    onUserDismiss();
                  }
                }
              })
          .create()
          .show();
    } else {
      onUserDismiss();
    }
  }
 private void endFormulaEditor() {
   if (formulaEditorEditText.hasChanges()) {
     if (saveFormulaIfPossible()) {
       updateUserBricksIfNecessary();
       onUserDismiss();
     }
   } else {
     onUserDismiss();
   }
 }
 @SuppressWarnings("deprecation")
 @Override
 public void onGlobalLayout() {
   fragmentView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
   Rect brickRect = new Rect();
   Rect keyboardRec = new Rect();
   formulaEditorBrick.getGlobalVisibleRect(brickRect);
   formulaEditorKeyboard.getGlobalVisibleRect(keyboardRec);
   formulaEditorEditText.setMaxHeight(keyboardRec.top - brickRect.bottom);
 }
  public static boolean saveFormulaForUserBrickParameterChange() {
    InternFormulaParser formulaToParse = formulaEditorEditText.getFormulaParser();
    FormulaElement formulaParseTree = formulaToParse.parseFormula();

    switch (formulaToParse.getErrorTokenIndex()) {
      case PARSER_OK:
        currentFormula.setRoot(formulaParseTree);
        if (onFormulaChangedListener != null) {
          onFormulaChangedListener.onFormulaChanged(
              formulaBrick, currentBrickField, currentFormula);
        }
        if (formulaEditorBrick != null) {
          currentFormula.refreshTextField(brickView);
        }
        formulaEditorEditText.formulaSaved();
        return true;
    }
    return false;
  }
  public void updateButtonsOnKeyboardAndInvalidateOptionsMenu() {
    getActivity().invalidateOptionsMenu();

    ImageButton backspaceOnKeyboard =
        (ImageButton) getActivity().findViewById(R.id.formula_editor_keyboard_delete);
    if (!formulaEditorEditText.isThereSomethingToDelete()) {
      backspaceOnKeyboard.setAlpha(255 / 3);
      backspaceOnKeyboard.setEnabled(false);
    } else {
      backspaceOnKeyboard.setAlpha(255);
      backspaceOnKeyboard.setEnabled(true);
    }
  }
  public boolean saveFormulaIfPossible() {
    InternFormulaParser formulaToParse = formulaEditorEditText.getFormulaParser();
    FormulaElement formulaParseTree = formulaToParse.parseFormula();

    switch (formulaToParse.getErrorTokenIndex()) {
      case PARSER_OK:
        currentFormula.setRoot(formulaParseTree);
        if (onFormulaChangedListener != null) {
          onFormulaChangedListener.onFormulaChanged(
              formulaBrick, currentBrickField, currentFormula);
        }
        if (formulaEditorBrick != null) {
          currentFormula.refreshTextField(brickView);
        }
        formulaEditorEditText.formulaSaved();
        showToast(R.string.formula_editor_changes_saved, false);
        return true;
      case PARSER_STACK_OVERFLOW:
        return checkReturnWithoutSaving(PARSER_STACK_OVERFLOW);
      default:
        formulaEditorEditText.setParseErrorCursorAndSelection();
        return checkReturnWithoutSaving(PARSER_INPUT_SYNTAX_ERROR);
    }
  }
  private void onUserDismiss() {
    refreshFormulaPreviewString(currentFormula.getTrimmedFormulaString(getActivity()));
    formulaEditorEditText.endEdit();
    currentFormula.prepareToRemove();

    Activity activity = getActivity();
    FragmentManager fragmentManager = activity.getFragmentManager();
    FragmentTransaction fragTransaction = fragmentManager.beginTransaction();
    fragTransaction.hide(this);
    fragTransaction.show(fragmentManager.findFragmentByTag(ScriptFragment.TAG));
    fragTransaction.commit();

    resetActionBar();

    BottomBar.showBottomBar(activity);
    BottomBar.showPlayButton(activity);
  }
  private void setInputFormula(Brick.BrickField brickField, int mode) {

    switch (mode) {
      case SET_FORMULA_ON_CREATE_VIEW:
        formulaEditorEditText.enterNewFormula(currentFormula.getInternFormulaState());
        currentFormula.highlightTextField(brickView);
        refreshFormulaPreviewString();
        break;

      case SET_FORMULA_ON_SWITCH_EDIT_TEXT:
        Formula newFormula = clonedFormulaBrick.getFormulaWithBrickField(brickField);
        if (currentFormula == newFormula && formulaEditorEditText.hasChanges()) {
          formulaEditorEditText.quickSelect();
          break;
        }
        if (formulaEditorEditText.hasChanges()) {
          confirmSwitchEditTextTimeStamp[0] = confirmSwitchEditTextTimeStamp[1];
          confirmSwitchEditTextTimeStamp[1] = System.currentTimeMillis();
          confirmSwitchEditTextCounter++;
          if (!saveFormulaIfPossible()) {
            return;
          }
        }
        MenuItem undo = currentMenu.findItem(R.id.menu_undo);
        if (undo != null) {
          undo.setIcon(R.drawable.icon_undo_disabled);
          undo.setEnabled(false);
        }

        MenuItem redo = currentMenu.findItem(R.id.menu_redo);
        redo.setIcon(R.drawable.icon_redo_disabled);
        redo.setEnabled(false);

        formulaEditorEditText.endEdit();
        currentBrickField = brickField;
        currentFormula = newFormula;
        formulaEditorEditText.enterNewFormula(newFormula.getInternFormulaState());
        refreshFormulaPreviewString();
        break;
      default:
        break;
    }
  }
 public void refreshFormulaPreviewString() {
   refreshFormulaPreviewString(formulaEditorEditText.getStringFromInternFormula());
 }
 public void overrideSelectedText(String string) {
   formulaEditorEditText.overrideSelectedText(string);
 }
 public String getSelectedFormulaText() {
   return formulaEditorEditText.getSelectedTextFromInternFormula();
 }
 public void addStringToActiveFormula(String string) {
   formulaEditorEditText.handleKeyEvent(R.id.formula_editor_keyboard_string, string);
 }
 public void addUserVariableToActiveFormula(String userVariableName) {
   formulaEditorEditText.handleKeyEvent(
       InternFormulaKeyboardAdapter.FORMULA_EDITOR_USER_VARIABLE_RESOURCE_ID, userVariableName);
 }
 public void addUserListToActiveFormula(String userListName) {
   formulaEditorEditText.handleKeyEvent(
       InternFormulaKeyboardAdapter.FORMULA_EDITOR_USER_LIST_RESOURCE_ID, userListName);
 }
 public void addResourceToActiveFormula(int resource) {
   formulaEditorEditText.handleKeyEvent(resource, "");
 }