//------------------------------------------------------------------------------
// 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.configuration.PracticeSubgroupItemProvider;
import org.eclipse.epf.library.edit.util.MethodElementPropUtil;
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.CustomCategory;
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()));
		}

	}

	protected 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();
				if (obj instanceof CustomCategory) {
					CustomCategory cc = (CustomCategory) obj;
					MethodElementPropUtil propUtil = MethodElementPropUtil
							.getMethodElementPropUtil();
					if (propUtil.isTransientElement(cc)) {
						if (cc.getName().equals("Roles")) {//$NON-NLS-1$
							type = "roleset";//$NON-NLS-1$
						} else if (cc.getName().equals("Tasks")) {//$NON-NLS-1$
							type = "discipline";//$NON-NLS-1$
						} else if (cc.getName().equals("Work Products")) {//$NON-NLS-1$
							type = "domain";//$NON-NLS-1$
						} else if (cc.getName().equals("Guidance")) {//$NON-NLS-1$
							type = "guidances";//$NON-NLS-1$
						} else if (cc.getName().equals("Processes")) {//$NON-NLS-1$
							type = "processes";//$NON-NLS-1$
						}
					}
				}
				iconFile = IconUtil.getNodeIconFile(type);
			} else if (obj instanceof PracticeSubgroupItemProvider) {
				iconFile = IconUtil.getNodeIconFile((PracticeSubgroupItemProvider) obj);
			}
		}

		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;
		}
	}

}
