/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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.intellij.injected.editor;

import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.markup.TextAttributes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * @author Alexey
 */
public class CaretModelWindow implements CaretModel {
  private final CaretModel myDelegate;
  private final EditorEx myHostEditor;
  private final EditorWindow myEditorWindow;
  private final Map<Caret, InjectedCaret> myInjectedCaretMap = new WeakHashMap<Caret, InjectedCaret>();

  public CaretModelWindow(CaretModel delegate, EditorWindow editorWindow) {
    myDelegate = delegate;
    myHostEditor = (EditorEx)editorWindow.getDelegate();
    myEditorWindow = editorWindow;
  }

  @Override
  public void moveCaretRelatively(final int columnShift,
                                  final int lineShift,
                                  final boolean withSelection,
                                  final boolean blockSelection,
                                  final boolean scrollToCaret) {
    myDelegate.moveCaretRelatively(columnShift, lineShift, withSelection, blockSelection, scrollToCaret);
  }

  @Override
  public void moveToLogicalPosition(@NotNull final LogicalPosition pos) {
    LogicalPosition hostPos = myEditorWindow.injectedToHost(pos);
    myDelegate.moveToLogicalPosition(hostPos);
  }

  @Override
  public void moveToVisualPosition(@NotNull final VisualPosition pos) {
    LogicalPosition hostPos = myEditorWindow.injectedToHost(myEditorWindow.visualToLogicalPosition(pos));
    myDelegate.moveToLogicalPosition(hostPos);
  }

  @Override
  public void moveToOffset(int offset) {
    moveToOffset(offset, false);
  }

  @Override
  public void moveToOffset(final int offset, boolean locateBeforeSoftWrap) {
    int hostOffset = myEditorWindow.getDocument().injectedToHost(offset);
    myDelegate.moveToOffset(hostOffset, locateBeforeSoftWrap);
  }

  @Override
  @NotNull
  public LogicalPosition getLogicalPosition() {
    LogicalPosition hostPos = myDelegate.getLogicalPosition();
    return myEditorWindow.hostToInjected(hostPos);
  }

  @Override
  @NotNull
  public VisualPosition getVisualPosition() {
    LogicalPosition logicalPosition = getLogicalPosition();
    return myEditorWindow.logicalToVisualPosition(logicalPosition);
  }

  @Override
  public int getOffset() {
    return myEditorWindow.getDocument().hostToInjected(myDelegate.getOffset());
  }

  @Override
  public boolean isUpToDate() {
    return myDelegate.isUpToDate();
  }

  private final ListenerWrapperMap<CaretListener> myCaretListeners = new ListenerWrapperMap<CaretListener>();
  @Override
  public void addCaretListener(@NotNull final CaretListener listener) {
    CaretListener wrapper = new CaretAdapter() {
      @Override
      public void caretPositionChanged(CaretEvent e) {
        if (!myEditorWindow.getDocument().isValid()) return; // injected document can be destroyed by now
        CaretEvent event = new CaretEvent(myEditorWindow, createInjectedCaret(e.getCaret()),
                                          myEditorWindow.hostToInjected(e.getOldPosition()),
                                          myEditorWindow.hostToInjected(e.getNewPosition()));
        listener.caretPositionChanged(event);
      }
    };
    myCaretListeners.registerWrapper(listener, wrapper);
    myDelegate.addCaretListener(wrapper);
  }

  @Override
  public void removeCaretListener(@NotNull final CaretListener listener) {
    CaretListener wrapper = myCaretListeners.removeWrapper(listener);
    if (wrapper != null) {
      myDelegate.removeCaretListener(wrapper);
    }
  }

  public void disposeModel() {
    for (CaretListener wrapper : myCaretListeners.wrappers()) {
      myDelegate.removeCaretListener(wrapper);
    }
    myCaretListeners.clear();
  }

  @Override
  public int getVisualLineStart() {
    return myEditorWindow.getDocument().hostToInjected(myDelegate.getVisualLineStart());
  }

  @Override
  public int getVisualLineEnd() {
    return myEditorWindow.getDocument().hostToInjected(myDelegate.getVisualLineEnd());
  }

  @Override
  public TextAttributes getTextAttributes() {
    return myDelegate.getTextAttributes();
  }

  @Override
  public boolean supportsMultipleCarets() {
    return myDelegate.supportsMultipleCarets();
  }

  @NotNull
  @Override
  public Caret getCurrentCaret() {
    return createInjectedCaret(myDelegate.getCurrentCaret());
  }

