package org.jetbrains.plugins.coursecreator.format;

import com.google.gson.annotations.Expose;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.LogicalPosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.coursecreator.CCProjectService;

import java.util.ArrayList;
import java.util.List;

public class TaskFile {
  @Expose public List<TaskWindow> task_windows = new ArrayList<TaskWindow>();
  public int myIndex;

  public TaskFile() {}

  public void addTaskWindow(@NotNull final TaskWindow taskWindow, int index) {
    taskWindow.setIndex(index);
    task_windows.add(taskWindow);
  }

  public List<TaskWindow> getTaskWindows() {
    return task_windows;
  }

  public void setIndex(int index) {
    myIndex = index;
  }


  /**
   * @param pos position in editor
   * @return task window located in specified position or null if there is no task window in this position
   */
  @Nullable
  public TaskWindow getTaskWindow(@NotNull final Document document, @NotNull final LogicalPosition pos) {
    int line = pos.line;
    if (line >= document.getLineCount()) {
      return null;
    }
    int column = pos.column;
    int offset = document.getLineStartOffset(line) + column;
    for (TaskWindow tw : task_windows) {
      if (tw.getLine() <= line) {
        int twStartOffset = tw.getRealStartOffset(document);
        final int length = tw.getReplacementLength() > 0 ? tw.getReplacementLength() : 0;
        int twEndOffset = twStartOffset + length;
        if (twStartOffset <= offset && offset <= twEndOffset) {
          return tw;
        }
      }
    }
    return null;
  }

  /**
   * Updates task window lines
   *
   * @param startLine lines greater than this line and including this line will be updated
   * @param change    change to be added to line numbers
   */
  public void incrementLines(int startLine, int change) {
    for (TaskWindow taskTaskWindow : task_windows) {
      if (taskTaskWindow.getLine() >= startLine) {
        taskTaskWindow.setLine(taskTaskWindow.getLine() + change);
      }
    }
  }

  /**
   * Updates windows in specific line
   *
   * @param lineChange         change in line number
   * @param line               line to be updated
   * @param newEndOffsetInLine distance from line start to end of inserted fragment
   * @param oldEndOffsetInLine distance from line start to end of changed fragment
   */
  public void updateLine(int lineChange, int line, int newEndOffsetInLine, int oldEndOffsetInLine) {
    for (TaskWindow w : task_windows) {
      if ((w.getLine() == line) && (w.getStart() >= oldEndOffsetInLine)) {
        int distance = w.getStart() - oldEndOffsetInLine;
        boolean coveredByPrevTW = false;
        int prevIndex = w.getIndex() - 1;
        if (CCProjectService.indexIsValid(prevIndex, task_windows)) {
          TaskWindow prevTW = task_windows.get(prevIndex);
          if (prevTW.getLine() == line) {
            int endOffset = prevTW.getStart() + prevTW.getLength();
            if (endOffset >= newEndOffsetInLine) {
              coveredByPrevTW = true;
            }
          }
        }
        if (lineChange != 0 || newEndOffsetInLine <= w.getStart() || coveredByPrevTW) {
          w.setStart(distance + newEndOffsetInLine);
          w.setLine(line + lineChange);
        }
      }
    }
  }

  public void copy(@NotNull final TaskFile target) {
    target.setIndex(myIndex);
    for (TaskWindow taskWindow : task_windows) {
      TaskWindow savedWindow = new TaskWindow(taskWindow.getLine(), taskWindow.getStart(),
                                    taskWindow.getLength(), "");
      target.getTaskWindows().add(savedWindow);
      savedWindow.setIndex(taskWindow.getIndex());
    }
  }

  public void update(@NotNull final TaskFile source) {
    for (TaskWindow taskWindow : source.getTaskWindows()) {
      TaskWindow taskWindowUpdated = task_windows.get(taskWindow.getIndex() - 1);
      taskWindowUpdated.setLine(taskWindow.getLine());
      taskWindowUpdated.setStart(taskWindow.getStart());
    }
  }
}
