// 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 net.codemirror.lib;

import com.google.gerrit.client.diff.DisplaySide;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.user.client.rpc.AsyncCallback;

import net.codemirror.lib.TextMarker.FromTo;

/**
 * Glue to connect CodeMirror to be callable from GWT.
 *
 * @see <a href="http://codemirror.net/doc/manual.html#api">CodeMirror API</a>
 */
public class CodeMirror extends JavaScriptObject {
  public static void initLibrary(AsyncCallback<Void> cb) {
    Loader.initLibrary(cb);
  }

  public static native CodeMirror create(
      DisplaySide side,
      Element parent,
      Configuration cfg) /*-{
    var m = $wnd.CodeMirror(parent, cfg);
    m._sbs2_side = side;
    return m;
  }-*/;

  public final native void setOption(String option, boolean value) /*-{
    this.setOption(option, value);
  }-*/;

  public final native void setOption(String option, double value) /*-{
    this.setOption(option, value);
  }-*/;

  public final native void setOption(String option, String value) /*-{
    this.setOption(option, value);
  }-*/;

  public final native void setOption(String option, JavaScriptObject val) /*-{
    this.setOption(option, val);
  }-*/;

  public final native String getStringOption(String o) /*-{ return this.getOption(o) }-*/;
  public final native void setValue(String v) /*-{ this.setValue(v); }-*/;

  public final native void setWidth(double w) /*-{ this.setSize(w, null); }-*/;
  public final native void setWidth(String w) /*-{ this.setSize(w, null); }-*/;
  public final native void setHeight(double h) /*-{ this.setSize(null, h); }-*/;
  public final native void setHeight(String h) /*-{ this.setSize(null, h); }-*/;
  public final native double defaultCharWidth() /*-{ return this.defaultCharWidth() }-*/;
  public final native String getLine(int n) /*-{ return this.getLine(n) }-*/;

  public final native void refresh() /*-{ this.refresh(); }-*/;
  public final native Element getWrapperElement() /*-{ return this.getWrapperElement(); }-*/;

  public final native TextMarker markText(LineCharacter from, LineCharacter to,
      Configuration options) /*-{
    return this.markText(from, to, options);
  }-*/;

  public enum LineClassWhere {
    TEXT, BACKGROUND, WRAP
  }

  public final void addLineClass(int line, LineClassWhere where,
      String className) {
    addLineClassNative(line, where.name().toLowerCase(), className);
  }

  private final native void addLineClassNative(int line, String where,
      String lineClass) /*-{
    this.addLineClass(line, where, lineClass);
  }-*/;

  public final void addLineClass(LineHandle line, LineClassWhere where,
      String className) {
    addLineClassNative(line, where.name().toLowerCase(), className);
  }

  private final native void addLineClassNative(LineHandle line, String where,
      String lineClass) /*-{
    this.addLineClass(line, where, lineClass);
  }-*/;

  public final void removeLineClass(int line, LineClassWhere where,
      String className) {
    removeLineClassNative(line, where.name().toLowerCase(), className);
  }

  private final native void removeLineClassNative(int line, String where,
      String lineClass) /*-{
    this.removeLineClass(line, where, lineClass);
  }-*/;

  public final void removeLineClass(LineHandle line, LineClassWhere where,
      String className) {
    removeLineClassNative(line, where.name().toLowerCase(), className);
  }

  private final native void removeLineClassNative(LineHandle line, String where,
      String lineClass) /*-{
    this.removeLineClass(line, where, lineClass);
  }-*/;

  public final native void addWidget(LineCharacter pos, Element node,
      boolean scrollIntoView) /*-{
    this.addWidget(pos, node, scrollIntoView);
  }-*/;

  public final native LineWidget addLineWidget(int line, Element node,
      Configuration options) /*-{
    return this.addLineWidget(line, node, options);
  }-*/;

  public final native int lineAtHeight(double height) /*-{
    return this.lineAtHeight(height);
  }-*/;

  public final native int lineAtHeight(double height, String mode) /*-{
    return this.lineAtHeight(height, mode);
  }-*/;

  public final native double heightAtLine(int line) /*-{
    return this.heightAtLine(line);
  }-*/;

  public final native double heightAtLine(int line, String mode) /*-{
    return this.heightAtLine(line, mode);
  }-*/;

  public final native Rect charCoords(LineCharacter pos, String mode) /*-{
    return this.charCoords(pos, mode);
  }-*/;

  public final native CodeMirrorDoc getDoc() /*-{
    return this.getDoc();
  }-*/;

  public final native void scrollTo(double x, double y) /*-{
    this.scrollTo(x, y);
  }-*/;

  public final native void scrollToY(double y) /*-{
    this.scrollTo(null, y);
  }-*/;

  public final native ScrollInfo getScrollInfo() /*-{
    return this.getScrollInfo();
  }-*/;

  public final native Viewport getViewport() /*-{
    return this.getViewport();
  }-*/;

  public final native void operation(Runnable thunk) /*-{
    this.operation(function() {
      thunk.@java.lang.Runnable::run()();
    });
  }-*/;

  public final native void on(String event, Runnable thunk) /*-{
    this.on(event, $entry(function() {
      thunk.@java.lang.Runnable::run()();
    }));
  }-*/;

  public final native void on(String event, EventHandler handler) /*-{
    this.on(event, $entry(function(cm, e) {
      handler.@net.codemirror.lib.CodeMirror.EventHandler::handle(
        Lnet/codemirror/lib/CodeMirror;Lcom/google/gwt/dom/client/NativeEvent;)(cm, e);
    }));
  }-*/;

