// Copyright (C) 2014 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.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Widget;
import net.codemirror.lib.CodeMirror;
import net.codemirror.lib.CodeMirror.RegisteredHandler;
import net.codemirror.lib.Pos;

/** Displayed on the vertical scrollbar to place a chunk or comment. */
class ScrollbarAnnotation extends Widget implements ClickHandler {
  private final CodeMirror cm;
  private CodeMirror cmB;
  private RegisteredHandler refresh;
  private Pos from;
  private Pos to;
  private double scale;

  ScrollbarAnnotation(CodeMirror cm) {
    setElement((Element) DOM.createDiv());
    getElement().setAttribute("not-content", "true");
    addDomHandler(this, ClickEvent.getType());
    this.cm = cm;
    this.cmB = cm;
  }

  void remove() {
    removeFromParent();
  }

  void at(int line) {
    at(Pos.create(line), Pos.create(line + 1));
  }

  void at(Pos from, Pos to) {
    this.from = from;
    this.to = to;
  }

  void renderOn(CodeMirror cm) {
    this.cmB = cm;
  }

  @Override
  protected void onLoad() {
    cmB.getWrapperElement().appendChild(getElement());
    refresh =
        cmB.on(
            "refresh",
            () -> {
              if (updateScale()) {
                updatePosition();
              }
            });
    updateScale();
    updatePosition();
  }

  @Override
  protected void onUnload() {
    cmB.off("refresh", refresh);
  }

  private boolean updateScale() {
    double old = scale;
    double docHeight = cmB.getWrapperElement().getClientHeight();
    double lineHeight = cmB.heightAtLine(cmB.lastLine() + 1, "local");
    scale = (docHeight - cmB.barHeight()) / lineHeight;
    return old != scale;
  }

  private void updatePosition() {
    double top = cm.charCoords(from, "local").top() * scale;
    double bottom = cm.charCoords(to, "local").bottom() * scale;

    Element e = getElement();
    e.getStyle().setTop(top, Unit.PX);
    e.getStyle().setWidth(Math.max(2, cm.barWidth() - 1), Unit.PX);
    e.getStyle().setHeight(Math.max(3, bottom - top), Unit.PX);
  }

  @Override
  public void onClick(ClickEvent event) {
    event.stopPropagation();

    int line = from.line();
    int h = to.line() - line;
    if (h > 5) {
      // Map click inside of the annotation to the relative position
      // within the region covered by the annotation.
      double s = ((double) event.getY()) / getElement().getOffsetHeight();
      line += (int) (s * h);
    }

    double y = cm.heightAtLine(line, "local");
    double viewport = cm.getScrollInfo().clientHeight();
    cm.setCursor(from);
    cm.scrollTo(0, y - 0.5 * viewport);
    cm.focus();
  }
}
