// Copyright (C) 2010 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.patches;

import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.Util;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
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.gwt.core.client.GWT;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.OptionElement;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
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.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.FocusWidget;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtjsonrpc.common.VoidResult;

public class PatchScriptSettingsPanel extends Composite {
  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

  interface MyUiBinder extends UiBinder<Widget, PatchScriptSettingsPanel> {
  }

  private final ListenableAccountDiffPreference listenablePrefs;
  private boolean enableIntralineDifference = true;
  private boolean enableSmallFileFeatures = true;

  @UiField
  ListBox ignoreWhitespace;

  @UiField
  NpIntTextBox tabWidth;

  @UiField
  NpIntTextBox colWidth;

  @UiField
  CheckBox syntaxHighlighting;

  @UiField
  CheckBox intralineDifference;

  @UiField
  ListBox context;

  @UiField
  CheckBox whitespaceErrors;

  @UiField
  CheckBox showLineEndings;

  @UiField
  CheckBox showTabs;

  @UiField
  CheckBox manualReview;

  @UiField
  CheckBox skipDeleted;

  @UiField
  CheckBox skipUncommented;

  @UiField
  CheckBox expandAllComments;

  @UiField
  CheckBox retainHeader;

  @UiField
  Button update;

  @UiField
  Button save;

  /**
   * Counts +1 for every setEnabled(true) and -1 for every setEnabled(false)
   *
   * The purpose is to prevent enabling widgets too early. It might happen that
   * setEnabled(false) is called from this class and from an event handler
   * of ValueChangeEvent in another class. The first setEnabled(true) would then
   * enable widgets too early i.e. before the second setEnabled(true) is called.
   *
   * With this counter the setEnabled(true) will enable widgets only when
   * setEnabledCounter == 0. Until it is less than zero setEnabled(true) will
   * not enable the widgets.
   */
  private int setEnabledCounter;

  public PatchScriptSettingsPanel(ListenableAccountDiffPreference prefs) {
    listenablePrefs = prefs;
    initWidget(uiBinder.createAndBindUi(this));
    initIgnoreWhitespace(ignoreWhitespace);
    initContext(context);
    if (!Gerrit.isSignedIn()) {
      save.setVisible(false);
    }

    KeyPressHandler onEnter = new KeyPressHandler() {
      @Override
      public void onKeyPress(KeyPressEvent event) {
        if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
          save();
        }
      }
    };
    tabWidth.addKeyPressHandler(onEnter);
    colWidth.addKeyPressHandler(onEnter);

