package org.eclipse.epf.publishing.services;

import java.io.File;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.layout.Bookmark;
import org.eclipse.epf.library.layout.BookmarkList;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.layout.LayoutResources;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.publishing.PublishingPlugin;
import org.eclipse.epf.publishing.util.PublishingUtil;

public class DefaultSiteGenerator implements ISiteGenerator {

	public static final String DOC_ROOT = "docroot/"; //$NON-NLS-1$;

	public static final String NO_APPLET_DIRECTORY = "noapplet"; //$NON-NLS-1$

	// public static final String BOOKMARK_SUFFIX = ".bkm"; //$NON-NLS-1$
	public static final String BOOKMARK_SUFFIX_XML = ".xml"; //$NON-NLS-1$

	public static final String BOOKMARK_SUFFIX_HTML = ".html"; //$NON-NLS-1$

	public static final String SPACE_REPLACEMENT = "_"; //$NON-NLS-1$

	public static final String SPACE_STRING = " "; //$NON-NLS-1$

	// public static final String DEFAULT_BOOKMARK_CFG_NAME =
	// "DefaultBookmark.cfg"; //$NON-NLS-1$
	public static final String PUBLISHED_BOOKMARKS_CFG_NAME = "PublishedBookmarks.xml"; //$NON-NLS-1$

	public static final String PUBLISHED_BOOKMARKS_DELIMITER = "*"; //$NON-NLS-1$

	protected static final String BOOKMARK_XSL_FILE = "xsl/bookmark.xsl"; //$NON-NLS-1$

	protected static final String BOOKMARKS_XSL_FILE = "xsl/PublishedBookmarks.xsl"; //$NON-NLS-1$

	protected static final String INDEX_XSL_FILE = "xsl/index.xsl"; //$NON-NLS-1$

	protected static final String TOPNAV_XSL_FILE = "xsl/topnav.xsl"; //$NON-NLS-1$

	private static final String APPLET_PATH = "applet" + File.separatorChar; //$NON-NLS-1$
	private static final String NO_APPLET_PATH = "noapplet" + File.separatorChar; //$NON-NLS-1$
	private static final String ICON_PATH = "images" + File.separatorChar; //$NON-NLS-1$


	protected String pubDir;
	protected PublishOptions options;
	protected HtmlBuilder builder;
	
	protected 	File iconPath;

	public DefaultSiteGenerator(HtmlBuilder builder, PublishOptions options) {
		this.options = options;
		this.builder = builder;
		this.pubDir = builder.getPublishDir();

		iconPath = new File(pubDir, APPLET_PATH + ICON_PATH);

	}
	
	public HtmlBuilder getHtmlBuilder() {
		return builder;
	}
	
	public PublishOptions getPublishOptions() {
		return options;
	}

	public String getNodeIconPath() {
		return iconPath.getAbsolutePath();
	}
	
	public void prePublish() throws Exception {
		copyFiles();
	}
	
	public void postPublish() throws Exception {
		copyIconsForNonApplet();
		writeIndexAndTopNavHtml();
	}
	
	protected void copyFiles() throws Exception {

		copyDocRootFiles();

		// copy localized files
		copyLocalizedFiles();

		// copy user customized files last
		copyCustomizedFiles();
	}

	protected void copyDocRootFiles() throws Exception {

		URL plugin_url = PublishingPlugin.getDefault().getInstallURL();
		URL url = new URL(plugin_url, DOC_ROOT);
		String fromPath = Platform.resolve(url).getPath();

		// folders that apply to all
		// NOTE: applet images should always be included since it's used in
		// Atlantic configuration
		// applet/help.htm is used in RSA to check character encoding, so
		// need to include this file
		// Process Advisor: FileNotFoundException in RSA log
		// when indexing start on a non-applet published site
		String includes = "*.*, process/**, images/**, index/**, scripts/**, stylesheets/**"; //$NON-NLS-1$

		String excludes = ""; //$NON-NLS-1$

		// based on the selection, copy the other folders
		if (options.useDefaultTreeBrowser) {
			includes += ", noapplet/**"; //$NON-NLS-1$
		}

		// String publishDir = viewBuilder.getHtmlBuilder().getPublishDir();

		LayoutResources.copyDir(fromPath, pubDir, includes, excludes);

	}

	protected void copyCustomizedFiles() throws Exception {
		if (options.bannerImage != null && options.bannerImage.length() > 0) {
			FileUtil.copyFile(options.bannerImage, pubDir + "images"); //$NON-NLS-1$
			options.bannerImage = FileUtil.getFileName(options.bannerImage);
		} else {
			options.bannerImage = "banner.gif"; //$NON-NLS-1$
		}

		if (options.aboutHTML != null && options.aboutHTML.length() > 0) {
			FileUtil.copyFile(options.aboutHTML, pubDir + "about.htm"); //$NON-NLS-1$
		}
	}

