// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.client.diff;

import static com.google.gerrit.extensions.client.DiffPreferencesInfo.DEFAULT_CONTEXT;
import static com.google.gerrit.extensions.client.DiffPreferencesInfo.WHOLE_FILE_CONTEXT;
import static com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace.IGNORE_ALL;
import static com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace.IGNORE_LEADING_AND_TRAILING;
import static com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace.IGNORE_NONE;
import static com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace.IGNORE_TRAILING;
import static com.google.gwt.event.dom.client.KeyCodes.KEY_ESCAPE;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.AccountApi;
import com.google.gerrit.client.account.DiffPreferences;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.NpIntTextBox;
import com.google.gerrit.extensions.client.DiffPreferencesInfo;
import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
import com.google.gerrit.extensions.client.Theme;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.UIObject;
import java.util.Objects;
import net.codemirror.lib.CodeMirror;
import net.codemirror.mode.ModeInfo;
import net.codemirror.mode.ModeInjector;
import net.codemirror.theme.ThemeLoader;

/** Displays current diff preferences. */
public class PreferencesBox extends Composite {
  interface Binder extends UiBinder<HTMLPanel, PreferencesBox> {}

  private static final Binder uiBinder = GWT.create(Binder.class);

  public interface Style extends CssResource {
    String dialog();
  }

  private final DiffScreen view;
  private DiffPreferences prefs;
  private int contextLastValue;
  private Timer updateContextTimer;

  @UiField Style style;
  @UiField Element header;
  @UiField Anchor close;
  @UiField ListBox ignoreWhitespace;
  @UiField NpIntTextBox tabWidth;
  @UiField NpIntTextBox lineLength;
  @UiField NpIntTextBox context;
  @UiField NpIntTextBox cursorBlinkRate;
  @UiField CheckBox contextEntireFile;
  @UiField ToggleButton intralineDifference;
  @UiField ToggleButton syntaxHighlighting;
  @UiField ToggleButton whitespaceErrors;
  @UiField ToggleButton showTabs;
  @UiField ToggleButton lineNumbers;
  @UiField Element leftSideLabel;
  @UiField ToggleButton leftSide;
  @UiField ToggleButton emptyPane;
  @UiField ToggleButton topMenu;
  @UiField ToggleButton autoHideDiffTableHeader;
  @UiField ToggleButton manualReview;
  @UiField ToggleButton expandAllComments;
  @UiField ToggleButton renderEntireFile;
  @UiField ToggleButton matchBrackets;
  @UiField ToggleButton lineWrapping;
  @UiField ToggleButton skipDeleted;
  @UiField ToggleButton skipUnchanged;
  @UiField ToggleButton skipUncommented;
  @UiField ListBox theme;
  @UiField Element modeLabel;
  @UiField ListBox mode;
  @UiField Button apply;
  @UiField Button save;

  public PreferencesBox(DiffScreen view) {
    this.view = view;

    initWidget(uiBinder.createAndBindUi(this));
    initIgnoreWhitespace();
    initTheme();

    if (view != null) {
      initMode();
    } else {
      UIObject.setVisible(header, false);
      apply.getElement().getStyle().setVisibility(Visibility.HIDDEN);
    }
  }

  @Override
  public void onLoad() {
    super.onLoad();

    save.setVisible(Gerrit.isSignedIn());

    if (view != null) {
      addDomHandler(
          new KeyDownHandler() {
            @Override
            public void onKeyDown(KeyDownEvent event) {
              if (event.getNativeKeyCode() == KEY_ESCAPE || event.getNativeKeyCode() == ',') {
                close();
              }
            }
          },
          KeyDownEvent.getType());

      updateContextTimer =
          new Timer() {
            @Override
            public void run() {
              if (prefs.context() == WHOLE_FILE_CONTEXT) {
                contextEntireFile.setValue(true);
              }
              if (view.canRenderEntireFile(prefs)) {
                renderEntireFile.setEnabled(true);
                renderEntireFile.setValue(prefs.renderEntireFile());
              } else {
                renderEntireFile.setValue(false);
                renderEntireFile.setEnabled(false);
              }
              view.setContext(prefs.context());
            }
          };
    }
  }

