//------------------------------------------------------------------------------
// 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.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;
	
	/**
	 * 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();
	}

	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();
				if (sourceURLStr == null || sourceURLStr.length() == 0) {
					sourceURLStr = basePath;
				}
				URL sourceURL = new URL(sourceURLStr);

				Matcher matcher = HREF_REFERENCES.matcher(html);
				while (matcher.find()) {
					String href = NetUtil.decodeURL(matcher.group(1));
					if (href.toLowerCase().endsWith(HTM_EXT)
							|| href.toLowerCase().endsWith(HTML_EXT)) {
						try {
							URL hrefURL = new URL(sourceURL, href);
							String scheme = hrefURL.getProtocol();
							if (scheme != null
									&& scheme.equalsIgnoreCase(NetUtil.FILE_SCHEME)) {
								String url = hrefURL.toString();
								File srcFile = new File(url);
								File tgtFile = new File(basePath + "resources"); //$NON-NLS-1$
								tgtFile.mkdirs();
								FileUtil.copyFile(srcFile, tgtFile);
							}
						} 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 = new File(basePath + "resources"); //$NON-NLS-1$
							tgtFile.mkdirs();
							FileUtil.copyFile(srcFile, tgtFile);
						}
					} 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;
	}

}
