// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.resource.text.modes;
import java.util.ArrayList;
import java.util.List;
import javax.swing.text.BadLocationException;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.folding.Fold;
import org.fife.ui.rsyntaxtextarea.folding.FoldParser;
import org.fife.ui.rsyntaxtextarea.folding.FoldType;
/**
* A fold parser for BCS scripts. It supports folding of multiline comments
* and IF/END blocks.
*/
public class BCSFoldParser implements FoldParser
{
private static final char[] BLOCK_START = {'I', 'F'};
private static final char[] BLOCK_END = {'E', 'N', 'D'};
private static final char[] MLC_END = {'*', '/'};
public BCSFoldParser()
{
}
@Override
public List<Fold> getFolds(RSyntaxTextArea textArea)
{
List<Fold> folds = new ArrayList<Fold>();
Fold curFold = null;
int lineCount = textArea.getLineCount();
boolean inMLC = false;
int mlcStart = 0;
try {
for (int line = 0; line < lineCount; line++) {
Token t = textArea.getTokenListForLine(line);
while (t != null && t.isPaintable()) {
if (t.isComment()) {
// continuing an MLC from a previous line?
if (inMLC) {
// found the end of the MLC starting on the previous line...
if (t.endsWith(MLC_END)) {
int mlcEnd = t.getEndOffset() - 1;
if (curFold == null) {
curFold = new Fold(FoldType.COMMENT, textArea, mlcStart);
curFold.setEndOffset(mlcEnd);
folds.add(curFold);
curFold = null;
} else {
curFold = curFold.createChild(FoldType.COMMENT, mlcStart);
curFold.setEndOffset(mlcEnd);
curFold = curFold.getParent();
}
inMLC = false;
mlcStart = 0;
}
// otherwise this MLC is continuing on to yet another line
} else {
// if we're in an MLC that ends on a later line...
if (t.getType() == Token.COMMENT_MULTILINE && !t.endsWith(MLC_END)) {
inMLC = true;
mlcStart = t.getOffset();
}
}
} else if (t.is(Token.RESERVED_WORD, BLOCK_START)) {
// a script block starts
if (curFold == null) {
curFold = new Fold(FoldType.CODE, textArea, t.getOffset());
}
} else if (t.is(Token.RESERVED_WORD, BLOCK_END)) {
// a script block ends - we don't need to consider nested blocks
if (curFold != null) {
curFold.setEndOffset(t.getEndOffset() - 1);
folds.add(curFold);
curFold = null;
}
}
t = t.getNextToken();
}
}
} catch (BadLocationException e) {
e.printStackTrace();
}
return folds;
}
}