// 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.AccountLink;
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 ChangeDetail changeDetail,
      final AccountInfoCache acc, SubmitTypeRecord submitTypeRecord) {
    final Change chg = changeDetail.getChange();
    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, AccountLink.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(changeDetail));
    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 ChangeDetail changeDetail) {
    final Change chg = changeDetail.getChange();
    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()));

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