/*******************************************************************************
 * Copyright (c) 2008 The Eclipse Foundation.
 * 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:
 *    The Eclipse Foundation - initial API and implementation
 *******************************************************************************/
package org.eclipse.epp.usagedata.internal.ui.preview;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.epp.usagedata.internal.gathering.events.UsageDataEvent;
import org.eclipse.epp.usagedata.internal.recording.filtering.FilterChangeListener;
import org.eclipse.epp.usagedata.internal.recording.filtering.FilterUtils;
import org.eclipse.epp.usagedata.internal.recording.filtering.PreferencesBasedFilter;
import org.eclipse.epp.usagedata.internal.recording.uploading.UploadParameters;
import org.eclipse.epp.usagedata.internal.recording.uploading.UsageDataFileReader;
import org.eclipse.epp.usagedata.internal.ui.Activator;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
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.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.forms.widgets.FormText;

public class UploadPreview  {

	private final UploadParameters parameters;
	
	TableViewer viewer;
	Job contentJob;
	List<UsageDataEventWrapper> events = Collections.synchronizedList(new ArrayList<UsageDataEventWrapper>());
	
	private static final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
	
	private UsageDataTableViewerColumn includeColumn;
	private UsageDataTableViewerColumn whatColumn;
	private UsageDataTableViewerColumn kindColumn;
	private UsageDataTableViewerColumn descriptionColumn;
	private UsageDataTableViewerColumn bundleIdColumn;
	private UsageDataTableViewerColumn bundleVersionColumn;
	private UsageDataTableViewerColumn timestampColumn;
	
	private Color colorGray;
	private Color colorBlack;
	private Image xImage;

	private Cursor busyCursor;

	Button removeFilterButton;

	private Button eclipseOnlyButton;

	private Button addFilterButton;

	public UploadPreview(UploadParameters parameters) {
		this.parameters = parameters;
	}

	public Control createControl(final Composite parent) {
		allocateResources(parent);
		
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout());
		
		createDescriptionText(composite);
		createEventsTable(composite);
		createEclipseOnlyButton(composite);
		createButtons(composite);
		
		/*
		 * Bit of a crazy idea. Add a paint listener that will
		 * start the job of actually populating the page when
		 * the composite is exposed. If the instance is created
		 * in a wizard, it won't start populating until the user
		 * actually switches to the page.
		 */
		final PaintListener paintListener = new PaintListener() {
			boolean called = false;
			// Don't need to synchronize since this will only ever be called in the UI thread.
			public void paintControl(PaintEvent e) {
				if (called) return;
				called = true;
				startContentJob();
			}			
		};
		composite.addPaintListener(paintListener);
		
