package cc.warlock.core.client;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
public class WarlockStringMarker {
private IWarlockStyle style;
private int start;
private int end;
private LinkedList<WarlockStringMarker> subMarkers = new LinkedList<WarlockStringMarker>();
public WarlockStringMarker(IWarlockStyle style, int start, int end) {
this.style = style;
this.start = start;
this.end = end;
}
public IWarlockStyle getStyle() {
return style;
}
public void setStyle(IWarlockStyle style) {
this.style = style;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public LinkedList<WarlockStringMarker> getSubMarkers() {
return subMarkers;
}
public void addMarker(WarlockStringMarker marker) {
subMarkers.add(marker);
}
public WarlockStringMarker clone() {
WarlockStringMarker clone = new WarlockStringMarker(style, start, end);
for(WarlockStringMarker marker : subMarkers) {
clone.addMarker(marker.clone());
}
return clone;
}
public WarlockStringMarker copy(int offset) {
WarlockStringMarker copy = new WarlockStringMarker(style, start + offset, end + offset);
for(WarlockStringMarker marker : subMarkers) {
copy.addMarker(marker.copy(offset));
}
return copy;
}
public WarlockStringMarker copy(int offset, int length) {
int newStart = start + offset;
if(newStart < 0)
newStart = 0;
int newEnd = end + offset;
if(newEnd > length)
newEnd = length;
WarlockStringMarker copy = new WarlockStringMarker(style, newStart, newEnd);
for(WarlockStringMarker marker : subMarkers) {
if(marker.getEnd() + offset > 0)
copy.addMarker(marker.copy(offset, length));
}
return copy;
}
public void move(int offset) {
this.start += offset;
if(this.start < 0)
start = 0;
this.end += offset;
if(this.end < 0)
this.end = 0;
for(Iterator<WarlockStringMarker> iter = subMarkers.iterator(); iter.hasNext();) {
WarlockStringMarker marker = iter.next();
if(marker.getEnd() + offset < 0)
iter.remove();
else
marker.move(offset);
}
}
public boolean hasStyleNamed(String styleName) {
String name = style.getName();
if(name != null && name.equals(styleName))
return true;
for(WarlockStringMarker marker : subMarkers) {
if(marker.hasStyleNamed(styleName))
return true;
}
return false;
}
public void clear() {
subMarkers.clear();
}
public String getName() {
if(style == null)
return null;
return style.getName();
}
public String getComponentName() {
if(style == null)
return null;
return style.getComponentName();
}
public WarlockStringMarker getMarkerByComponent(String componentName) {
String myName = getComponentName();
if(myName != null && myName.equals(componentName))
return this;
for(WarlockStringMarker subMarker : subMarkers) {
WarlockStringMarker marker = subMarker.getMarkerByComponent(componentName);
if(marker != null)
return marker;
}
return null;
}
// helper function to remove a style from a list
public static void removeStyle(Collection<WarlockStringMarker> list, IWarlockStyle style) {
Iterator<WarlockStringMarker> iter = list.iterator();
while(iter.hasNext()) {
WarlockStringMarker cur = iter.next();
if(style == cur.style) {
iter.remove();
break;
}
}
}
// this function removes the first "delta" amount of characters
public static boolean updateMarkers(int delta, WarlockStringMarker afterMarker,
Collection<WarlockStringMarker> markerList) {
// remove markers between start and end.
// all markers after start need to be adjusted by offset.
// returns whether or not the afterMarker was found
boolean started = false;
for(Iterator<WarlockStringMarker> iter = markerList.iterator();
iter.hasNext(); )
{
WarlockStringMarker marker = iter.next();
if(marker == afterMarker) {
started = true;
continue;
}
if(!started) {
started = updateMarkers(delta, afterMarker, marker.getSubMarkers());
if(started)
marker.setEnd(marker.getEnd() + delta);
} else
marker.move(delta);
}
return started;
}
public IWarlockStyle getBaseStyle(WarlockStringMarker marker) {
if(this == marker)
return style;
for(WarlockStringMarker subMarker : subMarkers) {
IWarlockStyle baseStyle = subMarker.getBaseStyle(marker);
if(baseStyle != null)
return baseStyle.mergeWith(style);
}
return null;
}
}