/*
 * 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.codeInsight.template.impl;

import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;

import java.util.ArrayList;

public class TemplateSegments {
  private final ArrayList<RangeMarker> mySegments = new ArrayList<>();
  private final Editor myEditor;

  public TemplateSegments(Editor editor) {
    myEditor = editor;
  }

  public int getSegmentStart(int i) {
    RangeMarker rangeMarker = mySegments.get(i);
    return rangeMarker.getStartOffset();
  }

  public int getSegmentEnd(int i) {
    RangeMarker rangeMarker = mySegments.get(i);
    return rangeMarker.getEndOffset();
  }

  public boolean isValid(int i) {
    return mySegments.get(i).isValid();
  }

  public void removeAll() {
    for (RangeMarker segment : mySegments) {
      segment.dispose();
    }
    mySegments.clear();
  }

  public void addSegment(int start, int end) {
    RangeMarker rangeMarker = myEditor.getDocument().createRangeMarker(start, end);
    mySegments.add(rangeMarker);
  }

  public void setSegmentsGreedy(boolean greedy) {
    for (final RangeMarker segment : mySegments) {
      segment.setGreedyToRight(greedy);
      segment.setGreedyToLeft(greedy);
    }
  }

  public boolean isInvalid() {
    for (RangeMarker marker : mySegments) {
      if (!marker.isValid()) {
        return true;
      }
    }
    return false;
  }

  public void replaceSegmentAt(int index, int start, int end) {
    replaceSegmentAt(index, start, end, false);
  }

  public void replaceSegmentAt(int index, int start, int end, boolean preserveGreediness) {
    RangeMarker rangeMarker = mySegments.get(index);
    boolean greedyToLeft = rangeMarker.isGreedyToLeft();
    boolean greedyToRight = rangeMarker.isGreedyToRight();
    rangeMarker.dispose();
    
    Document doc = myEditor.getDocument();
    rangeMarker = doc.createRangeMarker(start, end);
    rangeMarker.setGreedyToLeft(greedyToLeft || !preserveGreediness);
    rangeMarker.setGreedyToRight(greedyToRight || !preserveGreediness);
    mySegments.set(index, rangeMarker);
  }

  public void setNeighboursGreedy(final int segmentNumber, final boolean greedy) {
    if (segmentNumber > 0) {
      final RangeMarker left = mySegments.get(segmentNumber - 1);
      left.setGreedyToLeft(greedy);
      left.setGreedyToRight(greedy);
    }
    if (segmentNumber + 1 < mySegments.size()) {
      final RangeMarker right = mySegments.get(segmentNumber + 1);
      right.setGreedyToLeft(greedy);
      right.setGreedyToRight(greedy);
    }
  }

  /**
   * IDEADEV-13618
   *
   * prevent two different segments to grow simultaneously if they both starts at the same offset.
   */
  public void lockSegmentAtTheSameOffsetIfAny(final int number) {
    if (number == -1) {
      return;
    }

    final RangeMarker current = mySegments.get(number);
    int offset = current.getStartOffset();

    for (int i = 0; i < mySegments.size(); i++) {
      if (i != number) {
        final RangeMarker segment = mySegments.get(i);
        final int startOffset2 = segment.getStartOffset();
        if (offset == startOffset2) {
          segment.setGreedyToLeft(false);
        }
      }
    }
  }

  public int getSegmentsCount() {
    return mySegments.size();
  }
}
@@ -810,23 +810,16 @@
 yList;%0A%0A
-public 
 class Te
@@ -942,23 +942,16 @@
 tor;%0A%0A  
-public 
 Template
@@ -998,39 +998,32 @@
  editor;%0A  %7D%0A%0A  
-public 
 int getSegmentSt
@@ -1124,39 +1124,32 @@
 ffset();%0A  %7D%0A%0A  
-public 
 int getSegmentEn
@@ -1246,39 +1246,32 @@
 ffset();%0A  %7D%0A%0A  
-public 
 boolean isValid(
@@ -1322,31 +1322,24 @@
 d();%0A  %7D%0A%0A  
-public 
 void removeA
@@ -1448,31 +1448,24 @@
 r();%0A  %7D%0A%0A  
-public 
 void addSegm
@@ -1606,39 +1606,32 @@
 Marker);%0A  %7D%0A%0A  
-public 
 void setSegments
@@ -1798,23 +1798,16 @@
 %0A  %7D%0A%0A  
-public 
 boolean 
@@ -1947,39 +1947,32 @@
 n false;%0A  %7D%0A%0A  
-public 
 void replaceSegm
@@ -2061,31 +2061,24 @@
 se);%0A  %7D%0A%0A  
-public 
 void replace
@@ -2634,23 +2634,16 @@
 %0A  %7D%0A%0A  
-public 
 void set
@@ -3221,23 +3221,16 @@
    */%0A  
-public 
 void loc
@@ -3727,15 +3727,8 @@
 %0A%0A  
-public 
 int 

decrease visibility