// 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", new Runnable() {
      @Override
      public void run() {
        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();
  }
}
