/*******************************************************************************
 * Copyright (c) 2001, 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 API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.views.properties.tabbed.view;

import com.ibm.icu.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.internal.views.properties.tabbed.TabbedPropertyViewPlugin;
import org.eclipse.ui.internal.views.properties.tabbed.TabbedPropertyViewStatusCodes;
import org.eclipse.ui.internal.views.properties.tabbed.l10n.TabbedPropertyMessages;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.views.properties.tabbed.ISection;
import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
import org.eclipse.ui.views.properties.tabbed.ITabItem;

/**
 * Represents the default implementation of a tab descriptor on the tabbed
 * property tabs extensions.
 * 
 * @author Anthony Hunter
 */
public class TabDescriptor
	implements Cloneable, ITabItem {

	private static final String ATT_ID = "id"; //$NON-NLS-1$

	private static final String ATT_LABEL = "label"; //$NON-NLS-1$

	private static final String ATT_IMAGE = "image"; //$NON-NLS-1$

	private static final String ATT_INDENTED = "indented"; //$NON-NLS-1$

	private static final String ATT_CATEGORY = "category"; //$NON-NLS-1$

	private static final String ATT_AFTER_TAB = "afterTab"; //$NON-NLS-1$

	private static final String TOP = "top"; //$NON-NLS-1$

	private final static String TAB_ERROR = TabbedPropertyMessages.TabDescriptor_Tab_error;

	private String id;

	private String label;

	private Image image;

	private boolean selected;

	private boolean indented;

	private String category;

	private String afterTab;

	private List sectionDescriptors;

	/**
	 * Constructor for TabDescriptor.
	 * 
	 * @param configurationElement
	 *            the configuration element for the tab descriptor.
	 */
	public TabDescriptor(IConfigurationElement configurationElement) {
		if (configurationElement != null) {
			id = configurationElement.getAttribute(ATT_ID);
			label = configurationElement.getAttribute(ATT_LABEL);
			String imageString = configurationElement.getAttribute(ATT_IMAGE);
			if (imageString != null) {
				image = AbstractUIPlugin
					.imageDescriptorFromPlugin(
						configurationElement.getDeclaringExtension()
							.getNamespace(), imageString).createImage();
			}
			String indentedString = configurationElement
				.getAttribute(ATT_INDENTED);
			indented = indentedString != null && indentedString.equals("true"); //$NON-NLS-1$
			category = configurationElement.getAttribute(ATT_CATEGORY);
			afterTab = configurationElement.getAttribute(ATT_AFTER_TAB);
			if (id == null || label == null || category == null) {
				// the tab id, label and category are mandatory - log error
				handleTabError(configurationElement, null);
			}
		}
		if (getAfterTab() == null) {
			afterTab = TOP;
		}
		sectionDescriptors = new ArrayList(5);
		selected = false;
	}

	/**
	 * Get the unique identifier for the tab.
	 * 
	 * @return the unique identifier for the tab.
	 */
	public String getId() {
		return id;
	}

	/**
	 * Get the text label for the tab.
	 * 
	 * @return the text label for the tab.
	 */
	public String getLabel() {
		return label;
	}

	/**
	 * Get the identifier of the tab after which this tab should be displayed.
	 * When two or more tabs belong to the same category, they are sorted by the
	 * after tab values.
	 * 
	 * @return the identifier of the tab.
	 */
	protected String getAfterTab() {
		return afterTab;
	}

	/**
	 * Get the category this tab belongs to.
	 * 
	 * @return Get the category this tab belongs to.
	 */
	protected String getCategory() {
		return category;
	}

	/**
	 * Returns whether the given section was added to this tab. The section can
	 * be appended if its tab attribute matches the tab id. The afterSection
	 * attribute indicates the order in which the section should be appended.
	 * 
	 * @param target
	 *            the section descriptor to append.
	 */
	protected boolean append(ISectionDescriptor target) {
		if (!target.getTargetTab().equals(id)) {
			return false;
		}

		if (insertSectionDescriptor(target)) {
			return true;
		}

		sectionDescriptors.add(target);
		return true;
	}

	/**
	 * Insert the section descriptor into the section descriptor list.
	 * 
	 * @param target
	 *            the section descriptor to insert.
	 * @return <code>true</code> if the target descriptor was added to the
	 *         descriptors list.
	 */
	private boolean insertSectionDescriptor(ISectionDescriptor target) {
		if (target.getAfterSection().equals(TOP)) {
			sectionDescriptors.add(0, target);
			return true;
		}
		for (int i = 0; i < sectionDescriptors.size(); i++) {
			ISectionDescriptor descriptor = (ISectionDescriptor) sectionDescriptors
				.get(i);
			if (target.getAfterSection().equals(descriptor.getId())) {
				sectionDescriptors.add(i + 1, target);
				return true;
			} else {
				if (descriptor.getAfterSection().equals(target.getId())) {
					sectionDescriptors.add(i, target);
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Instantiate this tab's sections.
	 */
	public Tab createTab() {
		List sections = new ArrayList(sectionDescriptors.size());
		for (Iterator iter = sectionDescriptors.iterator(); iter.hasNext();) {
			ISectionDescriptor descriptor = (ISectionDescriptor) iter.next();
			ISection section = descriptor.getSectionClass();
			sections.add(section);
		}
		Tab tab = new Tab();
		tab.setSections((ISection[]) sections.toArray(new ISection[sections
			.size()]));
		return tab;
	}

	/**
	 * Get the list of section descriptors for the tab.
	 * 
	 * @return the list of section descriptors for the tab.
	 */
	protected List getSectionDescriptors() {
		return sectionDescriptors;
	}

	/**
	 * Set the list of section descriptors for the tab.
	 * 
	 * @param sectionDescriptors
	 *            the list of section descriptors for the tab.
	 */
	protected void setSectionDescriptors(List sectionDescriptors) {
		this.sectionDescriptors = sectionDescriptors;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return getId();
	}

	/**
	 * Handle the tab error when an issue is found loading from the
	 * configuration element.
	 * 
	 * @param configurationElement
	 *            the configuration element
	 * @param exception
	 *            an optional CoreException
	 */
	private void handleTabError(IConfigurationElement configurationElement,
			CoreException exception) {
		String pluginId = configurationElement.getDeclaringExtension()
			.getNamespace();
		String message = MessageFormat.format(TAB_ERROR,
			new Object[] {pluginId});
		IStatus status = new Status(IStatus.ERROR, pluginId,
			TabbedPropertyViewStatusCodes.TAB_ERROR, message, exception);
		TabbedPropertyViewPlugin.getPlugin().getLog().log(status);
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object object) {
		if (this == object) {
			return true;
		}

		if (this.getClass() == object.getClass()) {
			TabDescriptor descriptor = (TabDescriptor) object;
			if (this.getCategory().equals(descriptor.getCategory())
				&& this.getId().equals(descriptor.getId())
				&& this.getSectionDescriptors().size() == descriptor
					.getSectionDescriptors().size()) {

				Iterator i = this.getSectionDescriptors().iterator();
				Iterator j = descriptor.getSectionDescriptors().iterator();

				// the order is importent here - so as long as the sizes of the
				// lists are the same and id of the section at the same
				// positions are the same - the lists are the same
				while (i.hasNext()) {
					ISectionDescriptor source = (ISectionDescriptor) i.next();
					ISectionDescriptor target = (ISectionDescriptor) j.next();
					if (!source.getId().equals(target.getId())) {
						return false;
					}
				}

				return true;
			}

		}

		return false;
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {

		int hashCode = getCategory().hashCode();
		hashCode ^= getId().hashCode();
		Iterator i = this.getSectionDescriptors().iterator();
		while (i.hasNext()) {
			ISectionDescriptor section = (ISectionDescriptor) i.next();
			hashCode ^= section.getId().hashCode();
		}
		return hashCode;
	}

	/**
	 * @see java.lang.Object#clone()
	 */
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException exception) {
			IStatus status = new Status(IStatus.ERROR, TabbedPropertyViewPlugin
				.getPlugin().getBundle().getSymbolicName(), 666, exception
				.getMessage(), exception);
			TabbedPropertyViewPlugin.getPlugin().getLog().log(status);
		}
		return null;
	}

	/**
	 * Set the image for the tab.
	 * 
	 * @param image
	 *            the image for the tab.
	 */
	protected void setImage(Image image) {
		this.image = image;
	}

	/**
	 * Set the indicator to determine if the tab should be displayed as
	 * indented.
	 * 
	 * @param indented
	 *            <code>true</code> if the tab should be displayed as
	 *            indented.
	 */
	protected void setIndented(boolean indented) {
		this.indented = indented;
	}

	/**
	 * Set the indicator to determine if the tab should be the selected tab in
	 * the list.
	 * 
	 * @param selected
	 *            <code>true</code> if the tab should be the selected tab in
	 *            the list.
	 */
	protected void setSelected(boolean selected) {
		this.selected = selected;
	}

	/**
	 * Set the text label for the tab.
	 * 
	 * @param label
	 *            the text label for the tab.
	 */
	protected void setLabel(String label) {
		this.label = label;
	}

	/**
	 * Get the image for the tab.
	 * 
	 * @return the image for the tab.
	 */
	public Image getImage() {
		return image;
	}

	/**
	 * Determine if the tab is selected.
	 * 
	 * @return <code>true</code> if the tab is selected.
	 */
	public boolean isSelected() {
		return selected;
	}

	/**
	 * Determine if the tab should be displayed as indented.
	 * 
	 * @return <code>true</code> if the tab should be displayed as indented.
	 */
	public boolean isIndented() {
		return indented;
	}

	/**
	 * Get the text label for the tab.
	 * 
	 * @return the text label for the tab.
	 */
	public String getText() {
		return label;
	}
}
