// Copyright (C) 2016 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.googlesource.gerrit.plugins.reviewstrategy.client;

import com.google.gerrit.plugin.client.Plugin;
import com.google.gerrit.plugin.client.extension.Panel;
import com.google.gerrit.plugin.client.rpc.RestApi;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ReviewStrategyPreferencesPanel extends VerticalPanel {
  static class Factory implements Panel.EntryPoint {
    @Override
    public void onLoad(Panel panel) {
      panel.setWidget(new ReviewStrategyPreferencesPanel());
    }
  }

  private Label savedLabel;
  private Timer hideTimer;

  ReviewStrategyPreferencesPanel() {
    new RestApi("accounts").id("self")
        .view(Plugin.get().getPluginName(), "preferences")
        .get(new AsyncCallback<PreferencesInfo>() {
          @Override
          public void onSuccess(PreferencesInfo result) {
            display(result);
          }

          @Override
          public void onFailure(Throwable caught) {
            // never invoked
          }
        });
  }

  private void display(PreferencesInfo info) {
    Label heading = new Label(Plugin.get().getName() + " plugin");
    heading.setStyleName("smallHeading");
    add(heading);
    HorizontalPanel p = new HorizontalPanel();
    add(p);

    Label label = new Label("Review Strategy:");
    p.add(label);
    label.getElement().getStyle().setMarginRight(5, Unit.PX);
    label.getElement().getStyle().setMarginTop(2, Unit.PX);
    final ListBox ui = new ListBox();
    p.add(ui);
    savedLabel = new Label("Saved");
    savedLabel.getElement().getStyle().setMarginLeft(5, Unit.PX);
    savedLabel.getElement().getStyle().setMarginTop(2, Unit.PX);
    savedLabel.setVisible(false);
    p.add(savedLabel);

    for (PreferencesInfo.ReviewStrategy v :
      PreferencesInfo.ReviewStrategy.values()) {
      ui.addItem(v.name(), v.name());
    }

    for (int i = 0; i < ui.getItemCount(); i++) {
      if (info.reviewStrategy().name().equals(ui.getValue(i))) {
        ui.setSelectedIndex(i);
        break;
      }
    }

    ui.addChangeHandler(new ChangeHandler() {
      @Override
      public void onChange(ChangeEvent event) {
        savedLabel.setVisible(false);
        PreferencesInfo info = PreferencesInfo.create();
        info.reviewStrategy(ui.getSelectedValue());
        new RestApi("accounts").id("self")
            .view(Plugin.get().getPluginName(), "preferences")
            .put(info, new AsyncCallback<PreferencesInfo>() {
              @Override
              public void onSuccess(PreferencesInfo result) {
                showSavedStatus();
              }

              @Override
              public void onFailure(Throwable caught) {
                // never invoked
              }
            });
      }
    });
  }

  private void showSavedStatus() {
    if (hideTimer != null) {
      hideTimer.cancel();
      hideTimer = null;
    }
    savedLabel.setVisible(true);
    hideTimer = new Timer() {
      @Override
      public void run() {
        savedLabel.setVisible(false);
        hideTimer = null;
      }
    };
    hideTimer.schedule(1000);
  }
}
