/*
* Copyright 2003-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 jetbrains.mps.nodeEditor;
import jetbrains.mps.openapi.editor.cells.SubstituteAction;
import jetbrains.mps.smodel.presentation.NodePresentationUtil;
import jetbrains.mps.util.PatternUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class SubstituteActionUtil {
static final int CAN_SUBSTITUTE_VIA_PATTERN = 2;
static final int CAN_SUBSTITUTE_VIA_SEARCH = 1;
static final int CANT_SUBSTITUTE = 0;
//utility class
private SubstituteActionUtil() {
}
@Deprecated
public static Comparator<SubstituteAction> createComparator(String pattern) {
return new SubstituteActionComparator(pattern);
}
static int getSubstituteRate(SubstituteAction action, String pattern) {
boolean canSubstitute = action.canSubstitute(pattern);
if (canSubstitute) {
return CAN_SUBSTITUTE_VIA_PATTERN;
} else {
if (pattern == null || pattern.isEmpty()) {
return CANT_SUBSTITUTE;
}
String matchingText = action.getMatchingText(pattern);
if (matchingText == null || matchingText.isEmpty()) {
return CANT_SUBSTITUTE;
}
if (action.canSubstitute(matchingText) && matchingText.toLowerCase().contains(pattern.toLowerCase())) {
return CAN_SUBSTITUTE_VIA_SEARCH;
}
return CANT_SUBSTITUTE;
}
}
public static boolean canSubstitute(SubstituteAction action, String pattern) {
return getSubstituteRate(action, pattern) != CANT_SUBSTITUTE;
}
public static String createText(@NotNull SubstituteAction action, @Nullable String pattern, @NotNull String color) {
String visibleMatchingText = action.getVisibleMatchingText(pattern);
if (pattern == null || visibleMatchingText == null) {
return visibleMatchingText;
}
//whitespaces are not highlighted
List<Integer> indexesOfColoredChars = getIndexes(action, IntelligentInputUtil.trimLeft(pattern), visibleMatchingText);
if (indexesOfColoredChars.isEmpty()) {
return visibleMatchingText;
}
StringBuilder builder = new StringBuilder("<html>");
Iterator<Integer> coloredIndexIterator = indexesOfColoredChars.iterator();
int currentColoredIndex = coloredIndexIterator.next();
boolean isTextColoredNow = false;
for (int i = 0; i < visibleMatchingText.length(); i++) {
if (i == currentColoredIndex && !isTextColoredNow) {
builder.append("<font color='");
builder.append(color);
builder.append("'>");
isTextColoredNow = true;
}
char c = visibleMatchingText.charAt(i);
if (c == '<') {
builder.append("<");
} else if (c == '>') {
builder.append(">");
} else if (c == ' ') {
builder.append(" ");
} else {
builder.append(c);
}
if (isTextColoredNow) {
boolean hasNext = coloredIndexIterator.hasNext();
if (hasNext) {
currentColoredIndex = coloredIndexIterator.next();
}
if (!hasNext || currentColoredIndex > i + 1) {
builder.append("</font>");
isTextColoredNow = false;
}
}
}
builder.append("</html>");
return builder.toString();
}
@NotNull
private static List<Integer> getIndexes(SubstituteAction action, String pattern, String visibleMatchingText) {
List<Integer> indexList = new ArrayList<Integer>();
int substituteRate = getSubstituteRate(action, pattern);
if (substituteRate == CANT_SUBSTITUTE) {
return indexList;
}
if (substituteRate == CAN_SUBSTITUTE_VIA_PATTERN) {
return PatternUtil.getIndexes(pattern, false, visibleMatchingText);
} else if (substituteRate == CAN_SUBSTITUTE_VIA_SEARCH) {
int curIndex = visibleMatchingText.toLowerCase().indexOf(pattern.toLowerCase());
indexList.add(curIndex);
for (int i = 1; i < pattern.length(); i++) {
indexList.add(curIndex + i);
}
}
return indexList;
}
}