	protected void copyLocalizedFiles() throws Exception {

		// copy scripts, rename the localse specific name to the default
		// name
		PublishingPlugin
				.getDefault()
				.copyLocalizedFiles(
						DOC_ROOT + "scripts/", new File(pubDir, "scripts/"), true, false); //$NON-NLS-1$ //$NON-NLS-2$

		PublishingPlugin.getDefault().copyLocalizedFiles(
				DOC_ROOT + "images/", new File(pubDir, "images/"), true, false); //$NON-NLS-1$ //$NON-NLS-2$

		PublishingPlugin.getDefault().copyLocalizedFiles(DOC_ROOT,
				new File(pubDir, "/"), false, false); //$NON-NLS-1$ //$NON-NLS-2$

		if (options.useDefaultTreeBrowser) {
			// copy the applet html files, rename locale specific names
			PublishingPlugin
					.getDefault()
					.copyLocalizedFiles(
							DOC_ROOT + "noapplet/", new File(pubDir, "noapplet/"), false, false); //$NON-NLS-1$ //$NON-NLS-2$
		}

	}
	
	protected void copyIconsForNonApplet()
	{
		try
		{
			// don't jar it. copy the icons to the images
//			File jarFile = new File(builder.getPublishDir(), APPLET_PATH + ICON_ZIP_FILE);
//			PublishingUtil.jarFiles(iconPath, jarFile);

			if ( options.useDefaultTreeBrowser )
			{
				// also copy the icons to the no-applet folder
				LayoutResources.copyDir(iconPath.getAbsolutePath(), pubDir + NO_APPLET_PATH + ICON_PATH);
			}
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	protected String makeBookmarkFileName(String bookmarkName) {
		return bookmarkName.replace(SPACE_STRING.charAt(0), SPACE_REPLACEMENT
				.charAt(0))
				+ BOOKMARK_SUFFIX_XML;
	}


	private String writeBookmark(Bookmark b) {

		// get the bookmark name from the bookmark url
		String bookmarkFileName = makeBookmarkFileName(StrUtil
				.removeSpecialCharacters(b.getPresentationName()));
		XmlElement xml = b.getXmlElement();

		String buffer = PublishingUtil.getHtml(xml, BOOKMARK_XSL_FILE);
		if (buffer != null) {
			String htmlPath = getBookmarkHtmlPath(bookmarkFileName);
			FileUtil.writeUTF8File(htmlPath, buffer.toString());
		}

		return bookmarkFileName;
	}

	public void writePublishedBookmarks(List bookmarks, Bookmark defaultView) throws Exception {
		
		// first write xml for each individual view 
		BookmarkList list = new BookmarkList();

		if ((defaultView == null) && (bookmarks.size() > 0)) {
			defaultView = (Bookmark) bookmarks.get(0);
		}

		for (Iterator it = bookmarks.iterator(); it.hasNext();) {
			Bookmark b = (Bookmark) it.next();
			String fileName = writeBookmark(b);
			list.addBookmark(b.getPresentationName(), fileName,
					(defaultView == b));
		}
		
		// then write the top level bookmark xml
		XmlElement xml = list.getXmlElement();

		String buffer = PublishingUtil.getHtml(xml, BOOKMARKS_XSL_FILE);
		if (buffer != null) {
			String htmlPath = getBookmarkHtmlPath(PUBLISHED_BOOKMARKS_CFG_NAME);
			FileUtil.writeUTF8File(htmlPath, buffer.toString());
		}
	}
	
	protected void writeIndexAndTopNavHtml() {

		XmlElement optionXml = getOptionXml();
		
		String buffer = PublishingUtil.getHtml(optionXml, INDEX_XSL_FILE);
		if (buffer != null) {
			String htmlPath = getIndexFilePath();
			FileUtil.writeUTF8File(htmlPath, buffer.toString());
		}

		buffer = PublishingUtil.getHtml(optionXml, TOPNAV_XSL_FILE);
		if (buffer != null) {
			String htmlPath = pubDir + "topnav.htm"; //$NON-NLS-1$
			FileUtil.writeUTF8File(htmlPath, buffer.toString());
		}
	}
	
	protected String getBookmarkHtmlPath(String boomkarkFile) {
		int indx = boomkarkFile.lastIndexOf(BOOKMARK_SUFFIX_XML);
		return pubDir
				+ NO_APPLET_DIRECTORY + File.separatorChar
				+ boomkarkFile.substring(0, indx) + BOOKMARK_SUFFIX_HTML;
	}
	
	public String getIndexFilePath() {
		return pubDir + "index.htm"; //$NON-NLS-1$
	}

	protected XmlElement getOptionXml() {
		boolean showGlossary = (options == null) || options.generateGlossary;
		boolean showIndex = (options == null) || options.generateIndex;

		XmlElement optionXml = new XmlElement("PublishingOption") //$NON-NLS-1$
		.setAttribute("title", (options == null) ? "" : options.title) //$NON-NLS-1$ //$NON-NLS-2$
		.setAttribute(
				"bannerImage", (options == null) ? "" : options.bannerImage) //$NON-NLS-1$ //$NON-NLS-2$
		.setAttribute(
				"feedbackUrl", (options == null) ? "" : options.feedbackURL) //$NON-NLS-1$ //$NON-NLS-2$
		.setAttribute("showGlossary", (showGlossary ? "true" : "false")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		.setAttribute("showIndex", (showIndex ? "true" : "false")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		return optionXml;
	}
	
}