    display();
  }

  public void setEnabled(final boolean on) {
    if (on) {
      setEnabledCounter++;
    } else {
      setEnabledCounter--;
    }
    if (on && setEnabledCounter == 0 || !on) {
      for (Widget w : (HasWidgets) getWidget()) {
        if (w instanceof FocusWidget) {
          ((FocusWidget) w).setEnabled(on);
        }
      }
      toggleEnabledStatus(on);
    }
  }

  public void setEnableSmallFileFeatures(final boolean on) {
    enableSmallFileFeatures = on;
    if (enableSmallFileFeatures) {
      syntaxHighlighting.setValue(getValue().syntaxHighlighting);
    } else {
      syntaxHighlighting.setValue(false);
    }

    NodeList<OptionElement> options =
        context.getElement().<SelectElement>cast().getOptions();
    // WHOLE_FILE_CONTEXT is the last option in the list.
    int lastIndex = options.getLength() - 1;
    OptionElement currOption = options.getItem(lastIndex);
    if (enableSmallFileFeatures) {
      currOption.setDisabled(false);
    } else {
      currOption.setDisabled(true);
      if (context.getSelectedIndex() == lastIndex) {
        // Select the next longest context from WHOLE_FILE_CONTEXT
        context.setSelectedIndex(lastIndex - 1);
      }
    }
    toggleEnabledStatus(save.isEnabled());
  }

  public void setEnableIntralineDifference(final boolean on) {
    enableIntralineDifference = on;
    if (enableIntralineDifference) {
      intralineDifference.setValue(getValue().intralineDifference);
    } else {
      intralineDifference.setValue(false);
    }
    toggleEnabledStatus(save.isEnabled());
  }

  private void toggleEnabledStatus(final boolean on) {
    intralineDifference.setEnabled(on & enableIntralineDifference);
    syntaxHighlighting.setEnabled(on & enableSmallFileFeatures);

    final String title =
        enableSmallFileFeatures ? null : PatchUtil.C.disabledOnLargeFiles();
    syntaxHighlighting.setTitle(title);
  }

  public DiffPreferencesInfo getValue() {
    return listenablePrefs.get();
  }

  public void setValue(final DiffPreferencesInfo dp) {
    listenablePrefs.set(dp);
    display();
  }

  protected void display() {
    final DiffPreferencesInfo dp = getValue();
    setIgnoreWhitespace(dp.ignoreWhitespace);
    if (enableSmallFileFeatures) {
      syntaxHighlighting.setValue(dp.syntaxHighlighting);
    } else {
      syntaxHighlighting.setValue(false);
    }
    setContext(dp.context);

    tabWidth.setIntValue(dp.tabSize);
    colWidth.setIntValue(dp.lineLength);
    intralineDifference.setValue(dp.intralineDifference);
    whitespaceErrors.setValue(dp.showWhitespaceErrors);
    showLineEndings.setValue(dp.showLineEndings);
    showTabs.setValue(dp.showTabs);
    skipDeleted.setValue(dp.skipDeleted);
    skipUncommented.setValue(dp.skipUncommented);
    expandAllComments.setValue(dp.expandAllComments);
    retainHeader.setValue(dp.retainHeader);
    manualReview.setValue(dp.manualReview);
  }

  @UiHandler("update")
  void onUpdate(@SuppressWarnings("unused") ClickEvent event) {
    update();
  }

  @UiHandler("save")
  void onSave(@SuppressWarnings("unused") ClickEvent event) {
    save();
  }

  private void update() {
    if (colWidth.getIntValue() <= 0) {
      new ErrorDialog(PatchUtil.C.illegalNumberOfColumns()).center();
      return;
    }
    DiffPreferencesInfo dp = getValue();
    dp.ignoreWhitespace = getIgnoreWhitespace();
    dp.context = getContext();
    dp.tabSize = tabWidth.getIntValue();
    dp.lineLength = colWidth.getIntValue();
    dp.syntaxHighlighting = syntaxHighlighting.getValue();
    dp.intralineDifference = intralineDifference.getValue();
    dp.showWhitespaceErrors = whitespaceErrors.getValue();
    dp.showLineEndings = showLineEndings.getValue();
    dp.showTabs = showTabs.getValue();
    dp.skipDeleted = skipDeleted.getValue();
    dp.skipUncommented = skipUncommented.getValue();
    dp.expandAllComments = expandAllComments.getValue();
    dp.retainHeader = retainHeader.getValue();
    dp.manualReview = manualReview.getValue();

    listenablePrefs.set(dp);
  }

  private void save() {
    update();
    if (Gerrit.isSignedIn()) {
      persistDiffPreferences();
    }
  }

  private void persistDiffPreferences() {
    setEnabled(false);
    listenablePrefs.save(new GerritCallback<VoidResult>() {
      @Override
      public void onSuccess(VoidResult result) {
        setEnabled(true);
      }

      @Override
      public void onFailure(Throwable caught) {
        setEnabled(true);
      }
    });
  }

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

  private void initContext(ListBox context) {
    for (final short v : DiffPreferencesInfo.CONTEXT_CHOICES) {
      final String label;
      if (v == DiffPreferencesInfo.WHOLE_FILE_CONTEXT) {
        label = Util.C.contextWholeFile();
      } else {
        label = Util.M.lines(v);
      }
      context.addItem(label, String.valueOf(v));
    }
  }

  private Whitespace getIgnoreWhitespace() {
    final int sel = ignoreWhitespace.getSelectedIndex();
    if (0 <= sel) {
      return Whitespace.valueOf(ignoreWhitespace.getValue(sel));
    }
    return getValue().ignoreWhitespace;
  }

  private void setIgnoreWhitespace(Whitespace s) {
    for (int i = 0; i < ignoreWhitespace.getItemCount(); i++) {
      if (ignoreWhitespace.getValue(i).equals(s.name())) {
        ignoreWhitespace.setSelectedIndex(i);
        return;
      }
    }
    ignoreWhitespace.setSelectedIndex(0);
  }

  private int getContext() {
    final int sel = context.getSelectedIndex();
    if (0 <= sel) {
      return Short.parseShort(context.getValue(sel));
    }
    return getValue().context;
  }

  private void setContext(int ctx) {
    String v = String.valueOf(ctx);
    for (int i = 0; i < context.getItemCount(); i++) {
      if (context.getValue(i).equals(v)) {
        context.setSelectedIndex(i);
        return;
      }
    }
    context.setSelectedIndex(0);
  }
}
