/*******************************************************************************
 * Copyright (c) 2004, 2011 Jeff Pound and others.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Jeff Pound - initial API and implementation
 *     Tasktop Technologies - improvement
 *******************************************************************************/

package org.eclipse.mylyn.internal.tasks.ui.wizards;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentMapper;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Text;

/**
 * Shows a preview of an attachment.
 * 
 * @author Jeff Pound
 * @author Steffen Pingel
 */
public class AttachmentPreviewPage extends WizardPage {

	private static final String DIALOG_SETTING_RUN_IN_BACKGROUND = "run-in-background"; //$NON-NLS-1$

	private static final String DIALOG_SETTINGS_SECTION_ATTACHMENTS_WIZARD = "attachments-wizard"; //$NON-NLS-1$

	protected static final int MAX_TEXT_SIZE = 50000;

	private static final String PAGE_NAME = "PreviewAttachmentPage"; //$NON-NLS-1$

	private final Set<String> imageTypes;

	private final TaskAttachmentModel model;

	private Button runInBackgroundButton;

	private ScrolledComposite scrolledComposite;

	private final Set<String> textTypes;

	private Composite contentComposite;

	public AttachmentPreviewPage(TaskAttachmentModel model) {
		super(PAGE_NAME);
		this.model = model;
		setTitle(Messages.AttachmentPreviewPage_Attachment_Preview);
		setDescription(Messages.AttachmentPreviewPage_Review_the_attachment_before_submitting);

		textTypes = new HashSet<String>();
		textTypes.add("text/plain"); //$NON-NLS-1$
		textTypes.add("text/html"); //$NON-NLS-1$
		textTypes.add("application/xml"); //$NON-NLS-1$

		imageTypes = new HashSet<String>();
		imageTypes.add("image/jpeg"); //$NON-NLS-1$
		imageTypes.add("image/gif"); //$NON-NLS-1$
		imageTypes.add("image/png"); //$NON-NLS-1$
		imageTypes.add("image/tiff"); //$NON-NLS-1$
	}

	private void adjustScrollbars(Rectangle imgSize) {
		Rectangle clientArea = scrolledComposite.getClientArea();

		ScrollBar hBar = scrolledComposite.getHorizontalBar();
		hBar.setMinimum(0);
		hBar.setMaximum(imgSize.width - 1);
		hBar.setPageIncrement(clientArea.width);
		hBar.setIncrement(10);

		ScrollBar vBar = scrolledComposite.getVerticalBar();
		vBar.setMinimum(0);
		vBar.setMaximum(imgSize.height - 1);
		vBar.setPageIncrement(clientArea.height);
		vBar.setIncrement(10);
	}

	public void createControl(Composite parent) {
		final Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout());
		setControl(composite);

		contentComposite = new Composite(composite, SWT.NONE);
		contentComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
		contentComposite.setLayout(new GridLayout());

		runInBackgroundButton = new Button(composite, SWT.CHECK);
		runInBackgroundButton.setText(Messages.AttachmentPreviewPage_Run_in_background);

		IDialogSettings settings = TasksUiPlugin.getDefault().getDialogSettings();
		IDialogSettings attachmentsSettings = settings.getSection(DIALOG_SETTINGS_SECTION_ATTACHMENTS_WIZARD);
		if (attachmentsSettings != null) {
			runInBackgroundButton.setSelection(attachmentsSettings.getBoolean(DIALOG_SETTING_RUN_IN_BACKGROUND));
		}

