/*
 * Copyright (c) 2006-2008 Maskat Project.
 *
 * 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:
 *     Maskat Project - initial API and implementation
 */
package org.maskat.ui.editors.preview;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.apache.commons.io.IOUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

import org.maskat.runtime.MaskatRuntimePlugin;
import org.maskat.ui.MaskatNature;
import org.maskat.ui.MaskatUIPlugin;
import org.maskat.ui.Messages;

public class LayoutPreviewBrowser extends EditorPart {

	/** The editor ID */
	public static final String EDITOR_ID = MaskatUIPlugin.PLUGIN_ID
			+ ".layoutPreviewBrowser"; //$NON-NLS-1$

	/** The swt browser control used to render layout */
	private Browser browser;

	public LayoutPreviewBrowser() {
		super();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		FillLayout layout = new FillLayout();
		composite.setLayout(layout);
		browser = new Browser(composite, SWT.NULL);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite,
	 *      org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		setSite(site);
		setInput(input);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.EditorPart#isDirty()
	 */
	public boolean isDirty() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
	 */
	public boolean isSaveAsAllowed() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		throw new UnsupportedOperationException();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
	 */
	public void doSaveAs() {
		throw new UnsupportedOperationException();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	public void setFocus() {
		try {
			//browser.setText(generateContents());
			browser.setUrl(generateContents().toString());
		} catch (Exception e) {
			browser.setText(Messages.getString("preview.create.msg.error")); //$NON-NLS-1$
		}
		browser.setFocus();
	}

	private URL generateContents() throws IOException, CoreException {
		IFile file = (IFile) getEditorInput().getAdapter(IFile.class);
		String frameworkBase = MaskatRuntimePlugin.getFrameworkBaseURL().toString();
		try {
			MaskatNature nature = MaskatNature.getNature(file.getProject());
			if (nature != null) {
				URI uri = nature.getProject().getLocationURI();
				uri = new URI(uri.toString() + nature.getMaskatFrameworkPath().toString() + "/"); //$NON-NLS-1$
				frameworkBase = FileLocator.toFileURL(uri.toURL()).toString();
			}
		} catch (URISyntaxException e) {}
	    
		/* create tempFolder */
		File idxFile = File.createTempFile("_maskat", "idx"); //$NON-NLS-1$
		idxFile.deleteOnExit();
		File tmpFolder = new File(idxFile.getParentFile().getAbsoluteFile(), "_maskat"); //$NON-NLS-1$
		tmpFolder.mkdir();
		tmpFolder.deleteOnExit();
		
		/* container html */		
		InputStream containerIn = null;
		OutputStream containerOut = null;
		File containerFile = null;
		try {
			containerFile = new File(tmpFolder, "preview.html"); //$NON-NLS-1$
			containerFile.createNewFile();
			containerFile.deleteOnExit();
			containerOut = new BufferedOutputStream(new FileOutputStream(containerFile));
			containerIn = getClass().getResourceAsStream("preview.html"); //$NON-NLS-1$
			String html = IOUtils.toString(containerIn, "UTF-8"); //$NON-NLS-1$
			containerOut.write(html.replaceAll(
					"\\Q${maskatFW}\\E", frameworkBase).getBytes("UTF-8")); //$NON-NLS-1$
		} finally {
			IOUtils.closeQuietly(containerIn);
			IOUtils.closeQuietly(containerOut);
		}
		/* layout XML */
		InputStream layoutIn = null;
		OutputStream layoutOut = null;
		try {
			File layoutFile = new File(tmpFolder, "layout.xml"); //$NON-NLS-1$
			layoutFile.createNewFile();
			layoutFile.deleteOnExit();
			layoutOut = new BufferedOutputStream(new FileOutputStream(layoutFile));
			layoutIn = file.getContents(true);
			IOUtils.copy(layoutIn, layoutOut);
		} finally {
			IOUtils.closeQuietly(layoutIn);
			IOUtils.closeQuietly(layoutOut);			
		}
		/* event XML */
		InputStream eventIn = null;
		OutputStream eventOut = null;
		try {
			File eventFile = new File(tmpFolder, "layout_e.xml");  //$NON-NLS-1$
			eventFile.createNewFile();
			eventFile.deleteOnExit();
			eventOut = new BufferedOutputStream(new FileOutputStream(eventFile));
			eventIn = getClass().getResourceAsStream("layout_e.xml"); //$NON-NLS-1$
			IOUtils.copy(eventIn, eventOut);
		} finally {
			IOUtils.closeQuietly(eventIn);
			IOUtils.closeQuietly(eventOut);			
		}		
		/* transition XML */
		InputStream transitionIn = null;
		OutputStream transitionOut = null;
		try {
			File transitionFile = new File(tmpFolder, "transition.xml"); //$NON-NLS-1$
			transitionFile.createNewFile();
			transitionFile.deleteOnExit();
			transitionOut = new BufferedOutputStream(new FileOutputStream(transitionFile));
			transitionIn = getClass().getResourceAsStream("transition.xml"); //$NON-NLS-1$
			IOUtils.copy(transitionIn, transitionOut);
		} finally {
			IOUtils.closeQuietly(transitionIn);
			IOUtils.closeQuietly(transitionOut);			
		}			
		return containerFile != null ? containerFile.toURL() : null;
	}		
}