		return composite;
	}

	/*
	 * This method allocates the resources used by the receiver.
	 * It installs a dispose listener on parent so that when
	 * the parent is disposed, the allocated resources will be
	 * deallocated.
	 */
	private void allocateResources(Composite parent) {
		colorGray = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY);
		colorBlack = parent.getDisplay().getSystemColor(SWT.COLOR_BLACK);
		busyCursor = parent.getDisplay().getSystemCursor(SWT.CURSOR_WAIT);
		
		xImage = Activator.getDefault().getImageDescriptor("/icons/x.png").createImage(parent.getDisplay()); //$NON-NLS-1$
		
		parent.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				xImage.dispose();
			}			
		});
	}	

	private void createDescriptionText(Composite parent) {
		FormText text = new FormText(parent, SWT.NONE);
		text.setImage("x", xImage); //$NON-NLS-1$
		text.setText(Messages.UploadPreview_2, true, false); 
		GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
		layoutData.widthHint = 500;
		text.setLayoutData(layoutData);
	}

	private void createEventsTable(Composite parent) {
		viewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.getTable().setHeaderVisible(true);
		viewer.getTable().setLinesVisible(false);
		GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
		layoutData.widthHint = 500;
		viewer.getTable().setLayoutData(layoutData);
		
		createIncludeColumn();
		createWhatColumn();		
		createKindColumn();		
		createDescriptionColumn();
		createBundleIdColumn();		
		createBundleVersionColumn();
		createTimestampColumn();
		
		timestampColumn.setSortColumn();
		
		viewer.setContentProvider(new IStructuredContentProvider() {
			public void dispose() {		
			}

			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {				
			}

			@SuppressWarnings("unchecked")
			public Object[] getElements(Object input) {
				if (input instanceof List) {
					return (Object[]) ((List<UsageDataEventWrapper>)input).toArray(new Object[((List<UsageDataEventWrapper>)input).size()]);
				}
				return new Object[0];
			}			
		});

		/*
		 * Add a FilterChangeListener to the filter; if the filter changes, we need to
		 * refresh the display. The dispose listener, added to the table will clean
		 * up the FilterChangeListener when the table is disposed.
		 */
		final FilterChangeListener filterChangeListener = new FilterChangeListener() {
			public void filterChanged() {
				for (UsageDataEventWrapper event : events) {
					event.resetCaches();
				}
				viewer.refresh();
			}
		};
		parameters.getFilter().addFilterChangeListener(filterChangeListener);
		
		viewer.getTable().addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				parameters.getFilter().removeFilterChangeListener(filterChangeListener);
			}			
		});
		
		// Initially, we have nothing.
		viewer.setInput(events);
	}
	
	private void createIncludeColumn() {
		includeColumn = new UsageDataTableViewerColumn(SWT.CENTER);
		includeColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public Image getImage(UsageDataEventWrapper event) {
				if (!event.isIncludedByFilter()) return xImage;
				return null;
			}
		});
	}
	
	private void createWhatColumn() {
		whatColumn = new UsageDataTableViewerColumn(SWT.LEFT);
		whatColumn.setText(Messages.UploadPreview_3); 
		whatColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public String getText(UsageDataEventWrapper event) {
				return event.getWhat();
			}
		});
	}

	private void createKindColumn() {
		kindColumn = new UsageDataTableViewerColumn(SWT.LEFT);
		kindColumn.setText(Messages.UploadPreview_4); 
		kindColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public String getText(UsageDataEventWrapper event) {
				return event.getKind();
			}
		});
	}

	private void createDescriptionColumn() {
		descriptionColumn = new UsageDataTableViewerColumn(SWT.LEFT);
		descriptionColumn.setText(Messages.UploadPreview_5); 
		descriptionColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public String getText(UsageDataEventWrapper event) {
				return event.getDescription();
			}
		});
	}

	private void createBundleIdColumn() {
		bundleIdColumn = new UsageDataTableViewerColumn(SWT.LEFT);
		bundleIdColumn.setText(Messages.UploadPreview_6); 
		bundleIdColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public String getText(UsageDataEventWrapper event) {
				return event.getBundleId();
			}			
		});
	}

	private void createBundleVersionColumn() {
		bundleVersionColumn = new UsageDataTableViewerColumn(SWT.LEFT);
		bundleVersionColumn.setText(Messages.UploadPreview_7); 
		bundleVersionColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public String getText(UsageDataEventWrapper event) {
				return event.getBundleVersion();
			}
		});
	}

	private void createTimestampColumn() {
		timestampColumn = new UsageDataTableViewerColumn(SWT.LEFT);
		timestampColumn.setText(Messages.UploadPreview_8); 
		timestampColumn.setLabelProvider(new UsageDataColumnProvider() {
			@Override
			public String getText(UsageDataEventWrapper event) {
				return dateFormat.format(new Date(event.getWhen()));
			}
		});
		timestampColumn.setSorter(new Comparator<UsageDataEventWrapper>() {
			public int compare(UsageDataEventWrapper event1, UsageDataEventWrapper event2) {
				if (event1.getWhen() == event2.getWhen()) return 0;
				return event1.getWhen() > event2.getWhen() ? 1 : -1;
			}	
		});
	}

	private void createButtons(Composite parent) {
		Composite buttons = new Composite(parent, SWT.NONE);
		GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
		buttons.setLayoutData(layoutData);
		buttons.setLayout(new RowLayout());
		createAddFilterButton(buttons);
		createRemoveFilterButton(buttons);

		final FilterChangeListener filterChangeListener = new FilterChangeListener() {
			public void filterChanged() {
				updateButtons();
			}			
		};
		parameters.getFilter().addFilterChangeListener(filterChangeListener);
		parent.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				parameters.getFilter().removeFilterChangeListener(filterChangeListener);
			}			
		});
		updateButtons();
	}
	
	private void createEclipseOnlyButton(Composite buttons) {
		eclipseOnlyButton = new Button(buttons, SWT.CHECK);
		eclipseOnlyButton.setText(Messages.UploadPreview_9); 
		eclipseOnlyButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				((PreferencesBasedFilter)parameters.getFilter()).setEclipseOnly(eclipseOnlyButton.getSelection());
			}
		});
	}

	private void updateButtons() {
		if (parameters.getFilter() instanceof PreferencesBasedFilter) {
			PreferencesBasedFilter filter = (PreferencesBasedFilter)parameters.getFilter();
			if (filter.isEclipseOnly()) {
				eclipseOnlyButton.setSelection(true);
				addFilterButton.setEnabled(false);
				removeFilterButton.setEnabled(false);
			} else {
				eclipseOnlyButton.setSelection(false);
				addFilterButton.setEnabled(true);
				removeFilterButton.setEnabled(filter.getFilterPatterns().length > 0);
			}
		}
	}

	private void createAddFilterButton(Composite parent) {
		if (parameters.getFilter() instanceof PreferencesBasedFilter) {
			addFilterButton = new Button(parent, SWT.PUSH);
			addFilterButton.setText(Messages.UploadPreview_10); 
			addFilterButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					new AddFilterDialog((PreferencesBasedFilter)parameters.getFilter()).prompt(viewer.getTable().getShell(), getFilterSuggestion());
				}
			});
		}
	}

	private void createRemoveFilterButton(Composite parent) {
		if (parameters.getFilter() instanceof PreferencesBasedFilter) {
			removeFilterButton = new Button(parent, SWT.PUSH);
			removeFilterButton.setText(Messages.UploadPreview_11); 
			removeFilterButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					new RemoveFilterDialog((PreferencesBasedFilter)parameters.getFilter()).prompt(viewer.getTable().getShell());
				}
			});
		}
	}
	
	// TODO Return a more interesting suggestion based on the selection.
	String getFilterSuggestion() {
		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
		if (selection != null) {
			if (selection.size() == 1) {
				return getFilterSuggestionBasedOnSingleSelection(selection);
			} 
			if (selection.size() > 1) {
				return getFilterSuggestionBasedOnMultipleSelection(selection);
			}
		}
		
		return FilterUtils.getDefaultFilterSuggestion();
	}

	String getFilterSuggestionBasedOnSingleSelection(
			IStructuredSelection selection) {
		return ((UsageDataEventWrapper)selection.getFirstElement()).getBundleId();
	}

	String getFilterSuggestionBasedOnMultipleSelection(IStructuredSelection selection) {
		String[] names = new String[selection.size()];
		int index = 0;
		for (Object event : selection.toArray()) {
			names[index++] = ((UsageDataEventWrapper)event).getBundleId();
		}
		return FilterUtils.getFilterSuggestionBasedOnBundleIds(names);
	}
	
	/**
	 * This method starts the job that populates the list of
	 * events.
	 */
	synchronized void startContentJob() {
		if (contentJob != null) return;
		contentJob = new Job("Generate Usage Data Upload Preview") { //$NON-NLS-1$
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				setTableCursor(busyCursor);
				processFiles(monitor);
				setTableCursor(null);
				if (monitor.isCanceled()) return Status.CANCEL_STATUS;
				return Status.OK_STATUS;
			}

			private void setTableCursor(final Cursor cursor) {
				if (isDisposed()) return;
				getDisplay().syncExec(new Runnable() {
					public void run() {
						if (isDisposed()) return;
						viewer.getTable().setCursor(cursor);
					}					
				});
			}			
		};
		contentJob.setPriority(Job.LONG);
		contentJob.schedule();
	}

	void processFiles(IProgressMonitor monitor) {
		File[] files = parameters.getFiles();
		monitor.beginTask("Process Files", files.length);	 //$NON-NLS-1$
		for (File file : files) {
			if (isDisposed()) break; 
			if (monitor.isCanceled()) break;
			processFile(file, monitor);
			monitor.worked(1);
		}
		monitor.done();
	}
	
	/**
	 * This method extracts the events found in a {@link File}
	 * and adds them to the list of events displayed by the
	 * receiver. Events are batched into groups to reduce
	 * the number of times the viewer will have to update.
	 * 
	 * @param file the {@link File} to process.
	 * @param monitor the monitor.
	 */
	void processFile(File file, IProgressMonitor monitor) {
		// TODO Add a progress bar to the page?
		final List<UsageDataEventWrapper> events = new ArrayList<UsageDataEventWrapper>();
		UsageDataFileReader reader = null;
		try {
			reader = new UsageDataFileReader(file);
			reader.iterate(monitor, new UsageDataFileReader.Iterator() {
				public void header(String header) {
					// Ignore the header.
				}
				
				public void event(String line, UsageDataEvent event) {
					events.add(new UsageDataEventWrapper(parameters, event));
					if (events.size() > 25) {
						addEvents(events);
						events.clear();
					}
				}	
			});
			addEvents(events);
		} catch (Exception e) {
			Activator.getDefault().log(IStatus.WARNING, e, "An error occurred while trying to read %1$s", file.getAbsolutePath()); //$NON-NLS-1$
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
			}
		}
	}

	boolean isDisposed() {
		if (viewer == null) return true;
		if (viewer.getTable() == null) return true;
		return viewer.getTable().isDisposed();
	}

	/*
	 * This method adds the list of events to the master list maintained
	 * by the instance. It also updates the table.
	 */
	void addEvents(List<UsageDataEventWrapper> newEvents) { 
		if (isDisposed()) return;
		events.addAll(newEvents);
		
		final Object[] array = (Object[]) newEvents.toArray(new Object[newEvents.size()]);
		getDisplay().syncExec(new Runnable() {
			public void run() {
				if (isDisposed()) return;
				viewer.add(array);
				resizeColumns(array);
			}
		});
	}

	private Display getDisplay() {
		return viewer.getTable().getDisplay();
	}

	/*
	 * Oddly enough, this method resizes the columns. In order to figure out how
	 * wide to make the columns, we need to use a GC (specifically, the
	 * {@link GC#textExtent(String)} method). To avoid creating too many of
	 * them, we create one in this method and pass it into the helper method
	 * {@link #resizeColumn(GC, UsageDataTableViewerColumn)} which does most of
	 * the heavy lifting.
	 * 
	 * This method must be run in the UI Thread.
	 */
	void resizeColumns(final Object[] events) {
		if (isDisposed()) return;
	
		GC gc = new GC(getDisplay());
		gc.setFont(viewer.getTable().getFont());
		resizeColumn(gc, includeColumn, events);
		resizeColumn(gc, whatColumn, events);
		resizeColumn(gc, kindColumn, events);
		resizeColumn(gc, bundleIdColumn, events);
		resizeColumn(gc, bundleVersionColumn, events);
		resizeColumn(gc, descriptionColumn, events);
		resizeColumn(gc, timestampColumn, events);
		gc.dispose();
	}

	void resizeColumn(GC gc, UsageDataTableViewerColumn column, Object[] events) {
		column.resize(gc, events);
	}

	
	
	/**
	 * The {@link UsageDataTableViewerColumn} provides a level of abstraction
	 * for building table columns specifically for the table displaying
	 * instances of {@link UsageDataEventWrapper}. Instances automatically know how to
	 * sort themselves (ascending only) with help from the label provider. This
	 * behaviour can be overridden by providing an alternative
	 * {@link Comparator}.
	 */
	class UsageDataTableViewerColumn {
		private TableViewerColumn column;
		private UsageDataColumnProvider usageDataColumnProvider;
		/**
		 * The default comparator knows how to compare objects based on the
		 * string value returned for each instance by the
		 * {@link UsageDataColumnProvider#getText(UsageDataEventWrapper)}
		 * method.
		 */
		private Comparator<UsageDataEventWrapper> comparator = new Comparator<UsageDataEventWrapper>() {	
			public int compare(UsageDataEventWrapper event1, UsageDataEventWrapper event2) {
				if (usageDataColumnProvider == null) return 0;
				String text1 = usageDataColumnProvider.getText(event1);
				String text2 = usageDataColumnProvider.getText(event2);
				
				if (text1 == null && text2 == null) return 0;
				if (text1 == null) return -1;
				if (text2 == null) return 1;
				
				return text1.compareTo(text2);
			}	
		};
		
		private ViewerComparator sorter = new ViewerComparator() {
			@Override
			public int compare(Viewer viewer, Object object1, Object object2) {
				return comparator.compare((UsageDataEventWrapper)object1, (UsageDataEventWrapper)object2);
			}
		};
		
		private SelectionListener selectionListener = new SelectionAdapter() {
			/**
			 * When the column is selected (clicked on by the
			 * the user, sort the table based on the value 
			 * presented in that column.
			 */
			@Override
			public void widgetSelected(SelectionEvent e) {
				setSortColumn();
			}		
		};
	
		public UsageDataTableViewerColumn(int style) {
			column = new TableViewerColumn(viewer, style);
			initialize();
		}

		public void setSortColumn() {
			getTable().setSortColumn(getColumn());
			getTable().setSortDirection(SWT.DOWN);
			viewer.setComparator(sorter);
		}

		private void initialize() {
			getColumn().addSelectionListener(selectionListener);
			getColumn().setWidth(25);
		}
//	
//		DeferredContentProvider getContentProvider() {
//			return (DeferredContentProvider)viewer.getContentProvider();
//		}
	
		TableColumn getColumn() {
			return column.getColumn();
		}
	
		Table getTable() {
			return viewer.getTable();
		}
	
		public void setSorter(Comparator<UsageDataEventWrapper> comparator) {
			// TODO May need to handle the case when the active comparator is changed.
			this.comparator = comparator;
		}
	
		public void resize(GC gc, Object[] objects) {
			int width = usageDataColumnProvider.getMaximumWidth(gc, objects) + 20;
			width = Math.max(getColumn().getWidth(), width);
			getColumn().setWidth(width);
		}
	
		public void setLabelProvider(UsageDataColumnProvider usageDataColumnProvider) {
			this.usageDataColumnProvider = usageDataColumnProvider;
			column.setLabelProvider(usageDataColumnProvider);
		}
	
		public void setWidth(int width) {
			getColumn().setWidth(width);
		}
	
		public void setText(String text) {
			getColumn().setText(text);
		}
	}
	
	/**
	 * The {@link UsageDataColumnProvider} is a column label provider
	 * that includes some convenience methods. 
	 */
	abstract class UsageDataColumnProvider extends ColumnLabelProvider {
		/**
		 * This convenience method is used to determine an appropriate
		 * width for the column based on the collection of event objects.
		 * The returned value is the maximum width (in pixels) of the
		 * text the receiver associates with each of the events. The
		 * events are provided as Object[] because converting them to
		 * {@link UsageDataEventWrapper}[] would be an unnecessary expense.
		 * 
		 * @param gc a {@link GC} loaded with the font used to display the events.
		 * @param events an array of {@link UsageDataEventWrapper} instances.
		 * @return the width of the widest event
		 */
		public int getMaximumWidth(GC gc, Object[] events) {
			int width = 0;
			for (Object event : events) {
				Point extent = gc.textExtent(getText(event));
				int x = extent.x;
				Image image = getImage(event);
				if (image != null) x += image.getBounds().width;
				if (x > width) width = x;
			}
			return width;
		}
			
		/**
		 * This method provides a foreground colour for the cell.
		 * The cell will be black if the filter includes the
		 * includes the provided {@link UsageDataEvent}, or gray if the filter
		 * excludes it.
		 */
		@Override
		public Color getForeground(Object element) {
			if (((UsageDataEventWrapper)element).isIncludedByFilter()) {
				return colorBlack;
			} else {
				return colorGray;
			}
		}
		
		@Override
		public String getText(Object element) {
			return getText((UsageDataEventWrapper)element);
		}
	
		@Override
		public Image getImage(Object element) {
			return getImage((UsageDataEventWrapper)element);
		}
		
		public String getText(UsageDataEventWrapper element) {
			return ""; //$NON-NLS-1$
		}
		
		public Image getImage(UsageDataEventWrapper element) {
			return null;
		}
	}
}