// Copyright (C) 2013 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.diff;

import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
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.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.NpTextArea;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;

import net.codemirror.lib.CodeMirror;

/** An HtmlPanel for displaying and editing a draft */
class DraftBox extends CommentBox {
  interface Binder extends UiBinder<HTMLPanel, DraftBox> {}
  private static final Binder uiBinder = GWT.create(Binder.class);

  private static final int INITIAL_LINES = 5;
  private static final int MAX_LINES = 30;

  private final CommentLinkProcessor linkProcessor;
  private final PatchSet.Id psId;
  private final boolean expandAll;
  private CommentInfo comment;
  private PublishedBox replyToBox;
  private Timer expandTimer;
  private Timer resizeTimer;
  private int editAreaHeight;
  private boolean autoClosed;
  private CallbackGroup pendingGroup;

  @UiField Widget header;
  @UiField Element summary;
  @UiField Element date;

  @UiField Element p_view;
  @UiField HTML message;
  @UiField Button edit;
  @UiField Button discard1;

  @UiField Element p_edit;
  @UiField NpTextArea editArea;
  @UiField Button save;
  @UiField Button cancel;
  @UiField Button discard2;

  DraftBox(
      CommentGroup group,
      CommentLinkProcessor clp,
      PatchSet.Id id,
      CommentInfo info,
      boolean expandAllComments) {
    super(group, info.range());

    linkProcessor = clp;
    psId = id;
    expandAll = expandAllComments;
    initWidget(uiBinder.createAndBindUi(this));

    expandTimer = new Timer() {
      @Override
      public void run() {
        expandText();
      }
    };
    set(info);

    header.addDomHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        if (!isEdit()) {
          if (autoClosed && !isOpen()) {
            setOpen(true);
            setEdit(true);
          } else {
            setOpen(!isOpen());
          }
        }
      }
    }, ClickEvent.getType());

    addDomHandler(new DoubleClickHandler() {
      @Override
      public void onDoubleClick(DoubleClickEvent event) {
        if (isEdit()) {
          editArea.setFocus(true);
        } else {
          setOpen(true);
          setEdit(true);
        }
      }
    }, DoubleClickEvent.getType());

    initResizeHandler();
  }

  private void set(CommentInfo info) {
    autoClosed = !expandAll && info.message() != null && info.message().length() < 70;
    date.setInnerText(FormatUtil.shortFormatDayTime(info.updated()));
    if (info.message() != null) {
      String msg = info.message().trim();
      summary.setInnerText(msg);
      message.setHTML(linkProcessor.apply(
          new SafeHtmlBuilder().append(msg).wikify()));
    }
    comment = info;
  }

  @Override
  CommentInfo getCommentInfo() {
    return comment;
  }

  @Override
  boolean isOpen() {
    return UIObject.isVisible(p_view);
  }

  @Override
  void setOpen(boolean open) {
    UIObject.setVisible(summary, !open);
    UIObject.setVisible(p_view, open);
    super.setOpen(open);
  }

  private void expandText() {
    double cols = editArea.getCharacterWidth();
    int rows = 2;
    for (String line : editArea.getValue().split("\n")) {
      rows += Math.ceil((1.0 + line.length()) / cols);
    }
    rows = Math.max(INITIAL_LINES, Math.min(rows, MAX_LINES));
    if (editArea.getVisibleLines() != rows) {
      editArea.setVisibleLines(rows);
    }
    editAreaHeight = editArea.getOffsetHeight();
    getCommentGroup().resize();
  }

  boolean isEdit() {
    return UIObject.isVisible(p_edit);
  }

  void setEdit(boolean edit) {
    UIObject.setVisible(summary, false);
    UIObject.setVisible(p_view, !edit);
    UIObject.setVisible(p_edit, edit);

    setRangeHighlight(edit);
    if (edit) {
      String msg = comment.message() != null
          ? comment.message().trim()
          : "";
      editArea.setValue(msg);
      cancel.setVisible(!isNew());
      expandText();
      editAreaHeight = editArea.getOffsetHeight();

      final int len = msg.length();
      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
        @Override
        public void execute() {
          editArea.setFocus(true);
          if (len > 0) {
            editArea.setCursorPos(len);
          }
        }
      });
    } else {
      expandTimer.cancel();
      resizeTimer.cancel();
    }
    getCommentManager().setUnsaved(this, edit);
    getCommentGroup().resize();
  }

  PublishedBox getReplyToBox() {
    return replyToBox;
  }

  void setReplyToBox(PublishedBox box) {
    replyToBox = box;
  }

  @Override
  protected void onUnload() {
    expandTimer.cancel();
    resizeTimer.cancel();
    super.onUnload();
  }

  private void removeUI() {
    if (replyToBox != null) {
      replyToBox.unregisterReplyBox();
    }

    getCommentManager().setUnsaved(this, false);
    setRangeHighlight(false);
    clearRange();
    getAnnotation().remove();
    getCommentGroup().remove(this);
    getCm().focus();
  }

  private void restoreSelection() {
    if (getFromTo() != null && comment.inReplyTo() == null) {
      getCm().setSelection(getFromTo().from(), getFromTo().to());
    }
  }

  @UiHandler("message")
  void onMessageClick(ClickEvent e) {
    e.stopPropagation();
  }

  @UiHandler("message")
  void onMessageDoubleClick(@SuppressWarnings("unused") DoubleClickEvent e) {
    setEdit(true);
  }

  @UiHandler("edit")
  void onEdit(ClickEvent e) {
    e.stopPropagation();
    setEdit(true);
  }

  @UiHandler("save")
  void onSave(ClickEvent e) {
    e.stopPropagation();
    CallbackGroup group = new CallbackGroup();
    save(group);
    group.done();
  }

  void save(CallbackGroup group) {
    if (pendingGroup != null) {
      pendingGroup.addListener(group);
      return;
    }

    String message = editArea.getValue().trim();
    if (message.length() == 0) {
      return;
    }

    CommentInfo input = CommentInfo.copy(comment);
    input.message(message);
    enableEdit(false);

    pendingGroup = group;
    GerritCallback<CommentInfo> cb = new GerritCallback<CommentInfo>() {
      @Override
      public void onSuccess(CommentInfo result) {
        enableEdit(true);
        pendingGroup = null;
        set(result);
        setEdit(false);
        if (autoClosed) {
          setOpen(false);
        }
        getCommentManager().setUnsaved(DraftBox.this, false);
      }

      @Override
      public void onFailure(Throwable e) {
        enableEdit(true);
        pendingGroup = null;
        super.onFailure(e);
      }
    };
    if (input.id() == null) {
      CommentApi.createDraft(psId, input, group.add(cb));
    } else {
      CommentApi.updateDraft(psId, input.id(), input, group.add(cb));
    }
    CodeMirror cm = getCm();
    cm.vim().handleKey("<Esc>");
    cm.focus();
  }

  private void enableEdit(boolean on) {
    editArea.setEnabled(on);
    save.setEnabled(on);
    cancel.setEnabled(on);
    discard2.setEnabled(on);
  }

  @UiHandler("cancel")
  void onCancel(ClickEvent e) {
    e.stopPropagation();
    if (isNew() && !isDirty()) {
      removeUI();
      restoreSelection();
    } else {
      setEdit(false);
      if (autoClosed) {
        setOpen(false);
      }
      getCm().focus();
    }
  }

  @UiHandler({"discard1", "discard2"})
  void onDiscard(ClickEvent e) {
    e.stopPropagation();
    if (isNew()) {
      removeUI();
      restoreSelection();
    } else {
      setEdit(false);
      pendingGroup = new CallbackGroup();
      CommentApi.deleteDraft(psId, comment.id(),
          pendingGroup.addFinal(new GerritCallback<JavaScriptObject>() {
        @Override
        public void onSuccess(JavaScriptObject result) {
          pendingGroup = null;
          removeUI();
        }
      }));
    }
  }

  @UiHandler("editArea")
  void onKeyDown(KeyDownEvent e) {
    resizeTimer.cancel();
    if ((e.isControlKeyDown() || e.isMetaKeyDown())
        && !e.isAltKeyDown() && !e.isShiftKeyDown()) {
      switch (e.getNativeKeyCode()) {
        case 's':
        case 'S':
          e.preventDefault();
          CallbackGroup group = new CallbackGroup();
          save(group);
          group.done();
          return;
      }
    } else if (e.getNativeKeyCode() == KeyCodes.KEY_ESCAPE && !isDirty()) {
      if (isNew()) {
        removeUI();
        restoreSelection();
        return;
      } else {
        setEdit(false);
        if (autoClosed) {
          setOpen(false);
        }
        getCm().focus();
        return;
      }
    }
    expandTimer.schedule(250);
  }

  @UiHandler("editArea")
  void onBlur(@SuppressWarnings("unused") BlurEvent e) {
    resizeTimer.cancel();
  }

  private void initResizeHandler() {
    resizeTimer = new Timer() {
      @Override
      public void run() {
        getCommentGroup().resize();
      }
    };

    addDomHandler(new MouseMoveHandler() {
      @Override
      public void onMouseMove(MouseMoveEvent event) {
        int h = editArea.getOffsetHeight();
        if (isEdit() && h != editAreaHeight) {
          getCommentGroup().resize();
          resizeTimer.scheduleRepeating(50);
          editAreaHeight = h;
        }
      }
    }, MouseMoveEvent.getType());

    addDomHandler(new MouseUpHandler() {
      @Override
      public void onMouseUp(MouseUpEvent event) {
        resizeTimer.cancel();
        getCommentGroup().resize();
      }
    }, MouseUpEvent.getType());
  }

  private boolean isNew() {
    return comment.id() == null;
  }

  private boolean isDirty() {
    String msg = editArea.getValue().trim();
    if (isNew()) {
      return msg.length() > 0;
    }
    return !msg.equals(comment.message() != null
        ? comment.message().trim()
        : "");
  }
}
