// 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.patches;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.CommentPanel;
import com.google.gerrit.common.changes.Side;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.core.client.JavaScriptObject;
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.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.NpTextArea;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.VoidResult;

import java.sql.Timestamp;

public class CommentEditorPanel extends CommentPanel implements ClickHandler,
    DoubleClickHandler {
  private static final int INITIAL_COLS = 60;
  private static final int INITIAL_LINES = 5;
  private static final int MAX_LINES = 30;
  private static final AsyncCallback<VoidResult> NULL_CALLBACK =
      new AsyncCallback<VoidResult>() {
        @Override
        public void onFailure(Throwable caught) {
        }

        @Override
        public void onSuccess(VoidResult result) {
        }
      };

  private PatchLineComment comment;

  private final NpTextArea text;
  private final Button edit;
  private final Button save;
  private final Button cancel;
  private final Button discard;
  private final Timer expandTimer;

  public CommentEditorPanel(final PatchLineComment plc,
      final CommentLinkProcessor commentLinkProcessor) {
    super(commentLinkProcessor);
    comment = plc;

    addStyleName(Gerrit.RESOURCES.css().commentEditorPanel());
    setAuthorNameText(Gerrit.getUserAccountInfo(), PatchUtil.C.draft());
    setMessageText(plc.getMessage());
    addDoubleClickHandler(this);

    expandTimer = new Timer() {
      @Override
      public void run() {
        expandText();
      }
    };
    text = new NpTextArea();
    text.setText(comment.getMessage());
    text.setCharacterWidth(INITIAL_COLS);
    text.setVisibleLines(INITIAL_LINES);
    text.setSpellCheck(true);
    text.addKeyDownHandler(new KeyDownHandler() {
      @Override
      public void onKeyDown(final KeyDownEvent event) {
        if ((event.isControlKeyDown() || event.isMetaKeyDown())
            && !event.isAltKeyDown() && !event.isShiftKeyDown()) {
          switch (event.getNativeKeyCode()) {
            case 's':
            case 'S':
              event.preventDefault();
              onSave(NULL_CALLBACK);
              return;
          }
        }

        expandTimer.schedule(250);
      }
    });
    addContent(text);

    edit = new Button();
    edit.setText(PatchUtil.C.buttonEdit());
    edit.addClickHandler(this);
    addButton(edit);

    save = new Button();
    save.setText(PatchUtil.C.buttonSave());
    save.addClickHandler(this);
    addButton(save);

    cancel = new Button();
    cancel.setText(PatchUtil.C.buttonCancel());
    cancel.addClickHandler(this);
    addButton(cancel);

    discard = new Button();
    discard.setText(PatchUtil.C.buttonDiscard());
    discard.addClickHandler(this);
    addButton(discard);

    setOpen(true);
    if (isNew()) {
      edit();
    } else {
      render();
    }
  }

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

  private void edit() {
    if (!isOpen()) {
      setOpen(true);
    }
    text.setText(comment.getMessage());
    expandText();
    stateEdit(true);
    text.setFocus(true);
  }

  private void render() {
    final Timestamp on = comment.getWrittenOn();
    setDateText(PatchUtil.M.draftSaved(new java.util.Date(on.getTime())));
    setMessageText(comment.getMessage());
    stateEdit(false);
  }

  private void stateEdit(final boolean inEdit) {
    expandTimer.cancel();
    setMessageTextVisible(!inEdit);
    edit.setVisible(!inEdit);

    if (inEdit) {
      text.setVisible(true);
    } else {
      text.setFocus(false);
      text.setVisible(false);
    }

    save.setVisible(inEdit);
    cancel.setVisible(inEdit && !isNew());
    discard.setVisible(inEdit);
  }

  void setFocus(final boolean take) {
    if (take && !isOpen()) {
      setOpen(true);
    }
    if (text.isVisible()) {
      text.setFocus(take);
    } else if (take) {
      edit();
    }
  }

  boolean isNew() {
    return comment.getKey().get() == null;
  }

  public PatchLineComment getComment() {
    return comment;
  }

  @Override
  public void onDoubleClick(final DoubleClickEvent event) {
    edit();
  }

  @Override
  public void onClick(final ClickEvent event) {
    final Widget sender = (Widget) event.getSource();
    if (sender == edit) {
      edit();

    } else if (sender == save) {
      onSave(NULL_CALLBACK);

    } else if (sender == cancel) {
      render();

    } else if (sender == discard) {
      onDiscard();
    }
  }

  public void saveDraft(AsyncCallback<VoidResult> onSave) {
    if (isOpen() && text.isVisible()) {
      onSave(onSave);
    } else {
      onSave.onSuccess(VoidResult.INSTANCE);
    }
  }

  private void onSave(final AsyncCallback<VoidResult> onSave) {
    expandTimer.cancel();
    final String txt = text.getText().trim();
    if ("".equals(txt)) {
      return;
    }

    comment.setMessage(txt);
    text.setFocus(false);
    text.setReadOnly(true);
    save.setEnabled(false);
    cancel.setEnabled(false);
    discard.setEnabled(false);

    final PatchSet.Id psId = comment.getKey().getParentKey().getParentKey();
    final boolean wasNew = isNew();
    GerritCallback<CommentInfo> cb = new GerritCallback<CommentInfo>() {
      public void onSuccess(CommentInfo result) {
        notifyDraftDelta(wasNew ? 1 : 0);
        comment = toComment(psId, comment.getKey().getParentKey().get(), result);
        text.setReadOnly(false);
        save.setEnabled(true);
        cancel.setEnabled(true);
        discard.setEnabled(true);
        render();
        onSave.onSuccess(VoidResult.INSTANCE);
      }

      @Override
      public void onFailure(final Throwable caught) {
        text.setReadOnly(false);
        text.setFocus(true);
        save.setEnabled(true);
        cancel.setEnabled(true);
        discard.setEnabled(true);
        super.onFailure(caught);
        onSave.onFailure(caught);
      }
    };
    CommentInfo input = toInput(comment);
    if (wasNew) {
      CommentApi.createDraft(psId, input, cb);
    } else {
      CommentApi.updateDraft(psId, input.id(), input, cb);
    }
  }

  private void notifyDraftDelta(final int delta) {
    CommentEditorContainer c = getContainer();
    if (c != null) {
      c.notifyDraftDelta(delta);
    }
  }

  private void onDiscard() {
    expandTimer.cancel();
    if (isNew()) {
      text.setFocus(false);
      removeUI();
      return;
    }

    text.setFocus(false);
    text.setReadOnly(true);
    save.setEnabled(false);
    cancel.setEnabled(false);
    discard.setEnabled(false);

    CommentApi.deleteDraft(
        comment.getKey().getParentKey().getParentKey(),
        comment.getKey().get(),
        new GerritCallback<JavaScriptObject>() {
          public void onSuccess(JavaScriptObject result) {
            notifyDraftDelta(-1);
            removeUI();
          }

          @Override
          public void onFailure(final Throwable caught) {
            text.setReadOnly(false);
            text.setFocus(true);
            save.setEnabled(true);
            cancel.setEnabled(true);
            discard.setEnabled(true);
            super.onFailure(caught);
          }
        });
  }

  private void removeUI() {
    CommentEditorContainer c = getContainer();
    if (c != null) {
      c.remove(this);
    }
  }

  private CommentEditorContainer getContainer() {
    Widget p = getParent();
    while (p != null) {
      if (p instanceof CommentEditorContainer) {
        return (CommentEditorContainer) p;
      }
      p = p.getParent();
    }
    return null;
  }

  public static CommentInfo toInput(PatchLineComment c) {
    CommentInfo i = CommentInfo.createObject().cast();
    i.id(c.getKey().get());
    i.path(c.getKey().getParentKey().get());
    i.side(c.getSide() == 0 ? Side.PARENT : Side.REVISION);
    if (c.getLine() > 0) {
      i.line(c.getLine());
    }
    i.in_reply_to(c.getParentUuid());
    i.message(c.getMessage());
    return i;
  }

  public static PatchLineComment toComment(PatchSet.Id ps,
      String path,
      CommentInfo i) {
    PatchLineComment p = new PatchLineComment(
        new PatchLineComment.Key(
            new Patch.Key(ps, path),
            i.id()),
        i.line(),
        Gerrit.getUserAccount().getId(),
        i.in_reply_to(),
        i.updated());
    p.setMessage(i.message());
    p.setSide((short) (i.side() == Side.PARENT ? 0 : 1));
    return p;
  }
}
