//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.io.File;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.Bookmark;
import org.eclipse.epf.library.layout.ElementLayoutManager;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.layout.IElementLayout;
import org.eclipse.epf.library.util.IconUtil;
import org.eclipse.epf.publishing.PublishingPlugin;
import org.eclipse.epf.publishing.PublishingResources;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.osgi.util.NLS;

/**
 * The abstract base class for all publishing view builders.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @author Weiping Lu
 * @since 1.0
 */
public abstract class AbstractViewBuilder {

	protected static final int TIMEOUT_INTERVAL = 600000; // in milliseconds

	protected static boolean profiling = PublishingPlugin.getDefault()
			.isProfiling();

	protected ISiteGenerator siteGenerator;

	protected PublishOptions options;

	protected MethodConfiguration config;

	protected Bookmark defaultView;

	PublishingRunnable runnable = null;

	/**
	 * Creates a new instance.
	 * 
	 * @param generator
	 *            a site generator
	 */
	public AbstractViewBuilder(ISiteGenerator generator) {
		this.siteGenerator = generator;
		this.options = generator.getPublishOptions();
		this.config = generator.getHtmlBuilder().getLayoutManager()
				.getConfiguration();
		this.runnable = new PublishingRunnable(generator.getHtmlBuilder(), TIMEOUT_INTERVAL);
	}

	/**
	 * Gets the site generator.
	 * 
	 * @return the site generator assigned to this view builder
	 */
	public ISiteGenerator getSiteGenerator() {
		return this.siteGenerator;
	}

	/**
	 * Gets the HTML builder.
	 * 
	 * @return the HTML builder assigned to this view builder
	 */
	public HtmlBuilder getHtmlBuilder() {
		return this.siteGenerator.getHtmlBuilder();
	}

	/**
	 * Gets the publishing options.
	 * 
	 * @return the publishing options assigned to this view builder
	 */
	public PublishOptions getOptions() {
		return this.siteGenerator.getPublishOptions();
	}

	/**
	 * Gets the layout manager.
	 * 
	 * @return an element layout manager assigned to this view builder
	 */
	public ElementLayoutManager getLayoutMgr() {
		return getHtmlBuilder().getLayoutManager();
	}

	/**
	 * Gets the content validator.
	 * 
	 * @return an element layout manager assigned to this view builder
	 */
	public PublishingContentValidator getValidator() {
		return (PublishingContentValidator) getHtmlBuilder().getValidator();
	}

	/**
	 * Checks whether a method element can be published or not.
	 * 
	 * @param element
	 *            a method element
	 * @return <code>true</code> if the method element can be published
	 */
	protected boolean canPublish(MethodElement element) {
		return isVisible(element);
	}

	/**
	 * Checks whether a method element will be visible in the published web
	 * site.
	 * 
	 * @param element
	 *            a method element
	 * @return <code>true</code> if the method element will be visible in the
	 *         published web site
	 */
	protected boolean isVisible(MethodElement element) {
		if (element == null) {
			return false;
		}

		if (getValidator().isDiscarded(null, null, element)) {
			return false;
		}

		if (!ConfigurationHelper.canShow(element, config)) {
			return false;
		}

		if (options.isPublishProcess()) {
			return getValidator().inClosure(element);
		} else {
			return true;
		}
	}

	protected void discardEmptyCategory(ContentCategory element, boolean discard) {
		if (discard) {
			getValidator().setDiscardedElement(element);
			getValidator().logWarning(element,
					PublishingResources.discaredCategoryWarning_msg);
		} else {
			getValidator().addValidCategory((ContentCategory) element);
		}
	}

	protected MethodElement calc01FeatureValue(MethodElement element,
			EStructuralFeature feature) {
		return ConfigurationHelper.calc01FeatureValue(element, feature,
				getLayoutMgr().getElementRealizer());
	}

	protected List calc0nFeatureValue(MethodElement element,
			EStructuralFeature feature) {
		return ConfigurationHelper.calc0nFeatureValue(element, feature,
				getLayoutMgr().getElementRealizer());
	}

	protected MethodElement calc01FeatureValue(MethodElement element,
			OppositeFeature feature) {
		return ConfigurationHelper.calc01FeatureValue(element, feature,
				getLayoutMgr().getElementRealizer());
	}

	protected List calc0nFeatureValue(MethodElement element,
			OppositeFeature feature) {
		return ConfigurationHelper.calc0nFeatureValue(element, feature,
				getLayoutMgr().getElementRealizer());
	}

