/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.help.internal.toc;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.help.internal.HelpPlugin;

public class TocBuilder {

	// list of all toc files
	protected Collection contributedTocFiles;

	// list of unprocessed toc files
	protected Collection unprocessedTocFiles;

	// list of unprocessed toc (the target of attach_to was not available at the
	// time)
	protected List unprocessedTocs;

	/**
	 * Constructor.
	 */
	public TocBuilder() {
		unprocessedTocFiles = new ArrayList();
		unprocessedTocs = new ArrayList();
	}

	public Collection getBuiltTocs() {
		// returns the list of root Toc trees
		Collection tocCol = new ArrayList(contributedTocFiles.size());
		for (Iterator it = contributedTocFiles.iterator(); it.hasNext();) {
			TocFile tocFile = (TocFile) it.next();
			Toc toc = tocFile.getToc();
			if (toc != null && toc.getTocFile().isPrimary() && !isIntegrated(toc))
				tocCol.add((toc));
		}
		return tocCol;
	}

	/**
	 */
	public void build(Collection contributedTocFiles) {
		this.contributedTocFiles = contributedTocFiles;
		unprocessedTocFiles.addAll(contributedTocFiles);
		// process all the toc files.
		// A side-effect is that linked files are also processed
		while (!unprocessedTocFiles.isEmpty()) {
			TocFile tocFile = (TocFile) unprocessedTocFiles.iterator().next();
			tocFile.build(this);
		}
		// At the end, unprocessedTocs may contain TOCs that need be build.
		// All these toc could not be attached because the
		// target node was not parsed at that time

		// try processing as many toc (link_to) as possible now
		int remaining = unprocessedTocs.size();
		for (int i = 0; i < remaining; i++) {
			Toc toc = (Toc) unprocessedTocs.get(i);
			buildToc(toc);
		}
	}

	public void buildTocFile(TocFile tocFile) {
		try {
			unprocessedTocFiles.remove(tocFile);
			TocFileParser parser = new TocFileParser(this);
			parser.parse(tocFile);
		} catch (Exception e) {
			String msg = "Error occurred processing file " + tocFile.getHref() + "."; //$NON-NLS-1$ //$NON-NLS-2$
			HelpPlugin.logError(msg, e);
		}
	}

	public void buildAnchor(Anchor anchor) {
		// cache the anchor in the toc file
		anchor.getTocFile().addAnchor(anchor);
	}

	public void buildLink(Link link) {
		// parse the linked file
		String linkedToc = link.getToc();
		TocFile includedTocFile = getTocFile(linkedToc);
		if (includedTocFile == null)
			return;
		Toc toc = includedTocFile.getToc();
		if (toc == null)
			return;
		// link the two Toc objects
		link.addChild(toc);
	}

	public void buildTopic(Topic topic) {
		// nothing to do
	}

	public void buildToc(Toc toc) {
		// link toc if so specified
		String href = toc.getLink_to();
		if (href == null || href.equals("")) //$NON-NLS-1$
			return;
		TocFile targetTocFile = getTocFile(href);
		if (targetTocFile == null)
			return;
		Anchor anchor = targetTocFile.getAnchor(href);
		if (anchor == null) {
			unprocessedTocs.add(toc);
			return;
		}
		// link the two toc objects
		anchor.addChild(toc);
	}

	private TocFile getTocFile(String href) {
		String plugin = HrefUtil.getPluginIDFromHref(href);
		if (plugin == null)
			return null;
		String path = HrefUtil.getResourcePathFromHref(href);
		if (path == null)
			return null;
		TocFile tocFile = null;
		for (Iterator it = contributedTocFiles.iterator(); it.hasNext();) {
			tocFile = (TocFile) it.next();
			if (tocFile.getPluginID().equals(plugin) && tocFile.getHref().equals(path))
				break;
			tocFile = null;
		}
		if (tocFile == null)
			return null;
		if (unprocessedTocFiles.contains(tocFile))
			buildTocFile(tocFile);
		return tocFile;
	}

	/**
	 * Checks if navigation element has been integrated into another TOC.
	 */
	private boolean isIntegrated(TocNode element) {
		// check if there if there is TOC in ancestor hierarchy (depth first)
		for (Iterator it = element.getParents().iterator(); it.hasNext();) {
			TocNode parent = (TocNode) it.next();
			if (parent instanceof Toc && ((Toc) parent).getTocFile().isPrimary()) {
				return true;
			} else if (isIntegrated(parent)) {
				return true;
			}
		}
		// no ancestor is a TOC
		return false;
	}
}
