/*******************************************************************************
 * Copyright (c) 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.ui.internal.viewers;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
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.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.update.core.IFeature;
import org.eclipse.wst.server.ui.internal.ImageResource;
import org.eclipse.wst.server.ui.internal.Messages;
import org.eclipse.wst.server.ui.internal.Trace;
import org.eclipse.wst.server.ui.internal.extension.ExtensionUtility;
/**
 * 
 */
public class ExtensionComposite extends Composite {
	public interface FeatureSelectionListener {
		public void featureSelected(IFeature feature);
	}

	protected Table table;
	protected TableViewer tableViewer;

	protected Font font;

	protected HashMap<String, Image> images;

	protected String progress;
	protected int totalWork;
	protected double currentWork;
	protected int count;

	public FeatureSelectionListener listener;

	public ExtensionComposite(Composite parent, int style, FeatureSelectionListener listener) {
		super(parent, style);
		this.listener = listener;
		
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		layout.verticalSpacing = 5;
		layout.horizontalSpacing = 5;
		//layout.numColumns = 2;
		setLayout(layout);
		
		Font currentFont = getFont();
		FontData[] fd = currentFont.getFontData();
		int size2 = fd.length;
		for (int i = 0; i < size2; i++) {
			fd[i].setHeight(fd[i].getHeight() + 2);
			fd[i].setStyle(SWT.BOLD);
		}
		
		font = new Font(getDisplay(), fd);
		
		GridData data = new GridData(GridData.FILL_BOTH);
		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		data.heightHint = 350;
		setLayoutData(data);
		
		table = new Table(this, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
		data = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
		//data.horizontalSpan = 2;
		//data.heightHint = 250;
		data.widthHint = 350;
		table.setLayoutData(data);
		//table.setLinesVisible(true);
		table.setHeaderVisible(false);
		tableViewer = new TableViewer(table);
		table.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				disposeResources();
			}
		});
		
		TableLayout tableLayout = new TableLayout();
		table.setLayout(tableLayout);
		
		/*tableLayout.addColumnData(new ColumnPixelData(90, false));
		//tableLayout.addColumnData(new ColumnWeightData(8, 80, true));
		TableColumn col2 = new TableColumn(table, SWT.NONE);
		col2.setText("null");
		*/
		tableLayout.addColumnData(new ColumnWeightData(10, 250, false));
		final TableColumn col = new TableColumn(table, SWT.NONE);
		col.setText("null");
		/*col.setWidth(300);
		col.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				col.pack();
			}
		});*/
		
		//tableLayout.addColumnData(new ColumnWeightData(30, 250, false));
		//TableColumn col2 = new TableColumn(table, SWT.NONE);
		//col2.setText("null2");
		
		final int TEXT_MARGIN = 3;
		table.addListener(SWT.MeasureItem, new Listener() {
			public void handleEvent(Event event) {
				//System.out.println(event.width);
				/*TableItem item = (TableItem) event.item;
				Object obj = item.getData();
				//System.out.println("measure " + obj);
				if (obj instanceof CoreException) {
					event.gc.setFont(font);
					Point size = event.gc.textExtent("A");
					event.gc.setFont(null);
					//event.height = Math.max(event.height, TEXT_MARGIN * 2 + size.y);
					event.height = TEXT_MARGIN * 2 + size.y;
					System.out.println(event.height);
					return;
				}*/
				event.gc.setFont(font);
				Point size = event.gc.textExtent("A");
				int h = TEXT_MARGIN * 3 + size.y;
				size = event.gc.textExtent("A");
				event.gc.setFont(null);
				h += size.y;
				h = Math.max(h, 40 + TEXT_MARGIN * 2);
				//event.width = 400;
				event.height = Math.max(event.height, h);
				//System.out.println(event.height);
				//event.width = 300;
			}
		});
		table.addListener(SWT.EraseItem, new Listener() {
			public void handleEvent(Event event) {
				//if (event.index == 0)
				//	return;
				event.detail &= ~SWT.FOREGROUND;
				//event.detail &= ~SWT.BACKGROUND;
			}
		});
		table.addListener(SWT.PaintItem, new Listener() {
			public void handleEvent(Event event) {
				//if (event.index == 0)
				//	return;
				TableItem item = (TableItem) event.item;
				Object obj = item.getData();
				
				int width = table.getColumn(0).getWidth();
				GC gc = event.gc;
				
				if (obj instanceof String) {
					String s = (String) obj;
					if (progress != null)
						s = progress;
					int h = event.y + event.height / 2;
					Point size = event.gc.textExtent(s);
					gc.drawText(s, event.x + TEXT_MARGIN, h - size.y/2, true);
					
					int hh = event.y + event.height - 5 - TEXT_MARGIN - 1;
					
					gc.setLineWidth(2);
					Color color = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
					gc.setBackground(color);
					
					int width2 = 0;
					int step = 9;
					if (totalWork > 0)
						width2 = (int) ((width - step * 2 - 15 - TEXT_MARGIN * 2) * currentWork / totalWork);
					
					for (int i = 0; i < width2; i+= step) {
						gc.fillRectangle(event.x + TEXT_MARGIN + i, hh, step - 2, 5);
					}
					
					return;
				} else if (obj instanceof List) {
					List<String> list = (List<String>) obj;
					
					int size = list.size();
					String[] hosts = new String[size];
					list.toArray(hosts);
					
					StringBuffer sb = new StringBuffer();
					for (int i = 0; i < size; i++) {
						if (i > 0)
							sb.append(", ");
						sb.append(hosts[i]);
					}
					String s = NLS.bind(Messages.wizNewInstallableServerSiteError, sb.toString());
					gc.drawText(s, event.x + TEXT_MARGIN, event.y + TEXT_MARGIN, true);
					return;
				}
				IFeature ei = (IFeature) obj;
				if (ei == null)
					return;
				
				
				//if ((event.detail & SWT.SELECTED) == 0) {
				//	//event.gc.setForeground();
				//	//event.gc.fillRectangle(0, 0, width, 5);
				//	event.gc.setBackground(getBackground());
				//	event.gc.setForeground(getForeground());
				//	event.gc.fillRectangle(event.x, event.y, width, event.height);
				//}
				//System.out.println(width + " " + event.width + " " + event.x);
				
				String name = ei.getLabel();
				String provider = "" + ei.getProvider();
				//String provider = "" + ei.getImage();
				//String provider = "" + ExtensionUtility.getDescription(ei);
				String ver = ei.getVersionedIdentifier().toString();
				int ind = ver.indexOf("_");
				if (ind >= 0)
					ver = ver.substring(ind+1);
				String version = "v" + ver;
				
				Image image = getImage(ei.getImage());
				if (image == null)
					image = ImageResource.getImage(ImageResource.IMG_WIZBAN_NEW_SERVER);
				int iw = image.getBounds().width;
				int ih = image.getBounds().height;
				gc.drawImage(image, 0, 0, iw, ih, event.x + TEXT_MARGIN, event.y + TEXT_MARGIN, 40, 40);
				iw = 40 + TEXT_MARGIN * 2;
				
				int yOffset = TEXT_MARGIN;
				gc.setFont(font);
				gc.drawText(name, event.x + iw, event.y + yOffset, true);
				Point size = event.gc.textExtent(name);
				gc.setFont(null);
				
				yOffset += size.y + TEXT_MARGIN;
				gc.drawText(provider, event.x + iw, event.y + yOffset, true);
				
				size = event.gc.textExtent(version);
				gc.drawText(version, event.x + width - TEXT_MARGIN * 3 - size.x, event.y + yOffset, true);
			}
		});
		
		tableViewer.setSorter(new ViewerSorter() {
			public int compare(Viewer viewer, Object e1, Object e2) {
				if ((e1 instanceof IFeature) && !(e2 instanceof IFeature))
					return -1;
				if (!(e1 instanceof IFeature) && (e2 instanceof IFeature))
					return 1;
				try {
					IFeature f1 = (IFeature) e1;
					IFeature f2 = (IFeature) e2;
					return (f1.getLabel().compareToIgnoreCase(f2.getLabel()));
				} catch (Exception e) {
					return 0;
				}
			}
		});
		
		/*Composite buttonComp = new Composite(this, SWT.NONE);
		buttonComp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING));
		layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		buttonComp.setLayout(layout);
		
		Button install = SWTUtil.createButton(buttonComp, "Find Updates");
		install.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				//
			}
		});*/
		
		final Label description = new Label(this, SWT.WRAP);
		description.setText("Multi\nLine\nMessage");
		Dialog.applyDialogFont(this);
		Point p = description.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		description.setText("");
		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
		data.horizontalSpan = 2;
		if (p.y > 10)
			data.heightHint = p.y;
		else
			data.heightHint = 42;
		description.setLayoutData(data);
		
		/*final Label download = new Label(this, SWT.NONE);
		data = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
		data.horizontalSpan = 2;
		download.setLayoutData(data);
		download.setText("Download size: ");*/
		
		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				StructuredSelection sel = (StructuredSelection) tableViewer.getSelection();
				Object obj = sel.getFirstElement();
				IFeature feature = null;
				if (obj instanceof IFeature)
					feature = (IFeature) obj;
				
				handleSelection(feature);
				if (feature != null)
					description.setText(ExtensionUtility.getDescription(feature));
				else
					description.setText("");
				/*long size = feature.getDownloadSize();
				String s = "<unknown>";
				if (size > 0)
					s = size + " Kb";
				download.setText("Download size: " + s);*/
			}
		});
		
		deferInitialization();
	}

	protected Image getImage(URL url) {
		if (url == null)
			return null;
		
		try {
			Image image = images.get(url.toString());
			if (image != null)
				return image;
		} catch (Exception e) {
			// ignore
		}
		try {
			ImageDescriptor id = ImageDescriptor.createFromURL(url);
			Image image = id.createImage();
			if (images == null)
				images = new HashMap<String, Image>();
			images.put(url.toString(), image);
			return image;
		} catch (Exception e) {
			Trace.trace(Trace.INFO, "Could not create image", e);
		}
		return null;
	}

	protected void disposeResources() {
		try {
			font.dispose();
			
			if (images != null) {
				Iterator iterator = images.values().iterator();
				while (iterator.hasNext()) {
					Image image = (Image) iterator.next();
					image.dispose();
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Could not dispose - possible resource leak", e);
		}
	}

	protected void handleSelection(IFeature feature) {
		listener.featureSelected(feature);
	}

	protected void deferInitialization() {
		final List<Object> list = Collections.synchronizedList(new ArrayList<Object>());
		list.add(Messages.viewInitializing);
		
		tableViewer.setContentProvider(new ExtensionContentProvider(list));
		tableViewer.setLabelProvider(new ExtensionTableLabelProvider());
		tableViewer.setInput(AbstractTreeContentProvider.ROOT);
		
		final Thread t = new Thread("Deferred Initialization") {
			public void run() {
				deferredInitialize(list, new IProgressMonitor() {
					public void beginTask(String name, int totalWork2) {
						totalWork = totalWork2;
						progress = name;
					}

					public void setTaskName(String name) {
						progress = name;
					}

					public void subTask(String name) {
						progress = name;
					}

					public void done() {
						// 
					}

					public void internalWorked(double work) {
						currentWork += work;
					}

					public boolean isCanceled() {
						return false;
					}

					public void setCanceled(boolean value) {
						// 
					}

					public void worked(int work) {
						currentWork += work;
					}
				});
			}
		};
		t.setDaemon(true);
		t.start();
		
		final Display display = getDisplay();
		final int SLEEP = 100;
		final Runnable[] animator = new Runnable[1];
		animator[0] = new Runnable() {
			public void run() {
				if (t.isAlive()) {
					count++;
					if (!table.isDisposed())
						tableViewer.refresh(AbstractTreeContentProvider.ROOT);
					display.timerExec(SLEEP, animator[0]);
				}
			}
		};
		display.timerExec(SLEEP, animator[0]);
	}

	public void deferredInitialize(final List<Object> list, IProgressMonitor monitor) {
		final List<String> failedSites = new ArrayList<String>();
		ExtensionUtility.FeatureListener listener2 = new ExtensionUtility.FeatureListener() {
			public void featureFound(IFeature feature) {
				list.add(feature);
				if (progress != null)
					list.set(0, progress);
			}

			public void featureRemoved(IFeature feature) {
				list.remove(feature);
			}

			public void siteFailure(String host) {
				synchronized (failedSites) {
					if (!list.contains(failedSites))
						list.add(failedSites);
					failedSites.add(host);
				}
			}
		};
		
		String id = "org.eclipse.wst.server.core.serverAdapter";
		try {
			ExtensionUtility.getAllFeatures(id, listener2, monitor);
		} catch (CoreException ce) {
			Trace.trace(Trace.WARNING, "Error downloading server adapter info", ce);
		}
		
		list.remove(0);
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				if (!table.isDisposed())
					tableViewer.refresh(AbstractTreeContentProvider.ROOT);
			}
		});
	}

	protected Object getSelection(ISelection sel2) {
		IStructuredSelection sel = (IStructuredSelection) sel2;
		return sel.getFirstElement();
	}
}