//------------------------------------------------------------------------------
// 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.library.layout;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.eclipse.epf.common.utils.Timer;
import org.eclipse.epf.common.xml.XSLTProcessor;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.layout.util.XmlHelper;
import org.eclipse.epf.library.util.ContentResourceScanner;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.MethodElement;

import com.ibm.icu.util.Calendar;


/**
 * Generates the HTML page for a Method element.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 */
public class HtmlBuilder {

	private boolean debug = false;

	private Properties xslParams = null;

	private ElementLayoutManager mgr = null;

	private ContentResourceScanner scanner = null;

	private boolean scanContent = true;

	// If true, display the "Show tree browse" image/link to the right of a
	// published page.
	private boolean showTreeBrowser = false;

	//private IContentValidator validator = null;

	/**
	 * Creates a new instance.
	 */
	public HtmlBuilder() {
		init();
	}

	/**
	 * Creates a new instance.
	 */
	public HtmlBuilder(ElementLayoutManager mgr) {
		init();
		setLayoutManager(mgr);
	}

	/**
	 * Performs the necessary initialization.
	 */
	protected void init() {
		debug = LibraryPlugin.getDefault().isDebugging();
		try {
			xslParams = LibraryPlugin.getDefault().getProperties(
					"/layout/xsl/resources.properties"); //$NON-NLS-1$
			
			// add the colon property, 
			xslParams.put("colon_with_space", LibraryResources.colon_with_space);
			
		} catch (IOException e) {
			xslParams = null;
		}
	}

	/**
	 * Returns the publish directory.
	 */
	public String getPublishDir() {
		return (mgr == null) ? null : mgr.getPublishDir();
	}

	/**
	 * Returns the publish directory.
	 */
	public void setPublishDir(String dir) {
		if (mgr != null) {
			mgr.setPublishDir(dir);
		}

		getScanner().setTargetRootPath(new File(getPublishDir()));

		// Reset the validator's publish dir.
		getValidator().setPublishDir(dir);
	}

//	/**
//	 * Sets the content validator.
//	 */
//	public void setValidator(IContentValidator validator) {
//		this.validator = validator;
//		getScanner().setValidator(this.validator);
//	}

	/**
	 * Returns the content validator.
	 */
	public IContentValidator getValidator() {
//		if (validator == null) {
//			validator = new DefaultContentValidator(getPublishDir());
//		}
//		return validator;
		
		return this.mgr.getValidator();
	}

	/**
	 * Returns the content resource scanner.
	 */
	private ContentResourceScanner getScanner() {
		if (scanner == null) {
			scanner = new ContentResourceScanner(new File(LibraryService.getInstance()
					.getCurrentMethodLibraryPath()), getValidator());
			if (mgr != null) {
				scanner.setTargetRootPath(new File(getPublishDir()));
			}
		}
		return scanner;
	}

	/**
	 * Sets the flag to display the "Show tree browser" image/link.
	 */
	public void enableTreeBrowser(boolean flag) {
		this.showTreeBrowser = flag;
	}

	/**
	 * Enables content scanning.
	 */
	public void enableContentScan(boolean scan) {
		this.scanContent = scan;
	}

	/**
	 * Returns <code>true</code> if content scanning is enabled.
	 */
	public boolean contentScanEnabled() {
		return scanContent;
	}

	/**
	 * Sets the Element Layout Manager.
	 * <p>
	 * A Element Layout Manager is associated with a configuration.
	 */
	public void setLayoutManager(ElementLayoutManager mgr) {
		this.mgr = mgr;
		if (this.mgr == null) {
			this.mgr = getDefaultLayoutManager();
		}

		// Update the scanner target path.
		getScanner().setTargetRootPath(new File(getPublishDir()));

		// Reset the validator pub dir.
		getValidator().setPublishDir(getPublishDir());
	}

	/**
	 * Returns the default Element Layout Manager.
	 */
	private ElementLayoutManager getDefaultLayoutManager() {
		return new ElementLayoutManager();
	}

	/**
	 * Returns the Element Layout Manager.
	 */
	public ElementLayoutManager getLayoutManager() {
		if (this.mgr == null) {
			this.mgr = getDefaultLayoutManager();
			;
		}
		return mgr;
	}

