// Copyright (C) 2008 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 static com.google.gerrit.client.FormatUtil.mediumFormat;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.AccountLinkPanel;
import com.google.gerrit.client.ui.BranchLink;
import com.google.gerrit.client.ui.CommentedActionDialog;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.client.ui.ProjectSearchLink;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.SubmitTypeRecord;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
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.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.clippy.client.CopyableLabel;

public class ChangeInfoBlock extends Composite {
  private static final int R_CHANGE_ID = 0;
  private static final int R_OWNER = 1;
  private static final int R_PROJECT = 2;
  private static final int R_BRANCH = 3;
  private static final int R_TOPIC = 4;
  private static final int R_UPLOADED = 5;
  private static final int R_UPDATED = 6;
  private static final int R_SUBMIT_TYPE = 7;
  private static final int R_STATUS = 8;
  private static final int R_MERGE_TEST = 9;
  private static final int R_CNT = 10;

  private final Grid table;

  public ChangeInfoBlock() {
    if (Gerrit.getConfig().testChangeMerge()) {
      table = new Grid(R_CNT, 2);
    } else {
      table = new Grid(R_CNT - 1, 2);
    }
    table.setStyleName(Gerrit.RESOURCES.css().infoBlock());
    table.addStyleName(Gerrit.RESOURCES.css().changeInfoBlock());

    initRow(R_CHANGE_ID, "Change-Id: ");
    initRow(R_OWNER, Util.C.changeInfoBlockOwner());
    initRow(R_PROJECT, Util.C.changeInfoBlockProject());
    initRow(R_BRANCH, Util.C.changeInfoBlockBranch());
    initRow(R_TOPIC, Util.C.changeInfoBlockTopic());
    initRow(R_UPLOADED, Util.C.changeInfoBlockUploaded());
    initRow(R_UPDATED, Util.C.changeInfoBlockUpdated());
    initRow(R_STATUS, Util.C.changeInfoBlockStatus());
    initRow(R_SUBMIT_TYPE, Util.C.changeInfoBlockSubmitType());
    if (Gerrit.getConfig().testChangeMerge()) {
      initRow(R_MERGE_TEST, Util.C.changeInfoBlockCanMerge());
    }

    final CellFormatter fmt = table.getCellFormatter();
    fmt.addStyleName(0, 0, Gerrit.RESOURCES.css().topmost());
    fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().topmost());
    fmt.addStyleName(R_CHANGE_ID, 1, Gerrit.RESOURCES.css().changeid());
    fmt.addStyleName(R_CNT - 2, 0, Gerrit.RESOURCES.css().bottomheader());