  public Style getStyle() {
    return style;
  }

  public void set(DiffPreferences prefs) {
    this.prefs = prefs;

    setIgnoreWhitespace(prefs.ignoreWhitespace());
    tabWidth.setIntValue(prefs.tabSize());
    if (view != null && Patch.COMMIT_MSG.equals(view.path)) {
      lineLength.setEnabled(false);
      lineLength.setIntValue(72);
    } else {
      lineLength.setEnabled(true);
      lineLength.setIntValue(prefs.lineLength());
    }
    cursorBlinkRate.setIntValue(prefs.cursorBlinkRate());
    syntaxHighlighting.setValue(prefs.syntaxHighlighting());
    whitespaceErrors.setValue(prefs.showWhitespaceErrors());
    showTabs.setValue(prefs.showTabs());
    lineNumbers.setValue(prefs.showLineNumbers());
    emptyPane.setValue(!prefs.hideEmptyPane());
    if (view != null) {
      leftSide.setValue(view.getDiffTable().isVisibleA());
      leftSide.setEnabled(
          !(prefs.hideEmptyPane() && view.getDiffTable().getChangeType() == ChangeType.ADDED));
    } else {
      UIObject.setVisible(leftSideLabel, false);
      leftSide.setVisible(false);
    }
    topMenu.setValue(!prefs.hideTopMenu());
    autoHideDiffTableHeader.setValue(!prefs.autoHideDiffTableHeader());
    manualReview.setValue(prefs.manualReview());
    expandAllComments.setValue(prefs.expandAllComments());
    matchBrackets.setValue(prefs.matchBrackets());
    lineWrapping.setValue(prefs.lineWrapping());
    skipDeleted.setValue(!prefs.skipDeleted());
    skipUnchanged.setValue(!prefs.skipUnchanged());
    skipUncommented.setValue(!prefs.skipUncommented());
    setTheme(prefs.theme());

    if (view == null || view.canRenderEntireFile(prefs)) {
      renderEntireFile.setValue(prefs.renderEntireFile());
      renderEntireFile.setEnabled(true);
    } else {
      renderEntireFile.setValue(false);
      renderEntireFile.setEnabled(false);
    }

    if (view != null) {
      mode.setEnabled(prefs.syntaxHighlighting());
      if (prefs.syntaxHighlighting()) {
        setMode(view.getCmFromSide(DisplaySide.B).getStringOption("mode"));
      }
    } else {
      UIObject.setVisible(modeLabel, false);
      mode.setVisible(false);
    }

    if (view != null) {
      switch (view.getIntraLineStatus()) {
        case OFF:
        case OK:
          intralineDifference.setValue(prefs.intralineDifference());
          break;

        case TIMEOUT:
        case FAILURE:
          intralineDifference.setValue(false);
          intralineDifference.setEnabled(false);
          break;
      }
    } else {
      intralineDifference.setValue(prefs.intralineDifference());
    }

    if (prefs.context() == WHOLE_FILE_CONTEXT) {
      contextLastValue = DEFAULT_CONTEXT;
      context.setText("");
      contextEntireFile.setValue(true);
    } else {
      context.setIntValue(prefs.context());
      contextEntireFile.setValue(false);
    }
  }

  @UiHandler("ignoreWhitespace")
  void onIgnoreWhitespace(@SuppressWarnings("unused") ChangeEvent e) {
    prefs.ignoreWhitespace(
        Whitespace.valueOf(ignoreWhitespace.getValue(ignoreWhitespace.getSelectedIndex())));
    if (view != null) {
      view.reloadDiffInfo();
    }
  }

  @UiHandler("intralineDifference")
  void onIntralineDifference(ValueChangeEvent<Boolean> e) {
    prefs.intralineDifference(Boolean.valueOf(e.getValue()));
    if (view != null) {
      view.setShowIntraline(prefs.intralineDifference());
    }
  }

  @UiHandler("context")
  void onContextKey(KeyPressEvent e) {
    if (contextEntireFile.getValue()) {
      char c = e.getCharCode();
      if ('0' <= c && c <= '9') {
        contextEntireFile.setValue(false);
      }
    }
  }