	/**
	 * Generates the HTML for a Method element.
	 * 
	 * @param element
	 *            A Method element.
	 * @return A url of the generated content HTML file.
	 */
	public String generateHtml(MethodElement element) {
		String url = null;
		if (debug) {
			long startTime = System.currentTimeMillis();
			IElementLayout layout = getLayoutManager().getLayout(element, true);
			url = generateHtml(layout);
			long endTime = System.currentTimeMillis();
			System.out
					.println("Time taken to render HTML page for " + element.getName() + //$NON-NLS-1$
							": " + (endTime - startTime) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			IElementLayout layout = getLayoutManager().getLayout(element, true);
			url = generateHtml(layout);
		}
		return url;
	}


	/**
	 * Generates the HTML for a Method element.
	 * 
	 * @param url
	 *            The URL of a Method element.
	 */
	public void generateHtml(String url) {
		IElementLayout layout = getLayoutManager().getLayout(url);
		generateHtml(layout);
	}

	/**
	 * Generates the HTML for a Method element.
	 * 
	 * @param layout
	 *            A Method Element. Layout object.
	 * @param linkedElements
	 *            If not null, this object will be populated with a list of
	 *            linked elements in the page.
	 * @return A url of the generated content HTML file.
	 */
	public String generateHtml(IElementLayout layout) {
		if (layout == null) {
			return "about:blank"; //$NON-NLS-1$
		}

		// add time logging when publishing element
		long time_start = Calendar.getInstance().getTimeInMillis();
		String elementPath = layout.getFilePath().replace('/',
				File.separatorChar);
		String elementPathName = elementPath
				+ layout.getFileName(ResourceHelper.FILE_EXT_HTML);
		String filePath = this.getPublishDir() + elementPath;
		String html_file = this.getPublishDir() + elementPathName;

		try {

			StringBuffer xml = getXml(layout);

			String xsl_uri;

			File f = new File(filePath);
			if (!f.exists()) {
				f.mkdirs();
			}

			// Generate the additonal outputs.
			List layouts = layout.getLayouts();
			xsl_uri = layout.getXslUrl();
			generateHtml(layout, xsl_uri, html_file, xml);

			// Generate other layout files.
			if (layouts != null && layouts.size() > 0) {
				for (Iterator it = layouts.iterator(); it.hasNext();) {
					LayoutInfo info = (LayoutInfo) it.next();
					xsl_uri = LibraryPlugin.getDefault().getLayoutXslPath()
							+ info.layout_xsl;
					String file = filePath + info.fileName;
					generateHtml(layout, xsl_uri, file, xml);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			html_file = null;
		}

		long time_end = Calendar.getInstance().getTimeInMillis();
		long mini_seconds = time_end - time_start;
		if (mini_seconds > 1000) {
			String msg = mini_seconds
					+ " mini-second(s) publishing element " + LibraryUtil.getTypeName(layout.getElement()) + "[" + elementPathName + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			IContentValidator validator = getValidator();
			if (validator == null) {
				System.out.println(msg);
			} else {
				validator.logInfo(msg);
			}
		}
		if (html_file != null) {
			return html_file;
		}

		return "about:blank"; //$NON-NLS-1$
	}

	/**
	 * Generates the HTML for a Method element.
	 * 
	 * @param layout
	 *            A Method Element. Layout object.
	 * @param xslURI
	 *            The XSL stylesheet.
	 * @param htmlFile
	 *            The HTML file to be generated.
	 * @param xml
	 *            The XML buffer.
	 * @return A url of the generated content HTML file.
	 */
	private void generateHtml(IElementLayout layout,
			String xsl_uri, String html_file, StringBuffer xml) {
		Throwable th = null;
		if (layout == null) {
			return;
		}

		Timer timer = null;
		if ( debug ) {
			timer = new Timer();
		}
		
		try {
			StringWriter sw = new StringWriter();
			XSLTProcessor.transform(xsl_uri, xml.toString(), xslParams, sw);
			sw.flush();
			String content = sw.getBuffer().toString();

			if ( debug) {
				timer.stop();
				System.out.println(timer.getTime() + " mini seconds for xml/xslt transformation");
				timer.start();
			}
			// Always validate and fix the content before publishing.
			content = ResourceHelper.validateContent(layout.getElement(),
					content, getValidator(), layout.getLayoutMgr()
							.getConfiguration());
			if (contentScanEnabled()) {
				scanContentForResources(layout.getElement(), content, layout
						.getFilePath());
			}

			if ( debug) {
				timer.stop();
				System.out.println(timer.getTime() + " mini seconds scanning content");
				timer.start();
			}
			
			OutputStreamWriter output = new OutputStreamWriter(
					new FileOutputStream(html_file), "utf-8"); //$NON-NLS-1$
			output.write(content);
			output.flush();
			output.close();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			th = e;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			th = e;
		} catch (IOException e) {
			e.printStackTrace();
			th = e;
		} catch (Exception e) {
			e.printStackTrace();
			th = e;
		}

		if (th != null) {
			this.getValidator().logError(layout.getElement(),
					"Error generating element content", th); //$NON-NLS-1$
		}
	}

	/**
	 * Generates the HTML for a Method element.
	 * 
	 * @param layout
	 *            A Method Element. Layout object.
	 * @return A url of the generated content HTML file.
	 */
	private StringBuffer getXml(IElementLayout layout) {
		StringBuffer xml = new StringBuffer();
		XmlElement xmlElement = layout.getXmlElement(true);
		if (showTreeBrowser) {
			xmlElement.setAttribute("showTreeBrowser", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		xml.append(XmlHelper.XML_HEADER).append(xmlElement.toXml());

		if ( debug ) {
			try {
				String xml_file = this.getPublishDir() + "xml" + File.separator; //$NON-NLS-1$
				xml_file += layout.getType() + "." + layout.getFileName(".xml"); //$NON-NLS-1$ //$NON-NLS-2$
				File xf = new File(xml_file);
				if ( !xf.exists() )
				{
					xf.getParentFile().mkdirs();
					xf.createNewFile();
				}
							
				OutputStreamWriter output = new OutputStreamWriter(
						new FileOutputStream(xf), "utf-8"); //$NON-NLS-1$
				output.write(xml.toString());
				output.flush();
				output.close();
	
				// FileWriter xw = new FileWriter(xml_file);
				// xw.write(xml.toString());
				// xw.flush();
				// xw.close();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		
		return xml;
	}

	/**
	 * Scans the content for resource references.
	 */
	private void scanContentForResources(MethodElement owner, String content,
			String contentPath) {
		getScanner().resolveResources(owner, content, contentPath);
	}

	public void dispose() {
//		if (validator != null) {
//			validator.dispose();
//		}

		mgr = null;
		scanner = null;
//		validator = null;
	}
}