  @NotNull
  @Override
  public Caret getPrimaryCaret() {
    return createInjectedCaret(myDelegate.getPrimaryCaret());
  }

  @Override
  public int getCaretCount() {
    return myDelegate.getCaretCount();
  }

  @NotNull
  @Override
  public List<Caret> getAllCarets() {
    List<Caret> hostCarets = myDelegate.getAllCarets();
    List<Caret> carets = new ArrayList<Caret>(hostCarets.size());
    for (Caret hostCaret : hostCarets) {
      carets.add(createInjectedCaret(hostCaret));
    }
    return carets;
  }

  @Nullable
  @Override
  public Caret getCaretAt(@NotNull VisualPosition pos) {
    LogicalPosition hostPos = myEditorWindow.injectedToHost(myEditorWindow.visualToLogicalPosition(pos));
    Caret caret = myDelegate.getCaretAt(myHostEditor.logicalToVisualPosition(hostPos));
    return createInjectedCaret(caret);
  }

  @Nullable
  @Override
  public Caret addCaret(@NotNull VisualPosition pos) {
    LogicalPosition hostPos = myEditorWindow.injectedToHost(myEditorWindow.visualToLogicalPosition(pos));
    Caret caret = myDelegate.addCaret(myHostEditor.logicalToVisualPosition(hostPos));
    return createInjectedCaret(caret);
  }

  @Override
  public boolean removeCaret(@NotNull Caret caret) {
    if (caret instanceof InjectedCaret) {
      caret = ((InjectedCaret)caret).myDelegate;
    }
    return myDelegate.removeCaret(caret);
  }

  @Override
  public void removeSecondaryCarets() {
    myDelegate.removeSecondaryCarets();
  }

  @Override
  public void setCaretsAndSelections(@NotNull List<CaretState> caretStates) {
    List<CaretState> convertedStates = convertCaretStates(caretStates);
    myDelegate.setCaretsAndSelections(convertedStates);
  }

  @Override
  public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
    List<CaretState> convertedStates = convertCaretStates(caretStates);
    myDelegate.setCaretsAndSelections(convertedStates, updateSystemSelection);
  }

  private List<CaretState> convertCaretStates(List<CaretState> caretStates) {
    List<CaretState> convertedStates = new ArrayList<CaretState>(caretStates.size());
    for (CaretState state : caretStates) {
      convertedStates.add(new CaretState(injectedToHost(state.getCaretPosition()),
                                         injectedToHost(state.getSelectionStart()),
                                         injectedToHost(state.getSelectionEnd())));
    }
    return convertedStates;
  }

  private LogicalPosition injectedToHost(@Nullable LogicalPosition position) {
    return position == null ? null : myEditorWindow.injectedToHost(position);
  }

  @NotNull
  @Override
  public List<CaretState> getCaretsAndSelections() {
    List<CaretState> caretsAndSelections = myDelegate.getCaretsAndSelections();
    List<CaretState> convertedStates = new ArrayList<CaretState>(caretsAndSelections.size());
    for (CaretState state : caretsAndSelections) {
      convertedStates.add(new CaretState(hostToInjected(state.getCaretPosition()),
                                         hostToInjected(state.getSelectionStart()),
                                         hostToInjected(state.getSelectionEnd())));
    }
    return convertedStates;
  }

  private LogicalPosition hostToInjected(@Nullable LogicalPosition position) {
    return position == null ? null : myEditorWindow.hostToInjected(position);
  }

  private InjectedCaret createInjectedCaret(Caret caret) {
    if (caret == null) {
      return null;
    }
    synchronized (myInjectedCaretMap) {
      InjectedCaret injectedCaret = myInjectedCaretMap.get(caret);
      if (injectedCaret == null) {
        injectedCaret = new InjectedCaret(myEditorWindow, caret);
        myInjectedCaretMap.put(caret, injectedCaret);
      }
      return injectedCaret;
    }
  }

  @Override
  public void runForEachCaret(final @NotNull CaretAction action) {
    myDelegate.runForEachCaret(new CaretAction() {
      @Override
      public void perform(Caret caret) {
        action.perform(createInjectedCaret(caret));
      }
    });
  }

  @Override
  public void runForEachCaret(@NotNull final CaretAction action, boolean reverseOrder) {
    myDelegate.runForEachCaret(new CaretAction() {
      @Override
      public void perform(Caret caret) {
        action.perform(createInjectedCaret(caret));
      }
    }, reverseOrder);
  }

  @Override
  public void runBatchCaretOperation(@NotNull Runnable runnable) {
    myDelegate.runBatchCaretOperation(runnable);
  }
}