    initWidget(table);
  }

  private void initRow(final int row, final String name) {
    table.setText(row, 0, name);
    table.getCellFormatter().addStyleName(row, 0, Gerrit.RESOURCES.css().header());
  }

  public void display(final Change chg, final AccountInfoCache acc,
      SubmitTypeRecord submitTypeRecord) {
    final Branch.NameKey dst = chg.getDest();

    CopyableLabel changeIdLabel =
        new CopyableLabel("Change-Id: " + chg.getKey().get());
    changeIdLabel.setPreviewText(chg.getKey().get());
    table.setWidget(R_CHANGE_ID, 1, changeIdLabel);

    table.setWidget(R_OWNER, 1, AccountLinkPanel.link(acc, chg.getOwner()));

    final FlowPanel p = new FlowPanel();
    p.add(new ProjectSearchLink(chg.getProject()));
    p.add(new InlineHyperlink(chg.getProject().get(),
        PageLinks.toProject(chg.getProject())));
    table.setWidget(R_PROJECT, 1, p);

    table.setWidget(R_BRANCH, 1, new BranchLink(dst.getShortName(), chg
        .getProject(), chg.getStatus(), dst.get(), null));
    table.setWidget(R_TOPIC, 1, topic(chg));
    table.setText(R_UPLOADED, 1, mediumFormat(chg.getCreatedOn()));
    table.setText(R_UPDATED, 1, mediumFormat(chg.getLastUpdatedOn()));
    table.setText(R_STATUS, 1, Util.toLongString(chg.getStatus()));
    String submitType;
    if (submitTypeRecord.status == SubmitTypeRecord.Status.OK) {
      submitType = com.google.gerrit.client.admin.Util
              .toLongString(submitTypeRecord.type);
    } else {
      submitType = submitTypeRecord.status.name();
    }
    table.setText(R_SUBMIT_TYPE, 1, submitType);
    final Change.Status status = chg.getStatus();
    if (Gerrit.getConfig().testChangeMerge()) {
      if (status.equals(Change.Status.NEW) || status.equals(Change.Status.DRAFT)) {
        table.getRowFormatter().setVisible(R_MERGE_TEST, true);
        table.setText(R_MERGE_TEST, 1, chg.isMergeable() ? Util.C
            .changeInfoBlockCanMergeYes() : Util.C.changeInfoBlockCanMergeNo());
      } else {
        table.getRowFormatter().setVisible(R_MERGE_TEST, false);
      }
    }

    if (status.isClosed()) {
      table.getCellFormatter().addStyleName(R_STATUS, 1, Gerrit.RESOURCES.css().closedstate());
      table.getRowFormatter().setVisible(R_SUBMIT_TYPE, false);
    } else {
      table.getCellFormatter().removeStyleName(R_STATUS, 1, Gerrit.RESOURCES.css().closedstate());
      table.getRowFormatter().setVisible(R_SUBMIT_TYPE, true);
    }
  }

  public Widget topic(final Change chg) {
    final Branch.NameKey dst = chg.getDest();

    FlowPanel fp = new FlowPanel();
    fp.addStyleName(Gerrit.RESOURCES.css().changeInfoTopicPanel());
    fp.add(new BranchLink(chg.getTopic(), chg.getProject(), chg.getStatus(),
           dst.get(), chg.getTopic()));

    ChangeDetailCache detailCache = ChangeCache.get(chg.getId()).getChangeDetailCache();
    ChangeDetail changeDetail = detailCache.get();

    if (changeDetail.canEditTopicName()) {
      final Image edit = new Image(Gerrit.RESOURCES.edit());
      edit.addStyleName(Gerrit.RESOURCES.css().link());
      edit.setTitle(Util.C.changeInfoBlockTopicAlterTopicToolTip());
      edit.addClickHandler(new  ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          new AlterTopicDialog(chg).center();
        }
      });
      fp.add(edit);
    }

    return fp;
  }

  private class AlterTopicDialog extends CommentedActionDialog<ChangeDetail>
      implements KeyPressHandler {
    TextBox newTopic;
    Change change;

    AlterTopicDialog(Change chg) {
      super(Util.C.alterTopicTitle(), Util.C.headingAlterTopicMessage(),
          new ChangeDetailCache.IgnoreErrorCallback());
      change = chg;

      newTopic = new TextBox();
      newTopic.addKeyPressHandler(this);
      setFocusOn(newTopic);
      panel.insert(newTopic, 0);
      panel.insert(new InlineLabel(Util.C.alterTopicLabel()), 0);
    }

    @Override
    protected void onLoad() {
      super.onLoad();
      newTopic.setText(change.getTopic());
    }

    private void doTopicEdit() {
      String topic = newTopic.getText();
      ChangeApi.topic(change.getId().get(), topic, getMessageText(),
        new GerritCallback<String>() {
        @Override
        public void onSuccess(String result) {
          sent = true;
          Gerrit.display(PageLinks.toChange(change.getId()));
          hide();
        }

        @Override
        public void onFailure(final Throwable caught) {
          enableButtons(true);
          super.onFailure(caught);
        }});
    }

    @Override
    public void onSend() {
      doTopicEdit();
    }

    @Override
    public void onKeyPress(KeyPressEvent event) {
      if (event.getSource() == newTopic
          && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
        doTopicEdit();
      }
    }
  }
}
