//------------------------------------------------------------------------------
// 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.richtext.actions;

import java.io.File;
import java.net.URL;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.epf.common.serviceability.Logger;
import org.eclipse.epf.common.utils.ClipboardUtil;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.NetUtil;
import org.eclipse.epf.richtext.IRichText;
import org.eclipse.epf.richtext.RichTextCommand;
import org.eclipse.epf.richtext.RichTextEditor;
import org.eclipse.epf.richtext.RichTextImages;
import org.eclipse.epf.richtext.RichTextPlugin;
import org.eclipse.epf.richtext.RichTextResources;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.HTMLTransfer;
import org.eclipse.swt.widgets.Display;

/**
 * Pastes text from the clipboard onto a rich text control.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class PasteAction extends RichTextAction {

	private static final String SOURCE_URL = "SourceURL:"; //$NON-NLS-1$

	private static final String HTM_EXT = ".htm"; //$NON-NLS-1$

	private static final String HTML_EXT = ".html"; //$NON-NLS-1$

	private static final Pattern HREF_REFERENCES = Pattern
			.compile(
					"href\\s*=\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	protected static final Pattern p_image_ref = Pattern
			.compile(
					"(<(img|iframe).*?src\\s*=\\s*\")(.*?)(\")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	protected static String sourceURLStr = ""; //$NON-NLS-1$

	private Logger logger;
	
	private static String RESOURCES = "resources"; //$NON-NLS-1$

	/**
	 * Creates a new instance.
	 */
	public PasteAction() {
		super();
		setImage(RichTextImages.IMG_PASTE);
		setDisabledImage(RichTextImages.DISABLED_IMG_PASTE);
		setToolTipText(RichTextResources.pasteAction_toolTipText);
		setEnabled(true);
		logger = RichTextPlugin.getDefault().getLogger();
	}

	/**
	 * Returns <code>true</code> if this action should be disabled when the
	 * rich text editor is in source edit mode.
	 */
	public boolean disableInSourceMode() {
		return false;
	}

	/**
	 * Executes the action.
	 * 
	 * @param richText
	 *            a rich text control
	 */
	public void execute(IRichText richText) {
		if (richText != null) {
			copyLinkResources(richText);
			if (richText instanceof RichTextEditor
					&& ((RichTextEditor) richText).isHTMLTabSelected()) {
				StyledText styledText = ((RichTextEditor) richText)
						.getSourceEdit();
				styledText.paste();
			} else {
				richText.executeCommand(RichTextCommand.PASTE, sourceURLStr);
			}
		}
	}

	/**
	 * Copies the link resources.
	 * 
	 * @param richText
	 *            a rich text control
	 */
	protected void copyLinkResources(IRichText richText) {
		try {
			sourceURLStr = ClipboardUtil.getHTMLSourceURL();
			Clipboard clipboard = new Clipboard(Display.getCurrent());
			String html = (String) clipboard.getContents(HTMLTransfer
					.getInstance());
			if (html != null && html.length() > 0) {
				String basePath = richText.getBasePath();
				URL sourceURL = null;
				if (sourceURLStr == null || sourceURLStr.length() == 0
						|| sourceURLStr.equals("about:blank")) { //$NON-NLS-1$
					sourceURL = richText.getCopyURL();
				} else {
					sourceURL = new URL(sourceURLStr);
				}

				Matcher matcher = HREF_REFERENCES.matcher(html);
				while (matcher.find()) {
					String href = NetUtil.decodeURL(matcher.group(1));
					try {
						URL hrefURL = new URL(sourceURL, href);
						String scheme = hrefURL.getProtocol();
						if (scheme != null
								&& scheme
										.equalsIgnoreCase(NetUtil.FILE_SCHEME)) {
							String url = hrefURL.getPath();
							File srcFile = new File(url);
							File tgtFile = null;
							File tgtDir = null;
							if (href.startsWith(RESOURCES) || href.startsWith("./" + RESOURCES)) { //$NON-NLS-1$
								tgtFile = new File(basePath, href);
								tgtDir = tgtFile.getParentFile();
							} else {
								String resPath = getSubdirectoryOfResources(href);
								tgtFile = new File(basePath + RESOURCES, resPath);
								tgtDir = tgtFile;
							}
							tgtDir.mkdirs();
							FileUtil.copyFile(srcFile, tgtDir);
						}
					} catch (Exception e) {
						logger.logError(e);
					}
				}

				matcher = p_image_ref.matcher(html);
				while (matcher.find()) {
					String src = NetUtil.decodeURL(matcher.group(3));
					try {
						URL srcURL = new URL(sourceURL, src);
						String scheme = srcURL.getProtocol();
						if (scheme != null
								&& scheme.equalsIgnoreCase(NetUtil.FILE_SCHEME)) {
							File srcFile = null;
							String authority = srcURL.getAuthority();
							if (authority != null) {
								srcFile = new File(authority + srcURL.getPath());
							} else {
								srcFile = new File(srcURL.getPath());
							}
							File tgtFile = null;
							File tgtDir = null;
							if (src.startsWith(RESOURCES) || src.startsWith("./" + RESOURCES)) { //$NON-NLS-1$
								tgtFile = new File(basePath, src);
								tgtDir = tgtFile.getParentFile();
							} else {
								String resPath = getSubdirectoryOfResources(src);
								tgtFile = new File(basePath + RESOURCES, resPath);
								tgtDir = tgtFile;
							}
							tgtDir.mkdirs();
							FileUtil.copyFile(srcFile, tgtDir);
						}
					} catch (Exception e) {
						logger.logError(e);
					}
				}
			}
		} catch (Exception e) {
			logger.logError(e);
		}
	}

	/**
	 * Parses the given HTML content from the clipboard and returns the source
	 * URL.
	 * 
	 * @param htmlContent
	 *            the HTML content from the clipboard
	 * @return the source URL or <code>null</code>
	 */
	protected String getSourceURL(String htmlContent) {
		String sourceURL = null;
		int sourceURLIndex = htmlContent.indexOf(SOURCE_URL);
		if (sourceURLIndex > 0) {
			sourceURL = htmlContent.substring(sourceURLIndex
					+ SOURCE_URL.length());
			sourceURL = sourceURL.substring(0, sourceURL
					.indexOf(FileUtil.LINE_SEP));
			if (sourceURL.toLowerCase().endsWith(HTM_EXT)
					|| sourceURL.toLowerCase().endsWith(HTML_EXT)) {
				sourceURL = sourceURL.substring(0, sourceURL.indexOf(FileUtil
						.getFileName(sourceURL)) - 1);
				sourceURL = sourceURL.replace('\\', '/');
			}
			sourceURL = FileUtil.appendSeparator(sourceURL, "/"); //$NON-NLS-1$
		}
		return sourceURL;
	}

	protected String getSubdirectoryOfResources(String path) {
		String result = ""; //$NON-NLS-1$
		int res_idx = path.indexOf(RESOURCES);
		if (res_idx != -1) {
			Stack stack = new Stack();
			File relative = new File(path).getParentFile();
			while (!relative.getName().equals(RESOURCES)) {
				stack.push(relative.getName());
				relative = relative.getParentFile();
			}
			while (!stack.isEmpty()) {
				result = result + (String)stack.pop() + File.separator;
			}
		} 
		return result;
	}
	
}
