/*
 * Copyright (c) 2011, 2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.releng.doc.article.impl;

import org.eclipse.emf.cdo.releng.doc.AssembleScripts;
import org.eclipse.emf.cdo.releng.doc.article.ArticlePackage;
import org.eclipse.emf.cdo.releng.doc.article.Category;
import org.eclipse.emf.cdo.releng.doc.article.Chapter;
import org.eclipse.emf.cdo.releng.doc.article.Context;
import org.eclipse.emf.cdo.releng.doc.article.Documentation;
import org.eclipse.emf.cdo.releng.doc.article.EmbeddableElement;
import org.eclipse.emf.cdo.releng.doc.article.Javadoc;
import org.eclipse.emf.cdo.releng.doc.article.Plugin;
import org.eclipse.emf.cdo.releng.doc.article.Schemadoc;
import org.eclipse.emf.cdo.releng.doc.article.StructuralElement;
import org.eclipse.emf.cdo.releng.doc.article.util.ArticleUtil;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;

import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.Tag;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>Documentation</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getContext <em>Context</em>}</li>
 * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getEmbeddableElements <em>Embeddable
 * Elements</em>}</li>
 * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getDependencies <em>Dependencies</em>}</li>
 * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getProject <em>Project</em>}</li>
 * <li>{@link org.eclipse.emf.cdo.releng.doc.article.impl.DocumentationImpl#getPlugins <em>Plugins</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class DocumentationImpl extends StructuralElementImpl implements Documentation
{
  private static final String HTML = "html";

  private static final String PLUGINS = "plugins";

  private static final String JAVADOC_MARKER_CLASS = "Javadoc";

  private static final String SCHEMADOC_MARKER_CLASS = "Schemadoc";

  private static final boolean LOCAL = false;

  /**
   * The cached value of the '{@link #getEmbeddableElements() <em>Embeddable Elements</em>}' containment reference list.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @see #getEmbeddableElements()
   * @generated
   * @ordered
   */
  protected EList<EmbeddableElement> embeddableElements;

  /**
   * The cached value of the '{@link #getDependencies() <em>Dependencies</em>}' reference list. <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @see #getDependencies()
   * @generated
   * @ordered
   */
  protected EList<Documentation> dependencies;

  /**
   * The default value of the '{@link #getProject() <em>Project</em>}' attribute. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @see #getProject()
   * @generated
   * @ordered
   */
  protected static final String PROJECT_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getProject() <em>Project</em>}' attribute. <!-- begin-user-doc --> <!--
   * end-user-doc -->
   *
   * @see #getProject()
   * @generated
   * @ordered
   */
  protected String project = PROJECT_EDEFAULT;

  /**
   * The cached value of the '{@link #getPlugins() <em>Plugins</em>}' containment reference list. <!-- begin-user-doc
   * --> <!-- end-user-doc -->
   *
   * @see #getPlugins()
   * @generated
   * @ordered
   */
  protected EList<Plugin> plugins;

  private StructuralElement defaultElement;

  private final List<StructuralElement> navElements = new ArrayList<StructuralElement>();

  private boolean analyzed;

  private File projectFolder;

  private String basePathForChildren;

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  protected DocumentationImpl()
  {
    super();
  }

  DocumentationImpl(Context context, String project)
  {
    super(null, null, context.getRoot());
    setContext(context);
    this.project = project;
    context.register(getId(), this);

    basePathForChildren = PLUGINS + "/" + project + "/" + HTML;
    projectFolder = new File(new File(getContext().getBaseFolder(), PLUGINS), project);

    setTitle(AssembleScripts.getPluginName(projectFolder));

    analyzeDependencies(projectFolder);
    loadPlugins(projectFolder);
    analyzeDocumentation(projectFolder);
    if (defaultElement == null)
    {
      throw new AssertionError("No default element declared in " + getTitle());
    }

    setPath(defaultElement.getFullPath());
    analyzed = true;
    collectNavElements(navElements);
  }

  public void registerElement(StructuralElement element)
  {
    if (element != this)
    {
      getContext().register(element.getId(), element);
    }
  }

  private void analyzeDependencies(File projectFolder)
  {
    Context context = getContext();
    for (String dependency : AssembleScripts.getDependencies(projectFolder))
    {
      if (context.getDocumentation(dependency) == null)
      {
        new DocumentationImpl(context, dependency);
      }
    }
  }

  private void analyzeDocumentation(File projectFolder)
  {
    ClassDoc[] classes = getContext().getRoot().classes();
    for (ClassDoc classDoc : classes)
    {
      if (classDoc.containingClass() == null)
      {
        File file = classDoc.position().file();
        if (ArticleUtil.containsFile(projectFolder, file))
        {
          PackageDoc packageDoc = classDoc.containingPackage();
          StructuralElement parent = analyzePackage(packageDoc);
          analyzeClass(parent, classDoc);
        }
      }
    }
  }

  private StructuralElement analyzePackage(PackageDoc packageDoc)
  {
    if (packageDoc != null)
    {
      Object value = getContext().lookup(packageDoc);
      if (value instanceof Category)
      {
        return (Category)value;
      }

      PackageDoc parentDoc = ArticleUtil.getParentPackage(getContext().getRoot(), packageDoc);
      if (ArticleUtil.isDocumented(packageDoc))
      {
        StructuralElement parent = analyzePackage(parentDoc);

        ClassDoc javadocMarkerClass = packageDoc.findClass(JAVADOC_MARKER_CLASS);
        if (javadocMarkerClass != null && javadocMarkerClass.isPackagePrivate())
        {
          return new JavadocImpl(parent, packageDoc);
        }

        ClassDoc schemadocMarkerClass = packageDoc.findClass(SCHEMADOC_MARKER_CLASS);
        if (schemadocMarkerClass != null && schemadocMarkerClass.isPackagePrivate())
        {
          return new SchemadocImpl(parent, packageDoc);
        }

        return new CategoryImpl(parent, packageDoc);
      }

      warnIfSubPackagesUndocumented(packageDoc, parentDoc);
    }

    return this;
  }

  private void analyzeClass(StructuralElement parent, ClassDoc classDoc)
  {
    // TODO Non-public classes?

    if (ArticleUtil.isIgnore(classDoc))
    {
      return;
    }

    if (parent instanceof Javadoc && classDoc.simpleTypeName().equals(JAVADOC_MARKER_CLASS))
    {
      return;
    }

    if (parent instanceof Schemadoc && classDoc.simpleTypeName().equals(SCHEMADOC_MARKER_CLASS))
    {
      return;
    }

    Tag[] externals = classDoc.tags("@external");
    if (externals != null && externals.length != 0)
    {
      String url = externals[0].inlineTags()[0].text();
      if (URI.createURI(url).isRelative())
      {
        new PluginResourceImpl(parent, classDoc, url);
      }
      else
      {
        new ExternalArticleImpl(parent, classDoc, url);
      }

      return;
    }

    if (ArticleUtil.isSnippet(getContext().getRoot(), classDoc))
    {
      new SnippetImpl(this, classDoc);
      analyzeClassChildren(this, classDoc);
    }
    else
    {
      Chapter chapter = createChapter(parent, classDoc);
      analyzeClassChildren(chapter, classDoc);
    }
  }

  private void analyzeClassChildren(StructuralElement parent, ClassDoc classDoc)
  {
    for (ClassDoc child : classDoc.innerClasses())
    {
      analyzeClass(parent, child);
    }

    for (MethodDoc methodDoc : classDoc.methods())
    {
      analyzeMethod(methodDoc);
    }
  }

  private void analyzeMethod(MethodDoc methodDoc)
  {
    if (ArticleUtil.isIgnore(methodDoc))
    {
      return;
    }

    if (ArticleUtil.isSnippet(getContext().getRoot(), methodDoc))
    {
      new SnippetImpl(this, methodDoc);
    }

    if (ArticleUtil.isFactory(methodDoc))
    {
      new FactoryImpl(this, methodDoc);
    }
  }

  private void warnIfSubPackagesUndocumented(PackageDoc packageDoc, PackageDoc parentDoc)
  {
    while (parentDoc != null)
    {
      if (ArticleUtil.isDocumented(parentDoc))
      {
        System.err.println("Undocumented category " + packageDoc.name());
        break;
      }

      parentDoc = ArticleUtil.getParentPackage(getContext().getRoot(), parentDoc);
    }
  }

  private Chapter createChapter(StructuralElement parent, ClassDoc classDoc)
  {
    if (parent instanceof Chapter)
    {
      return new ChapterImpl(parent, classDoc);
    }

    return new ArticleImpl(parent, classDoc);
  }

  private void loadPlugins(File projectFolder)
  {
    try
    {
      Resource resource = AssembleScripts.JavaDoc.getTocXmiResource(projectFolder, false);

      for (Object content : resource.getContents().toArray())
      {
        getPlugins().add((Plugin)content);
      }
    }
    catch (IOException ex)
    {
      ex.printStackTrace();
    }
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  protected EClass eStaticClass()
  {
    return ArticlePackage.Literals.DOCUMENTATION;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public Context getContext()
  {
    if (eContainerFeatureID() != ArticlePackage.DOCUMENTATION__CONTEXT)
    {
      return null;
    }
    return (Context)eContainer();
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public NotificationChain basicSetContext(Context newContext, NotificationChain msgs)
  {
    msgs = eBasicSetContainer((InternalEObject)newContext, ArticlePackage.DOCUMENTATION__CONTEXT, msgs);
    return msgs;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public void setContext(Context newContext)
  {
    if (newContext != eInternalContainer()
        || eContainerFeatureID() != ArticlePackage.DOCUMENTATION__CONTEXT && newContext != null)
    {
      if (EcoreUtil.isAncestor(this, newContext))
      {
        throw new IllegalArgumentException("Recursive containment not allowed for " + toString());
      }
      NotificationChain msgs = null;
      if (eInternalContainer() != null)
      {
        msgs = eBasicRemoveFromContainer(msgs);
      }
      if (newContext != null)
      {
        msgs = ((InternalEObject)newContext).eInverseAdd(this, ArticlePackage.CONTEXT__DOCUMENTATIONS, Context.class,
            msgs);
      }
      msgs = basicSetContext(newContext, msgs);
      if (msgs != null)
      {
        msgs.dispatch();
      }
    }
    else if (eNotificationRequired())
    {
      eNotify(
          new ENotificationImpl(this, Notification.SET, ArticlePackage.DOCUMENTATION__CONTEXT, newContext, newContext));
    }
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public EList<EmbeddableElement> getEmbeddableElements()
  {
    if (embeddableElements == null)
    {
      embeddableElements = new EObjectContainmentWithInverseEList<EmbeddableElement>(EmbeddableElement.class, this,
          ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS, ArticlePackage.EMBEDDABLE_ELEMENT__DOCUMENTATION);
    }
    return embeddableElements;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public EList<Documentation> getDependencies()
  {
    if (dependencies == null)
    {
      dependencies = new EObjectEList<Documentation>(Documentation.class, this,
          ArticlePackage.DOCUMENTATION__DEPENDENCIES);
    }
    return dependencies;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public String getProject()
  {
    return project;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  public EList<Plugin> getPlugins()
  {
    if (plugins == null)
    {
      plugins = new EObjectContainmentEList<Plugin>(Plugin.class, this, ArticlePackage.DOCUMENTATION__PLUGINS);
    }
    return plugins;
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @SuppressWarnings("unchecked")
  @Override
  public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      if (eInternalContainer() != null)
      {
        msgs = eBasicRemoveFromContainer(msgs);
      }
      return basicSetContext((Context)otherEnd, msgs);
    case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS:
      return ((InternalEList<InternalEObject>)(InternalEList<?>)getEmbeddableElements()).basicAdd(otherEnd, msgs);
    }
    return super.eInverseAdd(otherEnd, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      return basicSetContext(null, msgs);
    case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS:
      return ((InternalEList<?>)getEmbeddableElements()).basicRemove(otherEnd, msgs);
    case ArticlePackage.DOCUMENTATION__PLUGINS:
      return ((InternalEList<?>)getPlugins()).basicRemove(otherEnd, msgs);
    }
    return super.eInverseRemove(otherEnd, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs)
  {
    switch (eContainerFeatureID())
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      return eInternalContainer().eInverseRemove(this, ArticlePackage.CONTEXT__DOCUMENTATIONS, Context.class, msgs);
    }
    return super.eBasicRemoveFromContainerFeature(msgs);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public Object eGet(int featureID, boolean resolve, boolean coreType)
  {
    switch (featureID)
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      return getContext();
    case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS:
      return getEmbeddableElements();
    case ArticlePackage.DOCUMENTATION__DEPENDENCIES:
      return getDependencies();
    case ArticlePackage.DOCUMENTATION__PROJECT:
      return getProject();
    case ArticlePackage.DOCUMENTATION__PLUGINS:
      return getPlugins();
    }
    return super.eGet(featureID, resolve, coreType);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @SuppressWarnings("unchecked")
  @Override
  public void eSet(int featureID, Object newValue)
  {
    switch (featureID)
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      setContext((Context)newValue);
      return;
    case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS:
      getEmbeddableElements().clear();
      getEmbeddableElements().addAll((Collection<? extends EmbeddableElement>)newValue);
      return;
    case ArticlePackage.DOCUMENTATION__DEPENDENCIES:
      getDependencies().clear();
      getDependencies().addAll((Collection<? extends Documentation>)newValue);
      return;
    }
    super.eSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      setContext((Context)null);
      return;
    case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS:
      getEmbeddableElements().clear();
      return;
    case ArticlePackage.DOCUMENTATION__DEPENDENCIES:
      getDependencies().clear();
      return;
    }
    super.eUnset(featureID);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
    case ArticlePackage.DOCUMENTATION__CONTEXT:
      return getContext() != null;
    case ArticlePackage.DOCUMENTATION__EMBEDDABLE_ELEMENTS:
      return embeddableElements != null && !embeddableElements.isEmpty();
    case ArticlePackage.DOCUMENTATION__DEPENDENCIES:
      return dependencies != null && !dependencies.isEmpty();
    case ArticlePackage.DOCUMENTATION__PROJECT:
      return PROJECT_EDEFAULT == null ? project != null : !PROJECT_EDEFAULT.equals(project);
    case ArticlePackage.DOCUMENTATION__PLUGINS:
      return plugins != null && !plugins.isEmpty();
    }
    return super.eIsSet(featureID);
  }

  /**
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   *
   * @generated
   */
  @Override
  public String toString()
  {
    if (eIsProxy())
    {
      return super.toString();
    }

    StringBuffer result = new StringBuffer(super.toString());
    result.append(" (project: ");
    result.append(project);
    result.append(')');
    return result.toString();
  }

  public File getProjectFolder()
  {
    return projectFolder;
  }

  @Override
  public String getBasePathForChildren()
  {
    return basePathForChildren;
  }

  public boolean isAnalyzed()
  {
    return analyzed;
  }

  @Override
  protected String getKind()
  {
    return "Documentation";
  }

  public StructuralElement getDefaultElement()
  {
    return defaultElement;
  }

  public void setDefaultElement(StructuralElement defaultElement)
  {
    if (this.defaultElement != null)
    {
      throw new AssertionError("Multiple default elements declared in " + getTitle());
    }

    this.defaultElement = defaultElement;
  }

  public List<StructuralElement> getNavElements()
  {
    return Collections.unmodifiableList(navElements);
  }

  @Override
  public RootDoc getDoc()
  {
    return (RootDoc)super.getDoc();
  }

  @Override
  public Object getId()
  {
    return project;
  }

  @Override
  public String getTooltip()
  {
    return getTitle();
  }

  @Override
  public String linkFrom(StructuralElement source)
  {
    return defaultElement.linkFrom(source);
  }

  @Override
  protected String getTocHref()
  {
    return ((StructuralElementImpl)defaultElement).getTocHref();
  }

  @Override
  public void generate() throws IOException
  {
    EList<StructuralElement> children = getChildren();
    if (!children.isEmpty())
    {
      StructuralElement child = children.get(0);
      File sourceFolder = child.getDoc().position().file().getParentFile();
      copyResources(sourceFolder);
    }

    super.generate();

    generateToc(false);
    generateToc(true);
  }

  @Override
  protected void generateBreadCrumbs(PrintWriter out, StructuralElement linkSource) throws IOException
  {
    super.generateBreadCrumbs(out, linkSource);

    if (linkSource != this)
    {
      generateLink(out, linkSource, null);
    }
  }

  private void generateToc(boolean html) throws IOException
  {
    TocWriter writer = null;

    try
    {
      if (html)
      {
        writer = new TocWriter.Html(projectFolder);
      }
      else
      {
        writer = new TocWriter.Xml(projectFolder);
      }

      writer.writeGroupStart(getDocumentation().getTitle(), getTocHref(), null);
      generateTocEntries(writer);
      writer.writeGroupEnd();
    }
    finally
    {
      ArticleUtil.close(writer);
    }
  }

  /**
   * @author Eike Stepper
   */
  public static abstract class TocWriter extends BufferedWriter
  {
    protected File project;

    protected int level;

    public TocWriter(File project, String filename) throws IOException
    {
      super(new FileWriter(new File(LOCAL ? project.getParentFile() : project, filename)));
      this.project = project;
    }

    public final void writePrefix() throws IOException
    {
      for (int i = 0; i < level; i++)
      {
        write("  ");
      }
    }

    public abstract void writeSingle(String label, String href, String icon) throws IOException;

    public abstract void writeGroupStart(String label, String href, String icon) throws IOException;

    public abstract void writeGroupEnd() throws IOException;

    /**
     * @author Eike Stepper
     */
    public static class Html extends TocWriter
    {
      private int id;

      private String idPrefix;

      public Html(File project) throws IOException
      {
        super(project, "toc.html");
        idPrefix = project.getName().replace('.', '_') + "_";

        if (LOCAL)
        {
          write("<LINK REL=stylesheet TYPE=\"text/css\" HREF=\"toc.css\">" + NL);
          write("" + NL);

          write("<script type=\"text/javascript\">" + NL);
          write("  function toggle(id)" + NL);
          write("  {" + NL);
          write("    e = document.getElementById(id);" + NL);
          write("    e.style.display = (e.style.display == \"\" ? \"none\" : \"\");" + NL);
          write("    img = document.getElementById(\"img_\" + id);" + NL);
          write("    img.src = (e.style.display == \"none\" ? \"plus.gif\" : \"minus.gif\");" + NL);
          write("  }" + NL);
          write("</script>" + NL);
          write("" + NL);

          write("<font face=\"Segoe UI,Arial\" size=\"-1\">" + NL);
          write("" + NL);
        }
      }

      @Override
      public void close() throws IOException
      {
        if (LOCAL)
        {
          write("" + NL);
          write("</font>" + NL);
        }

        super.close();
      }

      public String nextID()
      {
        return idPrefix + ++id;
      }

      public void writeHref(String label, String href) throws IOException
      {
        label = label.replaceAll(" ", "&nbsp;");
        if (level == 0)
        {
          label = "<b>" + label + "</b>";
        }

        URI uri = URI.createURI(href);
        if (uri.isRelative())
        {
          href = project.getName() + "/" + href;
        }

        write("<a href=\"" + href + "\" target=\"content\">" + label + "</a>");
      }

      public void writeImage(String name) throws IOException
      {
        write("<img src=\"" + name + "\">");
      }

      @Override
      public void writeSingle(String label, String href, String icon) throws IOException
      {
        writePrefix();
        write("<div class=\"te\"><span>");
        writeImage("empty.gif");
        writeImage(icon != null ? icon + ".gif" : "article.gif");
        writeHref(label, href);
        write("</span></div>" + NL);
      }

      @Override
      public void writeGroupStart(String label, String href, String icon) throws IOException
      {
        String id = nextID();

        writePrefix();
        write("<div class=\"te\">");
        write("<span><a href=\"javascript:toggle('" + id + "')\">");
        write("<img src=\"" + "plus.gif" + "\" id=\"img_" + id + "\">");
        write("</a>");

        if (level == 0)
        {
          writeImage("documentation.gif");
        }
        else
        {
          writeImage(icon != null ? icon + ".gif" : "category.gif");
        }

        writeHref(label, href);
        write("</span></div>" + NL);

        writePrefix();
        write("<div id=\"" + id + "\" style=\"display:none; margin-left:20px;\">" + NL);
        ++level;
      }

      @Override
      public void writeGroupEnd() throws IOException
      {
        --level;
        writePrefix();
        write("</div>" + NL);
      }
    }

    /**
     * @author Eike Stepper
     */
    public static class Xml extends TocWriter
    {
      public Xml(File project) throws IOException
      {
        super(project, "toc.xml");
        write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + NL);
        write("<?NLS TYPE=\"org.eclipse.help.toc\"?>" + NL + NL);
      }

      @Override
      public void writeSingle(String label, String href, String icon) throws IOException
      {
        writePrefix();
        write("<topic label=\"" + label + "\" href=\"" + href + "\"" + icon(icon) + " />" + NL);
      }

      @Override
      public void writeGroupStart(String label, String href, String icon) throws IOException
      {
        writePrefix();
        if (level == 0)
        {
          write("<toc label=\"" + label + "\" topic=\"" + href + "\">" + NL);
        }
        else
        {
          write("<topic label=\"" + label + "\" href=\"" + href + "\"" + icon(icon) + ">" + NL);
        }

        ++level;
      }

      @Override
      public void writeGroupEnd() throws IOException
      {
        --level;

        writePrefix();
        if (level == 0)
        {
          write("</toc>" + NL);
        }
        else
        {
          write("</topic>" + NL);
        }
      }

      private String icon(String icon)
      {
        if (icon == null)
        {
          return "";
        }

        return " icon=\"" + icon + "\"";
      }
    }
  }
} // DocumentationImpl
