package org.robotframework.ide.eclipse.main.plugin.tableeditor.code;
import java.util.Comparator;
import java.util.List;
import org.eclipse.nebula.widgets.nattable.sort.ISortModel;
import org.eclipse.nebula.widgets.nattable.sort.SortDirectionEnum;
import org.robotframework.ide.eclipse.main.plugin.model.IRobotCodeHoldingElement;
import org.robotframework.ide.eclipse.main.plugin.model.RobotCodeHoldingElement;
import org.robotframework.ide.eclipse.main.plugin.model.RobotKeywordCall;
import org.robotframework.ide.eclipse.main.plugin.tableeditor.AddingToken;
import ca.odell.glazedlists.TreeList;
public class CodeElementsTreeFormat implements TreeList.Format<Object> {
private ISortModel sortModel;
public void setSortModel(final ISortModel treeSortModel) {
this.sortModel = treeSortModel;
}
@Override
public void getPath(final List<Object> path, final Object element) {
if (element instanceof RobotKeywordCall) {
path.add(((RobotKeywordCall) element).getParent());
} else if (element instanceof AddingToken) {
path.add(((AddingToken) element).getParent());
}
path.add(element);
}
@Override
public boolean allowsChildren(final Object element) {
return true;
}
@Override
public Comparator<? super Object> getComparator(final int depth) {
if (sortModel == null || sortModel.getSortDirection(0) == SortDirectionEnum.NONE) {
return null;
} else if (sortModel.getSortDirection(0) == SortDirectionEnum.ASC) {
return depth == 0 ? new CodeAlphabeticalComparator() : new CallsFileOrderComparator();
} else if (sortModel.getSortDirection(0) == SortDirectionEnum.DESC) {
return depth == 0 ? new ReverseComparator<>(new CodeAlphabeticalComparator())
: new CallsFileOrderComparator();
}
return null;
}
private static class CallsFileOrderComparator implements Comparator<Object> {
private final CodeAlphabeticalComparator comparator = new CodeAlphabeticalComparator();
@Override
public int compare(final Object o1, final Object o2) {
final IRobotCodeHoldingElement holder1 = getHolder(o1);
final IRobotCodeHoldingElement holder2 = getHolder(o2);
if (holder1 != holder2) {
return comparator.compare(holder1, holder2);
}
if (o1 instanceof RobotKeywordCall && o2 instanceof RobotKeywordCall) {
final RobotKeywordCall call1 = (RobotKeywordCall) o1;
final RobotKeywordCall call2 = (RobotKeywordCall) o2;
return call1 == call2 ? 0 : call1.getIndex() - call2.getIndex();
} else if (o1 instanceof RobotKeywordCall && o2 instanceof AddingToken) {
return -1;
} else if (o1 instanceof AddingToken && o2 instanceof RobotKeywordCall) {
return 1;
} else {
return 0;
}
}
private IRobotCodeHoldingElement getHolder(final Object o) {
if (o instanceof RobotKeywordCall) {
final RobotKeywordCall call = (RobotKeywordCall) o;
return call.getParent();
} else if (o instanceof AddingToken) {
final AddingToken token = (AddingToken) o;
return (IRobotCodeHoldingElement) token.getParent();
}
throw new IllegalStateException("Unknown element " + o.toString());
}
}
private static class CodeAlphabeticalComparator implements Comparator<Object> {
@Override
public int compare(final Object o1, final Object o2) {
final RobotCodeHoldingElement<?> elem1 = (RobotCodeHoldingElement<?>) o1;
final RobotCodeHoldingElement<?> elem2 = (RobotCodeHoldingElement<?>) o2;
final int result = elem1.getName().compareToIgnoreCase(elem2.getName());
// if there are two different elements with same name we compare them using indexes
return result != 0 || o1 == o2 ? result : elem1.getIndex() - elem2.getIndex();
}
}
private static class ReverseComparator<T> implements Comparator<T> {
private final Comparator<T> comparator;
public ReverseComparator(final Comparator<T> comparator) {
this.comparator = comparator;
}
@Override
public int compare(final T o1, final T o2) {
return comparator.compare(o2, o1);
}
}
}