  @UiHandler("context")
  void onContext(ValueChangeEvent<String> e) {
    String v = e.getValue();
    int c;
    if (v != null && v.length() > 0) {
      c = Math.min(Math.max(0, Integer.parseInt(v)), 32767);
      contextEntireFile.setValue(false);
    } else if (v == null || v.isEmpty()) {
      c = WHOLE_FILE_CONTEXT;
    } else {
      return;
    }
    prefs.context(c);
    if (view != null) {
      updateContextTimer.schedule(200);
    }
  }

  @UiHandler("contextEntireFile")
  void onContextEntireFile(ValueChangeEvent<Boolean> e) {
    // If a click arrives too fast after onContext applied an update
    // the user committed the context line update by clicking on the
    // whole file checkmark. Drop this event, but transfer focus.
    if (e.getValue()) {
      contextLastValue = context.getIntValue();
      context.setText("");
      prefs.context(WHOLE_FILE_CONTEXT);
    } else {
      prefs.context(contextLastValue > 0 ? contextLastValue : DEFAULT_CONTEXT);
      context.setIntValue(prefs.context());
      context.setFocus(true);
      context.setSelectionRange(0, context.getText().length());
    }
    if (view != null) {
      updateContextTimer.schedule(200);
    }
  }

  @UiHandler("tabWidth")
  void onTabWidth(ValueChangeEvent<String> e) {
    String v = e.getValue();
    if (v != null && v.length() > 0) {
      prefs.tabSize(Math.max(1, Integer.parseInt(v)));
      if (view != null) {
        view.operation(
            () -> {
              int size = prefs.tabSize();
              for (CodeMirror cm : view.getCms()) {
                cm.setOption("tabSize", size);
              }
            });
      }
    }
  }

  @UiHandler("lineLength")
  void onLineLength(ValueChangeEvent<String> e) {
    String v = e.getValue();
    if (v != null && v.length() > 0) {
      prefs.lineLength(Math.max(1, Integer.parseInt(v)));
      if (view != null) {
        view.operation(() -> view.setLineLength(prefs.lineLength()));
      }
    }
  }

  @UiHandler("expandAllComments")
  void onExpandAllComments(ValueChangeEvent<Boolean> e) {
    prefs.expandAllComments(e.getValue());
    if (view != null) {
      view.getCommentManager().setExpandAllComments(prefs.expandAllComments());
    }
  }

  @UiHandler("cursorBlinkRate")
  void onCursoBlinkRate(ValueChangeEvent<String> e) {
    String v = e.getValue();
    if (v != null && v.length() > 0) {
      // A negative value hides the cursor entirely:
      // don't let user shoot himself in the foot.
      prefs.cursorBlinkRate(Math.max(0, Integer.parseInt(v)));
      view.getCmFromSide(DisplaySide.A).setOption("cursorBlinkRate", prefs.cursorBlinkRate());
      view.getCmFromSide(DisplaySide.B).setOption("cursorBlinkRate", prefs.cursorBlinkRate());
    }
  }

  @UiHandler("showTabs")
  void onShowTabs(ValueChangeEvent<Boolean> e) {
    prefs.showTabs(e.getValue());
    if (view != null) {
      view.setShowTabs(prefs.showTabs());
    }
  }

  @UiHandler("lineNumbers")
  void onLineNumbers(ValueChangeEvent<Boolean> e) {
    prefs.showLineNumbers(e.getValue());
    if (view != null) {
      view.setShowLineNumbers(prefs.showLineNumbers());
    }
  }

  @UiHandler("leftSide")
  void onLeftSide(ValueChangeEvent<Boolean> e) {
    if (view.getDiffTable() instanceof SideBySideTable) {
      ((SideBySideTable) view.getDiffTable()).setVisibleA(e.getValue());
    }
  }

  @UiHandler("emptyPane")
  void onHideEmptyPane(ValueChangeEvent<Boolean> e) {
    prefs.hideEmptyPane(!e.getValue());
    if (view != null) {
      view.getDiffTable().setHideEmptyPane(prefs.hideEmptyPane());
      if (prefs.hideEmptyPane()) {
        if (view.getDiffTable().getChangeType() == ChangeType.ADDED) {
          leftSide.setValue(false);
          leftSide.setEnabled(false);
        }
      } else {
        leftSide.setValue(view.getDiffTable().isVisibleA());
        leftSide.setEnabled(true);
      }
    }
  }