	protected List getPublishedElements() {
		return getValidator().getPublishedElements();
	}

	
	/**
	 * Publishes the element, collects the linked elements in the published
	 * content.
	 * 
	 * @param monitor
	 *            a progress monitor
	 * @param element
	 *            a method element
	 */
	protected void publish(final IProgressMonitor monitor,
			final MethodElement element) {
		
		// System.out.println("--- Begin publishing element " +
		// element.getGuid() + ":" + element.getType().getName() + ":" +
		// element.getName() );
		try {
			List linkedElements = getValidator()
					.getReferencedElements();
			List publishedElements = getValidator()
					.getPublishedElements();					
			HtmlBuilder htmlBuilder = getHtmlBuilder();
			if (!canPublish(element)) {
				htmlBuilder.getValidator().logWarning(element,
						PublishingResources.invalidElementWarning_msg);
			} else if (!publishedElements.contains(element)) {
				try {
					if (monitor != null) {
						String str;
						if (linkedElements != null) {
							str = NLS
									.bind(
											PublishingResources.publishingLinkedElementTask_name,
											Integer
													.toString(publishedElements
															.size()),
											Integer
													.toString(linkedElements
															.size()));
						} else {
							str = NLS
									.bind(
											PublishingResources.publishingElementTask_name,
											element.getType().getName(),
											element.getName());
						}
						monitor.subTask(str);

					}
					IElementLayout layout = htmlBuilder
							.getLayoutManager()
							.getLayout(element, true);
//					String htmlfile = htmlBuilder.generateHtml(layout);
					String htmlfile = runnable.generateHtml(layout);
					elementPublished(layout, htmlfile);

				} catch (Exception ex) {
					htmlBuilder
							.getValidator()
							.logError(
									element,
									NLS
											.bind(
													PublishingResources.publishElementError_msg,
													ex.getMessage()),
									ex);
				}
				publishedElements.add(element);
			} else {
				// System.out.println("Already generated: " +
				// getURL(element) );
			}
		} catch (RuntimeException e) {
			getHtmlBuilder()
					.getValidator()
					.logError(
							element,
							NLS
									.bind(
											PublishingResources.publishElementError_msg,
											e.getMessage()), e);
		}
	}

	protected void elementPublished(IElementLayout layout, String htmlfile) {
	}

	private void copyNodeIcon(File source) {
		String name = source.getName();

		File dest = new File(siteGenerator.getNodeIconPath(), name);
		if (FileUtil.copyFile(source, dest) == false) {
			getHtmlBuilder().getValidator().logWarning(
					NLS.bind(PublishingResources.copyFileWarning_msg, source
							.getAbsolutePath(), dest.getAbsolutePath()));
		}

	}

	private String getNodeIconName(Object obj) {
		File iconFile = null;
		String iconName = null;

		if (obj instanceof DescribableElement) {
			URI uri = ((DescribableElement) obj).getNodeicon();
			
			VariabilityElement uriInheritingBase = null;
			if (uri == null && config != null && obj instanceof VariabilityElement) {
				VariabilityElement[] uriInheritingBases = new VariabilityElement[1];
				uri = ConfigurationHelper.getInheritingUri((DescribableElement) obj, uri, uriInheritingBases, config, 0);
				uriInheritingBase = uriInheritingBases[0];
			}

			String elementName = ((DescribableElement) obj).getType().getName()
					.toLowerCase();
			if (DefaultElementTypeResources.useDefaultIcon(elementName))
				uri = null;

			if (uri != null) {
				// try if this is a valid URL or not
				boolean isFullPath = false;
				try {
					URL url = uri.toURL();
					if (url != null) {
						iconFile = new File(URLDecoder.decode(url.getFile(),
								"UTF-8")); //$NON-NLS-1$
						isFullPath = true;
					}
				} catch (Exception ex) {
					// not a valid url, maybe a relative path
				}

				if (!isFullPath) {
					// iconFile = new
					// File(LibraryService.getInstance().getCurrentMethodLibraryPath(),
					// URLDecoder.decode(uri.toString()));
					// To handle the nodeIcon uri, EPF 1.2, its changed now it
					// is relative to plugin path.
					iconFile = new File(
							TngUtil.getFullPathofNodeorShapeIconURI(
									uriInheritingBase == null ? (EObject) obj : uriInheritingBase, uri));
				}
			}
		}

		if ((iconFile != null) && !iconFile.exists()) {
			iconFile = null;
		}

		if (iconFile == null) {
			// get the default icon name
			if (obj instanceof MethodElement) {
				String type = ((MethodElement) obj).getType().getName()
						.toLowerCase();
				iconFile = IconUtil.getNodeIconFile(type);
			}
		}

		if (iconFile != null) {
			// need to copy the file together and zip for the applet
			if (!iconFile.exists()) {
				if (obj instanceof MethodElement) {
					getHtmlBuilder()
							.getValidator()
							.logWarning(
									(MethodElement) obj,
									NLS
											.bind(
													PublishingResources.missingIconFileWarning_msg,
													iconFile.getAbsolutePath()));
				} else {
					getHtmlBuilder()
							.getValidator()
							.logWarning(
									NLS
											.bind(
													PublishingResources.missingIconFileWarning_msg,
													iconFile.getAbsolutePath()));
				}
			}

			copyNodeIcon(iconFile);
			iconName = iconFile.getName();
		}

		if (iconName == null || iconName.length() == 0) {
			String name;
			if (obj instanceof MethodElement) {
				name = ((MethodElement) obj).getName();
			} else {
				name = obj.toString();
			}

			getHtmlBuilder().getValidator().logWarning(
					NLS.bind(PublishingResources.missingIconNameWarning_msg,
							name));
		}

		return iconName;
	}

