//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.services;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.util.ResourceHelper;

import com.ibm.uma.TermDefinition;

/**
 * Holds all glossary items and sort them in desired order grouped by first
 * letter of the glossary name TODO: Add a brief description for this class.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class GlossaryList {

	// using the default order from the configuration explorer.
	// maybe a special sorted list later,
	// TreeMap of the first letter of the glossary map to a (Sorted) List of
	// glossary Items
	private TreeMap itemMap = new TreeMap();

	public GlossaryList() {
	}

	public void clear() {
		itemMap.clear();
	}

	public void add(TermDefinition element) {
		String name = TngUtil.getPresentationName(element);
		String group = "" + name.charAt(0); //$NON-NLS-1$
		getItemList(group).add(element);
	}

	private List getItemList(String group) {
		group = group.toUpperCase();
		List l = (List) itemMap.get(group);
		if (l == null) {
			l = new ArrayList();
			itemMap.put(group, l);
		}

		return l;
	}

	public StringBuffer getXml() {
		XmlElement xe = new XmlElement("Glossary"); //$NON-NLS-1$

		for (Iterator it = itemMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			String group = (String) entry.getKey();
			List items = (List) entry.getValue();

			// create a bookmark for the group
			xe.newChild("item") //$NON-NLS-1$
					.setAttribute("name", group) //$NON-NLS-1$
					.setAttribute("presentationName", group) //$NON-NLS-1$
					.setAttribute("navigation-mark", "true") //$NON-NLS-1$ //$NON-NLS-2$
					.setAttribute("content", ""); //$NON-NLS-1$ //$NON-NLS-2$

			// then create entry for each item
			for (Iterator itItem = items.iterator(); itItem.hasNext();) {
				TermDefinition element = (TermDefinition) itItem.next();
				String name = element.getName();
				String presentationName = TngUtil.getPresentationName(element);
				String content = element.getPresentation().getMainDescription();

				// fix the links in the content
				content = ResourceHelper.fixContentUrlPath(content,
						ResourceHelper.getElementPath(element),
						GlossaryBuilder.GLOSSARY_BACKPATH);

				xe.newChild("item") //$NON-NLS-1$
						.setAttribute("name", name) //$NON-NLS-1$
						.setAttribute("presentationName", presentationName) //$NON-NLS-1$
						.setAttribute("content", content); //$NON-NLS-1$
			}
		}

		return xe.toXml();
	}

}