  public final native void on(String event, RenderLineHandler handler) /*-{
    this.on(event, $entry(function(cm, h, ele) {
      handler.@net.codemirror.lib.CodeMirror.RenderLineHandler::handle(
        Lnet/codemirror/lib/CodeMirror;Lnet/codemirror/lib/CodeMirror$LineHandle;
        Lcom/google/gwt/dom/client/Element;)(cm, h, ele);
    }));
  }-*/;

  public final native void on(String event, GutterClickHandler handler) /*-{
    this.on(event, $entry(function(cm, l, g, e) {
      handler.@net.codemirror.lib.CodeMirror.GutterClickHandler::handle(
        Lnet/codemirror/lib/CodeMirror;ILjava/lang/String;
        Lcom/google/gwt/dom/client/NativeEvent;)(cm, l, g, e);
    }));
  }-*/;

  public final native void on(String event, BeforeSelectionChangeHandler handler) /*-{
    this.on(event, $entry(function(cm, e) {
      handler.@net.codemirror.lib.CodeMirror.BeforeSelectionChangeHandler::handle(
        Lnet/codemirror/lib/CodeMirror;Lnet/codemirror/lib/LineCharacter;
        Lnet/codemirror/lib/LineCharacter;)(cm,e.anchor,e.head);
    }));
  }-*/;

  public final native LineCharacter getCursor() /*-{
    return this.getCursor();
  }-*/;

  public final native LineCharacter getCursor(String start) /*-{
    return this.getCursor(start);
  }-*/;

  public final FromTo getSelectedRange() {
    return FromTo.create(getCursor("start"), getCursor("end"));
  }

  public final native void setSelection(LineCharacter anchor) /*-{
    this.setSelection(anchor);
  }-*/;

  public final native void setSelection(LineCharacter anchor, LineCharacter head) /*-{
    this.setSelection(anchor, head);
  }-*/;

  public final native void setCursor(LineCharacter lineCh) /*-{
    this.setCursor(lineCh);
  }-*/;

  public final native boolean somethingSelected() /*-{
    return this.somethingSelected();
  }-*/;

  public final native boolean hasActiveLine() /*-{
    return !!this.state.activeLine;
  }-*/;

  public final native LineHandle getActiveLine() /*-{
    return this.state.activeLine;
  }-*/;

  public final native void setActiveLine(LineHandle line) /*-{
    this.state.activeLine = line;
  }-*/;

  public final native void addKeyMap(KeyMap map) /*-{ this.addKeyMap(map); }-*/;
  public final native void removeKeyMap(KeyMap map) /*-{ this.removeKeyMap(map); }-*/;

  public static final native LineCharacter pos(int line, int ch) /*-{
    return $wnd.CodeMirror.Pos(line, ch);
  }-*/;

  public static final native LineCharacter pos(int line) /*-{
    return $wnd.CodeMirror.Pos(line);
  }-*/;

  public final native LineHandle getLineHandle(int line) /*-{
    return this.getLineHandle(line);
  }-*/;

  public final native LineHandle getLineHandleVisualStart(int line) /*-{
    return this.getLineHandleVisualStart(line);
  }-*/;

  public final native int getLineNumber(LineHandle handle) /*-{
    return this.getLineNumber(handle);
  }-*/;

  public final native void focus() /*-{
    this.focus();
  }-*/;

  public final native Element getGutterElement() /*-{
    return this.getGutterElement();
  }-*/;

  public final native Element getSizer() /*-{
    return this.display.sizer;
  }-*/;

  public final native Element getMoverElement() /*-{
    return this.display.mover;
  }-*/;

  public final native Element getScrollbarV() /*-{
    return this.display.scrollbarV;
  }-*/;

  public static final native KeyMap cloneKeyMap(String name) /*-{
    var i = $wnd.CodeMirror.keyMap[name];
    var o = {};
    for (n in i)
      if (i.hasOwnProperty(n))
        o[n] = i[n];
    return o;
  }-*/;

  public final native void execCommand(String cmd) /*-{
    this.execCommand(cmd);
  }-*/;

  public static final native void addKeyMap(String name, KeyMap km) /*-{
    $wnd.CodeMirror.keyMap[name] = km;
  }-*/;

  public static final native void handleVimKey(CodeMirror cm, String key) /*-{
    $wnd.CodeMirror.Vim.handleKey(cm, key);
  }-*/;

  public static final native void mapVimKey(String alias, String actual) /*-{
    $wnd.CodeMirror.Vim.map(alias, actual);
  }-*/;

  public final native boolean hasVimSearchHighlight() /*-{
    return this.state.vim && this.state.vim.searchState_ &&
        !!this.state.vim.searchState_.getOverlay();
  }-*/;

  public final native DisplaySide side() /*-{ return this._sbs2_side }-*/;

  protected CodeMirror() {
  }

  public static class Viewport extends JavaScriptObject {
    public final native int getFrom() /*-{ return this.from; }-*/;
    public final native int getTo() /*-{ return this.to; }-*/;
    public final boolean contains(int line) {
      return getFrom() <= line && line < getTo();
    }

    protected Viewport() {
    }
  }

  public static class LineHandle extends JavaScriptObject {
    protected LineHandle(){
    }
  }

  public interface EventHandler {
    public void handle(CodeMirror instance, NativeEvent event);
  }

  public interface RenderLineHandler {
    public void handle(CodeMirror instance, LineHandle handle, Element element);
  }

  public interface GutterClickHandler {
    public void handle(CodeMirror instance, int line, String gutter,
        NativeEvent clickEvent);
  }

  public interface BeforeSelectionChangeHandler {
    public void handle(CodeMirror instance, LineCharacter anchor, LineCharacter head);
  }
}