		Dialog.applyDialogFont(composite);
	}

	@Override
	public void dispose() {
		IDialogSettings settings = TasksUiPlugin.getDefault().getDialogSettings();
		IDialogSettings attachmentsSettings = settings.getSection(DIALOG_SETTINGS_SECTION_ATTACHMENTS_WIZARD);
		if (attachmentsSettings == null) {
			attachmentsSettings = settings.addNewSection(DIALOG_SETTINGS_SECTION_ATTACHMENTS_WIZARD);
		}
		attachmentsSettings.put(DIALOG_SETTING_RUN_IN_BACKGROUND, runInBackgroundButton.getSelection());
		super.dispose();
	}

	@Override
	public void setVisible(boolean visible) {
		if (visible) {
			Control[] children = contentComposite.getChildren();
			for (Control control : children) {
				control.dispose();
			}
			if (isTextAttachment() || isImageAttachment()) {
				Object content = getContent(contentComposite);
				if (content instanceof String) {
					createTextPreview(contentComposite, (String) content);
				} else if (content instanceof Image) {
					createImagePreview(contentComposite, (Image) content);
				}
			} else {
				createGenericPreview(contentComposite);
			}
			contentComposite.layout(true, true);
		}
		Dialog.applyDialogFont(contentComposite);
		super.setVisible(visible);
	}

	private void createErrorPreview(Composite composite, String message) {
		Label label = new Label(composite, SWT.NONE);
		label.setLayoutData(new GridData(GridData.FILL_BOTH));
		label.setText(message);
	}

	private void createGenericPreview(Composite composite) {
		Label label = new Label(composite, SWT.NONE);
		label.setLayoutData(new GridData(GridData.FILL_BOTH));
		// TODO 3.5 put filename on model
		String name = model.getSource().getName();
		TaskAttachmentMapper taskAttachment = TaskAttachmentMapper.createFrom(model.getAttribute());
		if (taskAttachment.getFileName() != null) {
			name = taskAttachment.getFileName();
		}
		label.setText(MessageFormat.format(
				Messages.AttachmentPreviewPage_A_preview_the_type_X_is_currently_not_available, name,
				model.getContentType()));
	}

	private void createImagePreview(Composite composite, final Image bufferedImage) {
		scrolledComposite = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		scrolledComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
		scrolledComposite.setExpandHorizontal(true);
		scrolledComposite.setExpandVertical(true);

		Composite canvasComposite = new Composite(scrolledComposite, SWT.NONE);
		canvasComposite.setLayout(GridLayoutFactory.fillDefaults().create());
		Canvas canvas = new Canvas(canvasComposite, SWT.NO_BACKGROUND);
		final Rectangle imgSize = bufferedImage.getBounds();
		canvas.setLayoutData(GridDataFactory.fillDefaults()
				.align(SWT.CENTER, SWT.CENTER)
				.grab(true, true)
				.hint(imgSize.width, imgSize.height)
				.create());
		canvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				event.gc.drawImage(bufferedImage, 0, 0);
			}
		});
		canvas.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				bufferedImage.dispose();
			}
		});
		canvas.setSize(imgSize.width, imgSize.height);
		scrolledComposite.setMinSize(imgSize.width, imgSize.height);
		scrolledComposite.setContent(canvasComposite);
		scrolledComposite.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent event) {
				adjustScrollbars(imgSize);
			}

		});
		adjustScrollbars(imgSize);
	}

	private void createTextPreview(Composite composite, String contents) {
		Text text = new Text(composite, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.heightHint = composite.getBounds().y;
		gd.widthHint = composite.getBounds().x;
		text.setLayoutData(gd);
		text.setText(contents);
	}

	private Object getContent(final Composite composite) {
		final Object result[] = new Object[1];
		try {
			getContainer().run(true, false, new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					try {
						monitor.beginTask(Messages.AttachmentPreviewPage_Preparing_preview, IProgressMonitor.UNKNOWN);
						final InputStream in = model.getSource().createInputStream(monitor);
						try {
							if (isTextAttachment()) {
								StringBuilder content = new StringBuilder();
								BufferedReader reader = new BufferedReader(new InputStreamReader(in));
								String line;
								while ((line = reader.readLine()) != null && content.length() < MAX_TEXT_SIZE
										&& !monitor.isCanceled()) {
									content.append(line);
									content.append("\n"); //$NON-NLS-1$
								}
								result[0] = content.toString();
							} else if (isImageAttachment()) {
								Display.getDefault().syncExec(new Runnable() {
									public void run() {
										// Uses double buffering to paint the image; there was a weird behavior
										// with transparent images and flicker with large images
										Image originalImage = new Image(getShell().getDisplay(), in);
										final Image bufferedImage = new Image(getShell().getDisplay(),
												originalImage.getBounds());
										GC gc = new GC(bufferedImage);
										gc.setBackground(composite.getBackground());
										gc.fillRectangle(originalImage.getBounds());
										gc.drawImage(originalImage, 0, 0);
										gc.dispose();
										originalImage.dispose();
										result[0] = bufferedImage;
									}
								});
							}
						} catch (IOException e) {
							throw new InvocationTargetException(e);
						} finally {
							try {
								in.close();
							} catch (IOException e) {
								StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
										"Failed to close file", e)); //$NON-NLS-1$
							}
						}
					} catch (CoreException e) {
						throw new InvocationTargetException(e);
					} finally {
						monitor.done();
					}
				}
			});
		} catch (InvocationTargetException e) {
			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Error generating preview", e)); //$NON-NLS-1$
			createErrorPreview(composite, Messages.AttachmentPreviewPage_Could_not_create_preview);
			return null;
		} catch (InterruptedException e) {
			return null;
		}
		return result[0];
	}

	private boolean isImageAttachment() {
		return imageTypes.contains(model.getContentType());
	}

	private boolean isTextAttachment() {
		return textTypes.contains(model.getContentType());
	}

	public boolean runInBackground() {
		return runInBackgroundButton.getSelection();
	}

}