	/**
	 * Gets the display name for a method element or iterm provider adapter.
	 * 
	 * @param obj
	 *            a method element or iterm provider adapter
	 * @return the display name or <code>null</code>
	 */
	private String getName(Object obj) {
		String name = null;
		if (obj instanceof MethodElement) {
			MethodElement e = (MethodElement) obj;

			// calculate the presentation name, for extenders, get from base if
			// needed
			name = ConfigurationHelper.getPresentationName(e, config);
			if (name == null || name.equals("")) { //$NON-NLS-1$
				name = e.getClass().getName();
				int index = name.lastIndexOf("."); //$NON-NLS-1$
				if (index >= 0) {
					name = name.substring(index + 1);
					if (name.endsWith("Impl")) { //$NON-NLS-1$
						name = name.substring(0, name.length() - 4);
					}
				}
			}
		} else if (obj instanceof ItemProviderAdapter) {
			ItemProviderAdapter provider = (ItemProviderAdapter) obj;
			name = provider.getText(obj);
		}
		return name;
	}

	/**
	 * Gets the GUID for a method element.
	 * 
	 * @param obj
	 *            a method element
	 * @return the GUID for a method element or <code>null</code>
	 */
	private String getGUID(Object obj) {
		if (obj instanceof MethodElement) {
			return ((MethodElement) obj).getGuid();
		} else
			return null;
	}

	/**
	 * Gets thr URL for a method element.
	 * 
	 * @param obj
	 *            a method element
	 * @return the URL for a method element or a blank HTML
	 */
	private String getURL(Object obj) {
		if (obj instanceof MethodElement) {
			return getLayoutMgr().getLayout((MethodElement) obj, true).getUrl();
		} else {
			// FIXME: layout needs to be provided for uncategorized and category
			// object
			return "applet//empty.htm"; //$NON-NLS-1$
		}
	}

	/**
	 * Creates a bookmark for a method element
	 * 
	 * @param element
	 *            a method element
	 * @return a <code>Bookmark</code>
	 */
	protected Bookmark createBookmark(IProgressMonitor monitor, Object element) {
		// publish this element
		if (element instanceof MethodElement) {
			// delay the publishing till the bookmarks are created.
			getHtmlBuilder().getValidator().addReferencedElement(null,
					(MethodElement) element);
		}

		// create a bookmark for this element
		String name = getName(element);
		String guid = getGUID(element);
		String url = getURL(element);
		String nodeIcon = getNodeIconName(element);

		String msg = NLS.bind(PublishingResources.generatingBookmarkTask_name,
				name);
		monitor.subTask(msg);
		return createBookmark(name, guid, url, nodeIcon, nodeIcon, element);
	}

	protected Bookmark createBookmark(String name, String guid, String url,
			String closeIcon, String openIcon, Object owner) {

		Bookmark b = new Bookmark(name);
		b.setPresentationName(name);
		b.setUniqueId(guid);
		b.setClosedIconName(closeIcon);
		b.setOpenIconName(openIcon);
		b.setFileName(url);
		b.setFromContentLibrary(true);
		b.setEnabled(true);
		b.setExist(true);
		b.setVisible(true);
		b.setTransparency(false);
		b.setDefault(true);
		b.setCurrent(false);
		b.setOwner(owner);
		return b;
	}

	/**
	 * Gets the default view.
	 * 
	 * @return a <code>Bookmark</code> that encapsulates the default view
	 */
	public Bookmark getDefaultView() {
		return defaultView;
	}

	/**
	 * Builds the views and returns a list of bookmark objects.
	 * 
	 * @param monitor
	 *            a progress monitor
	 * @return a list of <code>Bookmark</code>
	 */
	public abstract List<Bookmark> buildViews(IProgressMonitor monitor);

	/**
	 * Disposes this object.
	 */
	public void dispose() {

		config = null;
		if ( runnable != null ) {
			runnable.dispose();
			runnable = null;
		}
		
		if ( siteGenerator != null ) {
			siteGenerator.dispose();
			siteGenerator = null;
		}
	}

}
