// Copyright (C) 2009 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.changes;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.Link;
import com.google.gerrit.client.data.ApprovalType;
import com.google.gerrit.client.patches.LineCommentPanel;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.reviewdb.ApprovalCategory;
import com.google.gerrit.client.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.client.reviewdb.Change;
import com.google.gerrit.client.reviewdb.ChangeApproval;
import com.google.gerrit.client.reviewdb.Patch;
import com.google.gerrit.client.reviewdb.PatchLineComment;
import com.google.gerrit.client.reviewdb.PatchSet;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.AccountScreen;
import com.google.gerrit.client.ui.PatchLink;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormHandler;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormSubmitEvent;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtjsonrpc.client.VoidResult;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class PublishCommentScreen extends AccountScreen implements
    ClickListener {
  private final PatchSet.Id patchSetId;
  private Collection<ValueRadioButton> approvalButtons;
  private ChangeDescriptionBlock descBlock;
  private Panel approvalPanel;
  private TextArea message;
  private Panel draftsPanel;
  private Button send;
  private Button cancel;
  private boolean displayedOnce;

  public PublishCommentScreen(final PatchSet.Id psi) {
    super(Util.M.publishComments(psi.getParentKey().get(), psi.get()));
    addStyleName("gerrit-PublishCommentsScreen");
    patchSetId = psi;
  }

  @Override
  public Object getScreenCacheToken() {
    return new ScreenCacheToken(patchSetId);
  }

  @Override
  public void onLoad() {
    if (message == null) {
      approvalButtons = new ArrayList<ValueRadioButton>();
      descBlock = new ChangeDescriptionBlock();
      add(descBlock);

      final FormPanel form = new FormPanel();
      final FlowPanel body = new FlowPanel();
      form.setWidget(body);
      form.addFormHandler(new FormHandler() {
        public void onSubmit(FormSubmitEvent event) {
          event.setCancelled(true);
        }

        public void onSubmitComplete(FormSubmitCompleteEvent event) {
        }
      });
      add(form);

      approvalPanel = new FlowPanel();
      body.add(approvalPanel);
      initMessage(body);

      draftsPanel = new FlowPanel();
      body.add(draftsPanel);

      final FlowPanel buttonRow = new FlowPanel();
      buttonRow.setStyleName("gerrit-CommentEditor-Buttons");
      body.add(buttonRow);

      send = new Button(Util.C.buttonPublishCommentsSend());
      send.addClickListener(this);
      buttonRow.add(send);

      cancel = new Button(Util.C.buttonPublishCommentsCancel());
      cancel.addClickListener(this);
      buttonRow.add(cancel);
    }

    super.onLoad();
    message.setFocus(true);

    send.setEnabled(false);
    Util.DETAIL_SVC.patchSetPublishDetail(patchSetId,
        new GerritCallback<PatchSetPublishDetail>() {
          public void onSuccess(final PatchSetPublishDetail result) {
            send.setEnabled(true);
            display(result);
          }
        });
  }

  public void onClick(final Widget sender) {
    if (send == sender) {
      onSend();
    } else if (cancel == sender) {
      Gerrit.uncache(this);
      goChange();
    }
  }

  private void initMessage(final Panel body) {
    body.add(new SmallHeading(Util.C.headingCoverMessage()));

    final VerticalPanel mwrap = new VerticalPanel();
    mwrap.setStyleName("gerrit-CoverMessage");
    body.add(mwrap);

    message = new TextArea();
    message.setCharacterWidth(60);
    message.setVisibleLines(10);
    DOM.setElementPropertyBoolean(message.getElement(), "spellcheck", true);
    mwrap.add(message);
  }

  private void initApprovals(final PatchSetPublishDetail r, final Panel body) {
    for (final ApprovalType ct : Common.getGerritConfig().getApprovalTypes()) {
      if (r.isAllowed(ct.getCategory().getId())) {
        initApprovalType(r, body, ct);
      }
    }
  }

  private void initApprovalType(final PatchSetPublishDetail r,
      final Panel body, final ApprovalType ct) {
    body.add(new SmallHeading(ct.getCategory().getName() + ":"));

    final VerticalPanel vp = new VerticalPanel();
    vp.setStyleName("gerrit-ApprovalCategoryList");
    final List<ApprovalCategoryValue> lst =
        new ArrayList<ApprovalCategoryValue>(ct.getValues());
    Collections.reverse(lst);
    final ApprovalCategory.Id catId = ct.getCategory().getId();
    final Set<ApprovalCategoryValue.Id> allowed = r.getAllowed(catId);
    final ChangeApproval prior = r.getChangeApproval(catId);

    for (final ApprovalCategoryValue buttonValue : lst) {
      if (!allowed.contains(buttonValue.getId())) {
        continue;
      }

      final ValueRadioButton b =
          new ValueRadioButton(buttonValue, ct.getCategory().getName());
      final StringBuilder m = new StringBuilder();
      if (buttonValue.getValue() == 0) {
        m.append(' ');
      } else if (buttonValue.getValue() > 0) {
        m.append('+');
      }
      m.append(buttonValue.getValue());
      m.append(' ');
      m.append(buttonValue.getName());
      b.setText(m.toString());
      b.setChecked(prior != null ? buttonValue.getValue() == prior.getValue()
          : buttonValue.getValue() == 0);
      approvalButtons.add(b);
      vp.add(b);
    }
    body.add(vp);
  }

  private void display(final PatchSetPublishDetail r) {
    descBlock.display(r.getChange(), r.getPatchSetInfo(), r.getAccounts());

    if (!displayedOnce) {
      if (r.getChange().getStatus().isOpen()) {
        initApprovals(r, approvalPanel);
      }
    }

    draftsPanel.clear();
    if (!r.getDrafts().isEmpty()) {
      draftsPanel.add(new SmallHeading(Util.C.headingPatchComments()));

      Panel panel = null;
      String priorFile = "";
      for (final PatchLineComment c : r.getDrafts()) {
        final Patch.Key patchKey = c.getKey().getParentKey();
        final String fn = patchKey.get();
        if (!fn.equals(priorFile)) {
          panel = new FlowPanel();
          panel.addStyleName("gerrit-PatchComments");
          draftsPanel.add(panel);

          panel.add(new PatchLink.SideBySide(fn, patchKey));
          priorFile = fn;
        }

        Label m;

        m = new DoubleClickLinkLabel(patchKey);
        m.setText(Util.M.lineHeader(c.getLine()));
        m.setStyleName("gerrit-LineHeader");
        panel.add(m);

        m = new DoubleClickLinkLabel(patchKey);
        SafeHtml.set(m.getElement(), LineCommentPanel.toSafeHtml(c));
        m.setStyleName("gerrit-PatchLineComment");
        panel.add(m);
      }
    }

    displayedOnce = true;
  }

  private void onSend() {
    final Map<ApprovalCategory.Id, ApprovalCategoryValue.Id> values =
        new HashMap<ApprovalCategory.Id, ApprovalCategoryValue.Id>();
    for (final ValueRadioButton b : approvalButtons) {
      if (b.isChecked()) {
        values.put(b.value.getCategoryId(), b.value.getId());
      }
    }

    PatchUtil.DETAIL_SVC.publishComments(patchSetId, message.getText().trim(),
        new HashSet<ApprovalCategoryValue.Id>(values.values()),
        new GerritCallback<VoidResult>() {
          public void onSuccess(final VoidResult result) {
            goChange();
          }
        });
  }

  private void goChange() {
    final Change.Id ck = patchSetId.getParentKey();
    Gerrit.display(Link.toChange(ck), new ChangeScreen(ck));
  }

  private static class ValueRadioButton extends RadioButton {
    final ApprovalCategoryValue value;

    ValueRadioButton(final ApprovalCategoryValue v, final String label) {
      super(label);
      value = v;
    }
  }

  private static class DoubleClickLinkLabel extends Label {
    private final Patch.Key patchKey;

    DoubleClickLinkLabel(final Patch.Key p) {
      patchKey = p;
      sinkEvents(Event.ONDBLCLICK);
    }

    @Override
    public void onBrowserEvent(final Event event) {
      switch (DOM.eventGetType(event)) {
        case Event.ONDBLCLICK:
          History.newItem(Link.toPatchSideBySide(patchKey), true);
          break;
      }
      super.onBrowserEvent(event);
    }
  }

  private static final class ScreenCacheToken {
    private final PatchSet.Id patchSetId;

    ScreenCacheToken(final PatchSet.Id psi) {
      patchSetId = psi;
    }

    @Override
    public boolean equals(Object obj) {
      if (obj instanceof ScreenCacheToken) {
        final ScreenCacheToken c = (ScreenCacheToken) obj;
        return patchSetId.equals(c.patchSetId);
      }
      return false;
    }

    @Override
    public int hashCode() {
      return patchSetId.hashCode();
    }
  }
}
