//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.patches.PatchUtil;
import com.google.gwt.core.client.GWT;
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.resources.client.CssResource;
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.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;

import net.codemirror.lib.CodeMirror;
import net.codemirror.lib.Configuration;
import net.codemirror.lib.LineWidget;
import net.codemirror.lib.TextMarker;
import net.codemirror.lib.TextMarker.FromTo;

/** The Widget that handles expanding of skipped lines */
class SkipBar extends Composite {
  interface Binder extends UiBinder<HTMLPanel, SkipBar> {}
  private static final Binder uiBinder = GWT.create(Binder.class);
  private static final int NUM_ROWS_TO_EXPAND = 10;
  private static final int UP_DOWN_THRESHOLD = 30;

  interface SkipBarStyle extends CssResource {
    String noExpand();
  }

  @UiField(provided=true) Anchor skipNum;
  @UiField(provided=true) Anchor upArrow;
  @UiField(provided=true) Anchor downArrow;
  @UiField SkipBarStyle style;

  private final SkipManager manager;
  private final CodeMirror cm;

  private LineWidget lineWidget;
  private TextMarker textMarker;
  private SkipBar otherBar;

  SkipBar(SkipManager manager, final CodeMirror cm) {
    this.manager = manager;
    this.cm = cm;

    skipNum = new Anchor(true);
    upArrow = new Anchor(true);
    downArrow = new Anchor(true);
    initWidget(uiBinder.createAndBindUi(this));
    addDomHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        cm.focus();
      }
    }, ClickEvent.getType());
  }

  void collapse(int start, int end, boolean attach) {
    if (attach) {
      boolean isNew = lineWidget == null;
      Configuration cfg = Configuration.create()
          .set("coverGutter", true)
          .set("noHScroll", true);
      if (start == 0) { // First line workaround
        lineWidget = cm.addLineWidget(end + 1, getElement(), cfg.set("above", true));
      } else {
        lineWidget = cm.addLineWidget(start - 1, getElement(), cfg);
      }
      if (isNew) {
        lineWidget.onFirstRedraw(new Runnable() {
          @Override
          public void run() {
            int w = cm.getGutterElement().getOffsetWidth();
            getElement().getStyle().setPaddingLeft(w, Unit.PX);
          }
        });
      }
    }

    textMarker = cm.markText(
        CodeMirror.pos(start, 0),
        CodeMirror.pos(end),
        Configuration.create()
          .set("collapsed", true)
          .set("inclusiveLeft", true)
          .set("inclusiveRight", true));

    textMarker.on("beforeCursorEnter", new Runnable() {
      @Override
      public void run() {
        expandAll();
      }
    });

    int skipped = end - start + 1;
    if (skipped <= UP_DOWN_THRESHOLD) {
      addStyleName(style.noExpand());
    } else {
      upArrow.setHTML(PatchUtil.M.expandBefore(NUM_ROWS_TO_EXPAND));
      downArrow.setHTML(PatchUtil.M.expandAfter(NUM_ROWS_TO_EXPAND));
    }
    skipNum.setText(Integer.toString(skipped));
  }

  static void link(SkipBar barA, SkipBar barB) {
    barA.otherBar = barB;
    barB.otherBar = barA;
  }

  private void clearMarkerAndWidget() {
    textMarker.clear();
    lineWidget.clear();
  }

  void expandBefore(int cnt) {
    expandSideBefore(cnt);
    otherBar.expandSideBefore(cnt);
    manager.getOverviewBar().refresh();
  }

  private void expandSideBefore(int cnt) {
    FromTo range = textMarker.find();
    int oldStart = range.getFrom().getLine();
    int newStart = oldStart + cnt;
    int end = range.getTo().getLine();
    clearMarkerAndWidget();
    collapse(newStart, end, true);
    updateSelection();
  }

  void expandSideAll() {
    clearMarkerAndWidget();
    removeFromParent();
  }

  private void expandAfter() {
    FromTo range = textMarker.find();
    int start = range.getFrom().getLine();
    int oldEnd = range.getTo().getLine();
    int newEnd = oldEnd - NUM_ROWS_TO_EXPAND;
    boolean attach = start == 0;
    if (attach) {
      clearMarkerAndWidget();
    } else {
      textMarker.clear();
    }
    collapse(start, newEnd, attach);
    updateSelection();
  }

  private void updateSelection() {
    if (cm.somethingSelected()) {
      FromTo sel = cm.getSelectedRange();
      cm.setSelection(sel.getFrom(), sel.getTo());
    }
  }

  @UiHandler("skipNum")
  void onExpandAll(ClickEvent e) {
    expandAll();
    updateSelection();
    otherBar.updateSelection();
    cm.focus();
  }

  private void expandAll() {
    expandSideAll();
    otherBar.expandSideAll();
    manager.remove(this, otherBar);
    manager.getOverviewBar().refresh();
  }

  @UiHandler("upArrow")
  void onExpandBefore(ClickEvent e) {
    expandBefore(NUM_ROWS_TO_EXPAND);
    cm.focus();
  }

  @UiHandler("downArrow")
  void onExpandAfter(ClickEvent e) {
    expandAfter();
    otherBar.expandAfter();
    manager.getOverviewBar().refresh();
    cm.focus();
  }
}