  @UiHandler("topMenu")
  void onTopMenu(ValueChangeEvent<Boolean> e) {
    prefs.hideTopMenu(!e.getValue());
    if (view != null) {
      Gerrit.setHeaderVisible(!prefs.hideTopMenu());
      view.resizeCodeMirror();
    }
  }

  @UiHandler("autoHideDiffTableHeader")
  void onAutoHideDiffTableHeader(ValueChangeEvent<Boolean> e) {
    prefs.autoHideDiffTableHeader(!e.getValue());
    if (view != null) {
      view.setAutoHideDiffHeader(!e.getValue());
    }
  }

  @UiHandler("manualReview")
  void onManualReview(ValueChangeEvent<Boolean> e) {
    prefs.manualReview(e.getValue());
  }

  @UiHandler("syntaxHighlighting")
  void onSyntaxHighlighting(ValueChangeEvent<Boolean> e) {
    prefs.syntaxHighlighting(e.getValue());
    if (view != null) {
      mode.setEnabled(prefs.syntaxHighlighting());
      if (prefs.syntaxHighlighting()) {
        setMode(view.getContentType());
      }
      view.setSyntaxHighlighting(prefs.syntaxHighlighting());
    }
  }

  @UiHandler("mode")
  void onMode(@SuppressWarnings("unused") ChangeEvent e) {
    String mode = getSelectedMode();
    prefs.syntaxHighlighting(true);
    syntaxHighlighting.setValue(true, false);
    new ModeInjector()
        .add(mode)
        .inject(
            new GerritCallback<Void>() {
              @Override
              public void onSuccess(Void result) {
                if (prefs.syntaxHighlighting()
                    && Objects.equals(mode, getSelectedMode())
                    && view.isAttached()) {
                  view.operation(
                      () -> {
                        view.getCmFromSide(DisplaySide.A).setOption("mode", mode);
                        view.getCmFromSide(DisplaySide.B).setOption("mode", mode);
                      });
                }
              }
            });
  }

  private String getSelectedMode() {
    String m = mode.getValue(mode.getSelectedIndex());
    return m != null && !m.isEmpty() ? m : null;
  }

  @UiHandler("whitespaceErrors")
  void onWhitespaceErrors(ValueChangeEvent<Boolean> e) {
    prefs.showWhitespaceErrors(e.getValue());
    if (view != null) {
      view.operation(
          () -> {
            boolean s = prefs.showWhitespaceErrors();
            for (CodeMirror cm : view.getCms()) {
              cm.setOption("showTrailingSpace", s);
            }
          });
    }
  }

  @UiHandler("renderEntireFile")
  void onRenderEntireFile(ValueChangeEvent<Boolean> e) {
    prefs.renderEntireFile(e.getValue());
    if (view != null) {
      view.updateRenderEntireFile();
    }
  }

  @UiHandler("matchBrackets")
  void onMatchBrackets(ValueChangeEvent<Boolean> e) {
    prefs.matchBrackets(e.getValue());
    view.getCmFromSide(DisplaySide.A).setOption("matchBrackets", prefs.matchBrackets());
    view.getCmFromSide(DisplaySide.B).setOption("matchBrackets", prefs.matchBrackets());
  }

  @UiHandler("lineWrapping")
  void onLineWrapping(ValueChangeEvent<Boolean> e) {
    prefs.lineWrapping(e.getValue());
    view.getCmFromSide(DisplaySide.A).setOption("lineWrapping", prefs.lineWrapping());
    view.getCmFromSide(DisplaySide.B).setOption("lineWrapping", prefs.lineWrapping());
  }

  @UiHandler("skipDeleted")
  void onSkipDeleted(ValueChangeEvent<Boolean> e) {
    prefs.skipDeleted(!e.getValue());
    // TODO: Update the navigation links on the current DiffScreen
  }

  @UiHandler("skipUnchanged")
  void onSkipUnchanged(ValueChangeEvent<Boolean> e) {
    prefs.skipUnchanged(!e.getValue());
    // TODO: Update the navigation links on the current DiffScreen
  }

