//------------------------------------------------------------------------------
// 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.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.ui.util.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.jface.action.IAction;
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(IRichText richText) {
		super(richText, IAction.AS_PUSH_BUTTON);
		setImageDescriptor(RichTextImages.IMG_DESC_PASTE);
		setDisabledImageDescriptor(RichTextImages.DISABLED_IMG_DESC_PASTE);
		setToolTipText(RichTextResources.pasteAction_toolTipText);
		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(NetUtil.decodeURL(url));
							File tgtFile = null;
							File tgtDir = null;
							if (href.startsWith("#") || sourceURL.sameFile(hrefURL)) { //$NON-NLS-1$
								continue;
							} else 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(NetUtil.decodeURL(authority + srcURL.getPath()));
							} else {
								srcFile = new File(NetUtil.decodeURL(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<String> stack = new Stack<String>();
			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;
	}
	
}
