package fitnesse.wikitext.parser;
import fitnesse.html.HtmlTag;
import fitnesse.html.HtmlUtil;
import fitnesse.wiki.PageData;
import fitnesse.wiki.PageType;
import fitnesse.wiki.WikiImportProperty;
import util.GracefulNamer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class ContentsItemBuilder {
private Symbol contents;
private int level;
public ContentsItemBuilder(Symbol contents, int level) {
this.contents = contents;
this.level = level;
}
public HtmlTag buildLevel(SourcePage page, HtmlTag contentsDiv) {
HtmlTag div = HtmlUtil.makeDivTag("toc" + level);
HtmlTag list = new HtmlTag("ul");
try {
for (SourcePage child: getSortedChildren(page)) {
list.add(buildListItem(child));
}
} catch (Exception e) {
e.printStackTrace();
throw new IllegalStateException(e);
}
contentsDiv.add(list);
div.add(contentsDiv);
return div;
}
private HtmlTag buildListItem(SourcePage child) {
HtmlTag listItem = new HtmlTag("li");
HtmlTag childItem = buildItem(child);
listItem.add(childItem);
if (child.getChildren().size() > 0) {
if (level < getRecursionLimit()) {
HtmlTag nestedDiv = HtmlUtil.makeDivTag("nested-contents");
listItem.add(new ContentsItemBuilder(contents, level + 1).buildLevel(child, nestedDiv));
}
else if (getRecursionLimit() > 0){
childItem.add(contents.getVariable(Contents.MORE_SUFFIX_TOC, Contents.MORE_SUFFIX_DEFAULT));
}
}
return listItem;
}
private Collection<SourcePage> getSortedChildren(SourcePage parent) {
ArrayList<SourcePage> result = new ArrayList<SourcePage>(parent.getChildren());
Collections.sort(result);
return result;
}
public HtmlTag buildItem(SourcePage page) {
HtmlTag result = new HtmlTag("a", buildBody(page));
result.addAttribute("href", buildReference(page));
String help = page.getProperty(PageData.PropertyHELP);
if (help.length() > 0) {
if (hasOption("-h", Contents.HELP_TOC)) {
result.tail = HtmlUtil.makeSpanTag("pageHelp", ": " + help).htmlInline();
}
else {
result.addAttribute("title", help);
}
}
return result;
}
private String buildBody(SourcePage page) {
String itemText = page.getName();
if (hasOption("-g", Contents.REGRACE_TOC)) {
//todo: DRY? see wikiwordbuilder
itemText = GracefulNamer.regrace(itemText);
}
if (hasOption("-p", Contents.PROPERTY_TOC)) {
String properties = getBooleanProperties(page);
if (properties.length() > 0) itemText += " " + properties;
}
if (hasOption("-f", Contents.FILTER_TOC)) {
String filters = page.getProperty(PageData.PropertySUITES);
if (filters.length() > 0) itemText += " (" + filters + ")";
}
return itemText;
}
private String buildReference(SourcePage sourcePage) {
return sourcePage.getFullName();
}
private int getRecursionLimit() {
for (Symbol child: contents.getChildren()) {
if (!child.getContent().startsWith("-R")) continue;
String level = child.getContent().substring(2);
if (level.length() == 0) return Integer.MAX_VALUE;
try {
return Integer.parseInt(level);
}
catch (NumberFormatException e) {
return 0;
}
}
return 0;
}
private boolean hasOption(String option, String variableName) {
for (Symbol child: contents.getChildren()) {
if (child.getContent().equals(option)) return true;
}
return variableName.length() > 0
&& contents.getVariable(variableName, "").equals("true");
}
private String getBooleanProperties(SourcePage sourcePage) {
String result = "";
if (sourcePage.hasProperty(PageType.SUITE.toString())) result += "*";
if (sourcePage.hasProperty(PageType.TEST.toString())) result += "+";
if (sourcePage.hasProperty(WikiImportProperty.PROPERTY_NAME)) result += "@";
if (sourcePage.hasProperty(PageData.PropertyPRUNE)) result += "-";
return result;
}
}