  @UiHandler("skipUncommented")
  void onSkipUncommented(ValueChangeEvent<Boolean> e) {
    prefs.skipUncommented(!e.getValue());
    // TODO: Update the navigation links on the current DiffScreen
  }

  @UiHandler("theme")
  void onTheme(@SuppressWarnings("unused") ChangeEvent e) {
    Theme newTheme = getSelectedTheme();
    prefs.theme(newTheme);
    if (view != null) {
      ThemeLoader.loadTheme(
          newTheme,
          new GerritCallback<Void>() {
            @Override
            public void onSuccess(Void result) {
              view.operation(
                  () -> {
                    if (getSelectedTheme() == newTheme && isAttached()) {
                      String t = newTheme.name().toLowerCase();
                      view.getCmFromSide(DisplaySide.A).setOption("theme", t);
                      view.getCmFromSide(DisplaySide.B).setOption("theme", t);
                      view.setThemeStyles(newTheme.isDark());
                    }
                  });
            }
          });
    }
  }

  private Theme getSelectedTheme() {
    return Theme.valueOf(theme.getValue(theme.getSelectedIndex()));
  }

  @UiHandler("apply")
  void onApply(@SuppressWarnings("unused") ClickEvent e) {
    close();
  }

  @UiHandler("save")
  void onSave(@SuppressWarnings("unused") ClickEvent e) {
    AccountApi.putDiffPreferences(
        prefs,
        new GerritCallback<DiffPreferences>() {
          @Override
          public void onSuccess(DiffPreferences result) {
            DiffPreferencesInfo p = new DiffPreferencesInfo();
            result.copyTo(p);
            Gerrit.setDiffPreferences(p);
          }
        });
    if (view != null) {
      close();
    }
  }

  @UiHandler("close")
  void onClose(ClickEvent e) {
    e.preventDefault();
    close();
  }

  void setFocus(boolean focus) {
    ignoreWhitespace.setFocus(focus);
  }

  private void close() {
    ((PopupPanel) getParent()).hide();
  }

  private void setIgnoreWhitespace(Whitespace v) {
    String name = v != null ? v.name() : IGNORE_NONE.name();
    for (int i = 0; i < ignoreWhitespace.getItemCount(); i++) {
      if (ignoreWhitespace.getValue(i).equals(name)) {
        ignoreWhitespace.setSelectedIndex(i);
        return;
      }
    }
    ignoreWhitespace.setSelectedIndex(0);
  }

  private void initIgnoreWhitespace() {
    ignoreWhitespace.addItem(PatchUtil.C.whitespaceIGNORE_NONE(), IGNORE_NONE.name());
    ignoreWhitespace.addItem(PatchUtil.C.whitespaceIGNORE_TRAILING(), IGNORE_TRAILING.name());
    ignoreWhitespace.addItem(
        PatchUtil.C.whitespaceIGNORE_LEADING_AND_TRAILING(), IGNORE_LEADING_AND_TRAILING.name());
    ignoreWhitespace.addItem(PatchUtil.C.whitespaceIGNORE_ALL(), IGNORE_ALL.name());
  }

  private void initMode() {
    mode.addItem("", "");
    for (ModeInfo m : Natives.asList(ModeInfo.all())) {
      mode.addItem(m.name(), m.mime());
    }
  }

  private void setMode(String modeType) {
    if (modeType != null && !modeType.isEmpty()) {
      ModeInfo m = ModeInfo.findModeByMIME(modeType);
      if (m != null) {
        for (int i = 0; i < mode.getItemCount(); i++) {
          if (mode.getValue(i).equals(m.mime())) {
            mode.setSelectedIndex(i);
            return;
          }
        }
      }
    }
    mode.setSelectedIndex(0);
  }

  private void setTheme(Theme v) {
    String name = v != null ? v.name() : Theme.DEFAULT.name();
    for (int i = 0; i < theme.getItemCount(); i++) {
      if (theme.getValue(i).equals(name)) {
        theme.setSelectedIndex(i);
        return;
      }
    }
    theme.setSelectedIndex(0);
  }

  private void initTheme() {
    for (Theme t : Theme.values()) {
      theme.addItem(t.name().toLowerCase(), t.name());
    }
  }
}
