// 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) {
    final 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) {
    final 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());
    }
  }
}
