// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.search;
import java.awt.Component;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.infinity.datatype.ResourceRef;
import org.infinity.resource.AbstractStruct;
import org.infinity.resource.Resource;
import org.infinity.resource.StructEntry;
import org.infinity.resource.are.Actor;
import org.infinity.resource.are.Container;
import org.infinity.resource.are.Door;
import org.infinity.resource.are.ITEPoint;
import org.infinity.resource.bcs.BcsResource;
import org.infinity.resource.cre.CreResource;
import org.infinity.resource.dlg.AbstractCode;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.resource.text.PlainTextResource;
public final class ScriptReferenceSearcher extends AbstractReferenceSearcher
{
private String targetResRef;
private Pattern cutscene;
public ScriptReferenceSearcher(ResourceEntry targetEntry, Component parent)
{
super(targetEntry, new String[]{"ARE", "BCS", "CHR", "CRE", "DLG", "INI"}, parent);
this.targetResRef = targetEntry.getResourceName().substring(0,
targetEntry.getResourceName().indexOf('.'));
this.cutscene = Pattern.compile("StartCutScene(\""
+ targetResRef + "\")", Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
}
@Override
protected void search(ResourceEntry entry, Resource resource)
{
if (resource instanceof BcsResource) {
// TODO: avoid decompilation
String text = ((BcsResource) resource).getText();
if (cutscene.matcher(text).find()) {
addHit(entry, null, null);
}
} else if (resource instanceof PlainTextResource) {
searchText(entry, (PlainTextResource)resource);
} else {
searchStruct(entry, (AbstractStruct)resource);
}
}
private void searchStruct(ResourceEntry entry, AbstractStruct struct)
{
for (int i = 0; i < struct.getFieldCount(); i++) {
StructEntry o = struct.getField(i);
if (o instanceof ResourceRef &&
((ResourceRef)o).getResourceName().equalsIgnoreCase(targetEntry.toString())) {
ResourceRef ref = (ResourceRef)o;
if (struct instanceof CreResource) {
addHit(entry, entry.getSearchString(), ref);
} else if (struct instanceof Actor) {
addHit(entry, struct.getField(20).toString(), ref);
} else {
addHit(entry, null, ref);
}
}
else if (o instanceof Actor ||
o instanceof Container ||
o instanceof Door ||
o instanceof ITEPoint) {
searchStruct(entry, (AbstractStruct)o);
}
else if (o instanceof AbstractCode) {
String text = o.toString();
if (cutscene.matcher(text).find()) {
addHit(entry, o.getName(), o);
}
}
}
}
private void searchText(ResourceEntry entry, PlainTextResource text)
{
String name = getTargetEntry().getResourceName();
int idx = name.lastIndexOf('.');
if (idx > 0) {
name = name.substring(0, idx);
}
Pattern p = Pattern.compile("\\b" + name + "\\b", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(text.getText());
if (m.find()) {
addHit(entry, entry.getSearchString(), null);
}
}
}