/*******************************************************************************
 * Copyright (c) 2006, 2017 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
 *     Cornel Izbasa <cizbasa@info.uvt.ro> - Removed unwanted items in the Customize functionality on the Intro - https://bugs.eclipse.org/420843
 *******************************************************************************/
package org.eclipse.ui.internal.intro.universal;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.intro.impl.FontSelection;
import org.eclipse.ui.internal.intro.impl.IntroPlugin;
import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
import org.eclipse.ui.internal.intro.universal.util.BundleUtil;
import org.eclipse.ui.internal.intro.universal.util.ImageUtil;
import org.eclipse.ui.internal.intro.universal.util.Log;
import org.eclipse.ui.intro.IIntroManager;
import org.eclipse.ui.intro.IIntroPart;
import org.eclipse.ui.intro.config.CustomizableIntroPart;
import org.eclipse.ui.intro.config.IIntroURL;
import org.eclipse.ui.intro.config.IntroURLFactory;
import org.osgi.framework.Bundle;
import org.osgi.service.prefs.BackingStoreException;


public class CustomizationContentsArea {

	private static final String INTRO_ROOT_PAGES = "INTRO_ROOT_PAGES"; //$NON-NLS-1$
	private static final String INTRO_DATA = "INTRO_DATA"; //$NON-NLS-1$
	private static final String INTRO_THEME = "INTRO_THEME"; //$NON-NLS-1$
	private static final String NO_ROOT_PAGES = "no_root_pages"; //$NON-NLS-1$
	private TabFolder tabFolder;
	private String firstPageId;
	private Composite pageContainer;
	private TableViewer themes;
	private TableViewer available;
	private TableViewer topLeft;
	private TableViewer topRight;
	private TableViewer bottomLeft;
	private TableViewer bottomRight;
	private CheckboxTableViewer rootPages;
	private ArrayList<String> introRootPages = new ArrayList<>();
	private ArrayList<IntroTheme> themeList = new ArrayList<>();
	private IntroTheme introTheme;
	private String introThemeId;
	private IntroData introData;
	private Canvas themePreview;
	private TableContentProvider contentProvider;
	private TableLabelProvider labelProvider;
	private Button applyToAll;
	private Button useRelativeFonts;
	private Image extensionImage;
	private Image themeImage;
	private Image ihighImage;
	private Image ilowImage;
	private Image inewImage;
	private Image icalloutImage;
	private Shell shell;
	private static final Transfer[] TRANSFER_TYPES = new Transfer[] { ExtensionDataTransfer.getInstance() };


	private static final RootPage ROOT_PAGE_TABLE[] = new RootPage[] {
			new RootPage(IUniversalIntroConstants.ID_OVERVIEW,
					Messages.WelcomeCustomizationPreferencePage_overview,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_overview),
			new RootPage(IUniversalIntroConstants.ID_FIRSTSTEPS,
					Messages.WelcomeCustomizationPreferencePage_firststeps,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_firststeps),
			new RootPage(IUniversalIntroConstants.ID_TUTORIALS,
					Messages.WelcomeCustomizationPreferencePage_tutorials,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_tutorials),
			new RootPage(IUniversalIntroConstants.ID_SAMPLES,
					Messages.WelcomeCustomizationPreferencePage_samples,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_samples),
			new RootPage(IUniversalIntroConstants.ID_WHATSNEW,
					Messages.WelcomeCustomizationPreferencePage_whatsnew,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_whatsnew),
			new RootPage(IUniversalIntroConstants.ID_WEBRESOURCES,
					Messages.WelcomeCustomizationPreferencePage_webresources,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_webresources),
			new RootPage(IUniversalIntroConstants.ID_MIGRATE,
					Messages.WelcomeCustomizationPreferencePage_migrate,
					Messages.WelcomeCustomizationPreferencePage_NoMnemonic_migrate) };

	static class RootPage {

		public String id;
		public String name;
		public String nameNoMnemonic;

		public RootPage(String id, String name, String nameNoMnemonic) {
			this.id = id;
			this.name = name;
			this.nameNoMnemonic = nameNoMnemonic;
		}

		public String getId() {
			return id;
		}

		public String getName() {
			return name;
		}

		public String getNameNoMnemonic() {
			return nameNoMnemonic;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == this)
				return true;
			if (obj == null)
				return false;
			if (obj instanceof RootPage) {
				RootPage page = (RootPage) obj;
				return page.id.equals(id) && page.name.equals(name);
			}
			return false;
		}

		@Override
		public String toString() {
			return name;
		}
	}

	class TableContentProvider implements IStructuredContentProvider {

		@Override
		public Object[] getElements(Object inputElement) {
			if (inputElement == ROOT_PAGE_TABLE)
				return ROOT_PAGE_TABLE;
			if (inputElement instanceof GroupData) {
				return ((GroupData) inputElement).getChildren();
			}
			if (inputElement == themes) {
				return themeList.toArray();
			}
			return new Object[0];
		}

		@Override
		public void dispose() {
		}

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

	class TableDragSourceListener implements DragSourceListener {

		TableViewer viewer;
		BaseData[] sel;

		public TableDragSourceListener(TableViewer viewer) {
			this.viewer = viewer;
		}

		@Override
		public void dragStart(DragSourceEvent event) {
			IStructuredSelection ssel = (IStructuredSelection) viewer.getSelection();
			if (ssel.size() > 0) {
				event.doit = true;
			} else {
				event.doit = false;
			}
		};

		@Override
		public void dragSetData(DragSourceEvent event) {
			IStructuredSelection ssel = (IStructuredSelection) viewer.getSelection();
			BaseData[] array = new BaseData[ssel.size()];
			int i = 0;
			for (Iterator<BaseData> iter = ssel.iterator(); iter.hasNext();) {
				array[i++] = iter.next();
			}
			event.data = array;
			sel = array;
		}

		@Override
		public void dragFinished(DragSourceEvent event) {
			if (event.detail == DND.DROP_MOVE) {
				GroupData gd = (GroupData) viewer.getInput();
				for (int i = 0; i < sel.length; i++) {
					BaseData ed = sel[i];
					gd.remove(ed);
				}
				viewer.refresh();
				updateColumnSizes(viewer);
			}
			sel = null;
		}
	}

	CustomizationContentsArea() {
	}

	class TableDropTargetListener extends ViewerDropAdapter {

		public TableDropTargetListener(TableViewer viewer) {
			super(viewer);
		}

		@Override
		public boolean performDrop(Object data) {
			BaseData target = (BaseData) getCurrentTarget();
			int loc = getCurrentLocation();
			GroupData gd = (GroupData) getViewer().getInput();
			if (gd == null)
				gd = createTargetGd(getViewer());
			BaseData[] sel = (BaseData[]) data;

			int index = target != null ? gd.getIndexOf(target) : -1;
			int startingIndex = getStartIndex(gd, sel);
			if (target != null) {
				if (loc == LOCATION_AFTER
						|| (loc == LOCATION_ON && startingIndex != -1 && startingIndex < index))
					index++;
				else if (index > 0 && loc == LOCATION_BEFORE)
					index--;
			}

			for (int i = 0; i < sel.length; i++) {
				BaseData ed = sel[i];
				if (index == -1)
					gd.add(ed);
				else
					gd.add(index++, ed);
			}
			if (getViewer().getInput() != null)
				getViewer().refresh();
			else
				getViewer().setInput(gd);
			updateColumnSizes((TableViewer) getViewer());
			return true;
		}

		private int getStartIndex(GroupData gd, BaseData[] sel) {
			for (int i = 0; i < sel.length; i++) {
				BaseData ed = sel[i];
				int index = gd.getIndexOf(ed.getId());
				if (index != -1)
					return index;
			}
			return -1;
		}

		@Override
		public boolean validateDrop(Object target, int operation, TransferData transferType) {
			return ExtensionDataTransfer.getInstance().isSupportedType(transferType);
		}
	}

	class TableLabelProvider extends LabelProvider implements ITableLabelProvider {

		@Override
		public String getText(Object obj) {
			if (obj instanceof RootPage) {
				return ((RootPage) obj).getNameNoMnemonic();
			}
			if (obj instanceof ExtensionData) {
				ExtensionData ed = (ExtensionData) obj;
				String name = ed.getName();
				if (name != null && name.length() > 0)
					return name;
				return ed.getId();
			}
			if (obj instanceof SeparatorData) {
				return Messages.WelcomeCustomizationPreferencePage_horizontalSeparator;
			}
			if (obj instanceof IntroTheme) {
				IntroTheme bg = (IntroTheme) obj;
				return bg.getName();
			}
			return super.getText(obj);
		}

		@Override
		public Image getImage(Object obj) {
			if (obj instanceof ExtensionData) {
				ExtensionData ed = (ExtensionData) obj;
				switch (ed.getImportance()) {
				case ExtensionData.HIGH:
					return ihighImage;
				case ExtensionData.LOW:
					return ilowImage;
				case ExtensionData.NEW:
					return inewImage;
				case ExtensionData.CALLOUT:
					return icalloutImage;
				}
				return extensionImage;
			}
			if (obj instanceof IntroTheme)
				return themeImage;
			return null;
		}

		@Override
		public Image getColumnImage(Object element, int columnIndex) {
			if (columnIndex == 0)
				return getImage(element);
			return null;
		}

		@Override
		public String getColumnText(Object element, int columnIndex) {
			if (columnIndex == 1 || element instanceof IntroTheme || element instanceof RootPage)
				return getText(element);
			return null;
		}
	}

	class IntroTheme {
		IConfigurationElement element;
		Image previewImage;

		public String getName() {
			return element.getAttribute("name"); //$NON-NLS-1$
		}

		public String getId() {
			return element.getAttribute("id"); //$NON-NLS-1$
		}

		public boolean isScalable() {
			return "true".equals(element.getAttribute(FontSelection.ATT_SCALABLE)); //$NON-NLS-1$
		}

		public IntroTheme(IConfigurationElement element) {
			this.element = element;
		}

		public Image getPreviewImage() {
			if (previewImage==null) {
				String path = element.getAttribute("previewImage"); //$NON-NLS-1$
				if (path!=null) {
				    String bid = element.getDeclaringExtension().getNamespaceIdentifier();
				    Bundle bundle = Platform.getBundle(bid);
				    if (bundle!=null) {
				    	ImageDescriptor desc = ImageUtil.createImageDescriptor(bundle, path);
				    	previewImage = desc.createImage();
				    }
				}
			}
			return previewImage;
		}

		public void dispose() {
			if (previewImage!=null) {
				previewImage.dispose();
				previewImage=null;
			}
		}
	}

	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		GridData data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		container.setLayoutData(data);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		container.setLayout(layout);
		tabFolder = new TabFolder(container, SWT.TOP);
		tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
		tabFolder.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				TabItem[] selection = tabFolder.getSelection();
				onTabChange(selection[0]);
			}
		});
		useRelativeFonts = new Button(container, SWT.CHECK);
		useRelativeFonts.setText(Messages.WelcomeCustomizationPreferencePage_useRelative);
		applyToAll = new Button(container, SWT.CHECK);
		applyToAll.setText(Messages.WelcomeCustomizationPreferencePage_applyToAll);
		contentProvider = new TableContentProvider();
		labelProvider = new TableLabelProvider();
		if (isCustomizationMode()) {
			Button serialize = new Button(container, SWT.PUSH);
			serialize.setText(Messages.WelcomeCustomizationPreferencePage_serialize);
			serialize.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					doSerializeState();
				}
			});
		}
		extensionImage = ImageUtil.createImage("full/obj16/extension_obj.gif"); //$NON-NLS-1$
		ihighImage = ImageUtil.createImage("full/obj16/ihigh_obj.gif"); //$NON-NLS-1$
		ilowImage = ImageUtil.createImage("full/obj16/ilow_obj.gif"); //$NON-NLS-1$
		inewImage = ImageUtil.createImage("full/obj16/inew_obj.gif"); //$NON-NLS-1$
		icalloutImage = ImageUtil.createImage("full/obj16/icallout_obj.gif"); //$NON-NLS-1$
		themeImage = ImageUtil.createImage("full/obj16/image_obj.gif"); //$NON-NLS-1$
		addPages();
		org.eclipse.jface.dialogs.Dialog.applyDialogFont(container);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.ui.intro.universal.universalWelcomePreference"); //$NON-NLS-1$
		return container;
	}

	private void doSerializeState() {
		FileDialog fd = new FileDialog(shell, SWT.SAVE);
		fd.setText(Messages.WelcomeCustomizationPreferencePage_serializeTitle);
		String fileName = fd.open();
		if (fileName != null) {
			try {
				FileWriter writer = new FileWriter(fileName);
				PrintWriter pwriter = new PrintWriter(writer);
				introData.write(pwriter);
				pwriter.close();
			} catch (IOException e) {
				// show an error dialog in addition
				Log.error("Error while saving the intro data file", e); //$NON-NLS-1$
			}
		}
	}

	private boolean isCustomizationMode() {
		/*
		 * String[] args = Platform.getApplicationArgs(); for (int i = 0; i < args.length; i++) { if
		 * (args[i].equalsIgnoreCase("-welcomeCustomization")) //$NON-NLS-1$ return true; } return
		 * false;
		 */
		return true;
	}

	public void init(IWorkbench workbench) {
	}

	private void addPages() {
		loadData(false);
		addHomePage();
		createPageContainer();
		addRootPages();
		updateWidgetsFromData();
		selectFirstPage();
	}

	private void addRootPages() {
		addPage(IUniversalIntroConstants.ID_OVERVIEW);
		addPage(IUniversalIntroConstants.ID_FIRSTSTEPS);
		addPage(IUniversalIntroConstants.ID_TUTORIALS);
		addPage(IUniversalIntroConstants.ID_SAMPLES);
		addPage(IUniversalIntroConstants.ID_WHATSNEW);
		addPage(IUniversalIntroConstants.ID_WEBRESOURCES);
		addPage(IUniversalIntroConstants.ID_MIGRATE);
	}

	private void createPageContainer() {
		pageContainer = new Composite(tabFolder, SWT.NULL);
		GridLayout layout = new GridLayout();
		//layout.horizontalSpacing = 10;
		pageContainer.setLayout(layout);
		layout.numColumns = 4;
		//layout.makeColumnsEqualWidth = true;
		Label label;
		label = new Label(pageContainer, SWT.WRAP);
		label.setText(Messages.WelcomeCustomizationPreferencePage_pageDesc);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 4;
		label.setLayoutData(gd);
		label = new Label(pageContainer, SWT.SEPARATOR | SWT.HORIZONTAL);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 4;
		label.setLayoutData(gd);
		label = new Label(pageContainer, SWT.NULL);
		label.setText(Messages.WelcomeCustomizationPreferencePage_available);
		gd = new GridData();
		label.setLayoutData(gd);
		label = new Label(pageContainer, SWT.SEPARATOR | SWT.VERTICAL);
		gd = new GridData(GridData.VERTICAL_ALIGN_FILL);
		gd.verticalSpan = 3;
		gd.widthHint = 10;
		label.setLayoutData(gd);

		label = new Label(pageContainer, SWT.NULL);
		label.setText(Messages.WelcomeCustomizationPreferencePage_left);
		label = new Label(pageContainer, SWT.NULL);
		label.setText(Messages.WelcomeCustomizationPreferencePage_right);
		available = createTableViewer(pageContainer, "hidden"); //$NON-NLS-1$
		available.setComparator(new ViewerComparator());
		gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		gd.verticalSpan = 2;
		gd.widthHint = 100;
		//gd.horizontalSpan = 2;
		available.getControl().setLayoutData(gd);

		topLeft = createTableViewer(pageContainer, "top-left"); //$NON-NLS-1$
		gd = new GridData(GridData.FILL_BOTH);
		gd.widthHint = 100;
		topLeft.getControl().setLayoutData(gd);

		topRight = createTableViewer(pageContainer, "top-right"); //$NON-NLS-1$
		gd = new GridData(GridData.FILL_BOTH);
		gd.widthHint = 100;
		topRight.getControl().setLayoutData(gd);

		//label = new Label(pageContainer, SWT.NULL);
		//label.setText(Messages.WelcomeCustomizationPreferencePage_bottom);
		bottomLeft = createTableViewer(pageContainer, "bottom-left"); //$NON-NLS-1$
		gd = new GridData(GridData.FILL_BOTH);
		gd.widthHint = 100;
		bottomLeft.getControl().setLayoutData(gd);

		bottomRight = createTableViewer(pageContainer, "bottom-right"); //$NON-NLS-1$
		gd = new GridData(GridData.FILL_BOTH);
		gd.widthHint = 100;
		bottomRight.getControl().setLayoutData(gd);
	}

	private void updatePageContainer(String pageId, PageData pd) {
		if (pageId == null)
			return;
		refreshQuadrant(topLeft, pd, IUniversalIntroConstants.DIV_LAYOUT_TOP_LEFT);
		refreshQuadrant(topRight, pd, IUniversalIntroConstants.DIV_LAYOUT_TOP_RIGHT);
		refreshQuadrant(bottomLeft, pd, IUniversalIntroConstants.DIV_LAYOUT_BOTTOM_LEFT);
		refreshQuadrant(bottomRight, pd, IUniversalIntroConstants.DIV_LAYOUT_BOTTOM_RIGHT);
		refreshQuadrant(available, pd, IUniversalIntroConstants.HIDDEN);
	}

	private void refreshQuadrant(TableViewer viewer, PageData pd, String quadrant) {
		GroupData gd = pd!=null?pd.findGroup(quadrant):null;
		viewer.setInput(gd);
		if (gd!=null)
			updateColumnSizes(viewer);
	}

	private void onTabChange(TabItem item) {
		String id = (String) item.getData();
		if (item.getControl() == pageContainer)
			updatePageContainer(id, (PageData) item.getData("pageData")); //$NON-NLS-1$
	}

	private void loadData(boolean fromDefault) {
		IProduct product = Platform.getProduct();
		if (product == null)
			return;
		String pid = product.getId();
		introRootPages.clear();
		// 1. Root pages
		// try product-qualified value first
		String rootPages = getIntroPreference(INTRO_ROOT_PAGES, fromDefault, pid, UniversalIntroPlugin.PLUGIN_ID);
		if (rootPages.length() > 0) {
			StringTokenizer stok = new StringTokenizer(rootPages, ","); //$NON-NLS-1$
			while (stok.hasMoreTokens()) {
				String tok = stok.nextToken().trim();
				if (!NO_ROOT_PAGES.equals(tok)) {
				    introRootPages.add(tok);
				}
			}
		}
		// 2. Font Style
		String fontStyle = FontSelection.getFontStyle();
		useRelativeFonts.setSelection(FontSelection.FONT_RELATIVE.equals(fontStyle));
		// 3. Active theme
		String value = getIntroPreference(INTRO_THEME, fromDefault, pid, IntroPlugin.PLUGIN_ID);
		if (value.length() > 0)
			introThemeId = value;
		// 4. Intro data
		value = getIntroPreference(INTRO_DATA, fromDefault, pid, UniversalIntroPlugin.PLUGIN_ID);
		if (value.length() == 0)
			value = null;
		if (value != null && value.startsWith("product:")) //$NON-NLS-1$
			value = value.substring(8);
		value = BundleUtil.getResolvedResourceLocation(value, product.getDefiningBundle());
		introData = new IntroData(pid, value, true);
		introData.addImplicitContent();
	}

	private String getIntroPreference(String key, boolean fromDefault,
			String pid, String pluginId) {
		IEclipsePreferences prefs;
		String pidKey = pid + "_" + key; //$NON-NLS-1$
		String value;
		if (!fromDefault) {
		     prefs = InstanceScope.INSTANCE.getNode(pluginId);
		     value = getPreference(key, prefs, pidKey, null);
		     if (value != null) {
		    	 return value;
		     }
		}
		prefs = DefaultScope.INSTANCE.getNode(pluginId);
		return getPreference(key, prefs, pidKey, ""); //$NON-NLS-1$
	}

	private String getPreference(String key, IEclipsePreferences prefs,
			String pidKey, String defaultValue) {
		String value = prefs.get(pidKey, null);
		if (value == null) {
			value = prefs.get(key, defaultValue);
		}
		return value;
	}

	public void dispose() {
		Iterator<IntroTheme> iter = themeList.iterator();
		while (iter.hasNext()) {
			iter.next().dispose();
		}
		extensionImage.dispose();
		ihighImage.dispose();
		ilowImage.dispose();
		inewImage.dispose();
		icalloutImage.dispose();
		themeImage.dispose();
	}

	private void updateIntroThemeFromData() {
		if (introThemeId != null) {
			for (int i = 0; i < themeList.size(); i++) {
				IntroTheme theme = themeList.get(i);
				if (theme.getId().equals(introThemeId)) {
					introTheme = theme;
					break;
				}
			}
		}
		updateThemePreview();
	}

	private void updateWidgetsFromData() {
		// sync up intro background part
		updateIntroThemeFromData();
		enableFontsButton();
		// sync up the root page checklist
		rootPages.setInput(ROOT_PAGE_TABLE);
		ArrayList<RootPage> selected = new ArrayList<>();
		for (int i = 0; i < ROOT_PAGE_TABLE.length; i++) {
			String id = ROOT_PAGE_TABLE[i].id;
			if (introRootPages.contains(id))
				selected.add(ROOT_PAGE_TABLE[i]);
		}
		rootPages.setCheckedElements(selected.toArray());
	}

	private void enableFontsButton() {
		if (introTheme != null) {
			useRelativeFonts.setEnabled(introTheme.isScalable());
		}
	}

	private void updateThemePreview() {
		themes.setInput(themes);
		if (introTheme != null)
			themes.setSelection(new StructuredSelection(introTheme), true);
		themePreview.redraw();
	}

	public boolean performOk() {
		saveData();
		BusyIndicator.showWhile(shell.getDisplay(), () -> restartIntro());
		return true;
	}

	/**
	 * Remember the current page, close intro, reopen it and show the saved page.
	 *
	 */
	private void restartIntro() {
		IIntroManager manager = PlatformUI.getWorkbench().getIntroManager();
		IIntroPart part = manager.getIntro();
		if (part != null && part instanceof CustomizableIntroPart) {
			IntroModelRoot modelRoot = IntroPlugin.getDefault().getIntroModelRoot();
			String currentPageId = modelRoot.getCurrentPageId();
			IWorkbenchWindow window = part.getIntroSite().getWorkbenchWindow();
			boolean standby = manager.isIntroStandby(part);
			PlatformUI.getWorkbench().getIntroManager().closeIntro(part);
			IntroPlugin.getDefault().resetVolatileImageRegistry();
			UniversalIntroPlugin.getDefault().resetVolatileImageRegistry();
			part = PlatformUI.getWorkbench().getIntroManager().showIntro(window, standby);
			if (part != null  && !standby) {
				StringBuffer url = new StringBuffer();
				url.append("http://org.eclipse.ui.intro/showPage?id="); //$NON-NLS-1$
				url.append(currentPageId);
				IIntroURL introURL = IntroURLFactory.createIntroURL(url.toString());
				if (introURL != null)
					introURL.execute();
			}
		}
	}

	protected void performDefaults() {
		loadData(true);
		// Dispose all the root page tabs
		TabItem[] items = tabFolder.getItems();
		for (int i = 0; i < items.length; i++) {
			if (items[i].getData("pageData") != null) //$NON-NLS-1$
				items[i].dispose();
		}
		// Add them back in based on the checked state
		addRootPages();
		updateWidgetsFromData();
		// Get the items again
		items = tabFolder.getItems();
		// Select root
		onTabChange(items[0]);
	}

	private void saveData() {
		IEclipsePreferences iprefs = InstanceScope.INSTANCE.getNode(IntroPlugin.PLUGIN_ID);
		IEclipsePreferences uprefs = InstanceScope.INSTANCE.getNode(UniversalIntroPlugin.PLUGIN_ID);
		boolean toAll = applyToAll.getSelection();
		IProduct product = Platform.getProduct();
		if (product == null)
			return;
		String pid = product.getId();
		StringBuffer sbuf = new StringBuffer();
		if (introRootPages.size() == 0) {
			// An empty string means no preference so special value needed
			// to indicate no root pages.
			sbuf.append(NO_ROOT_PAGES);
		}
		for (int i = 0; i < introRootPages.size(); i++) {
			if (i > 0)
				sbuf.append(","); //$NON-NLS-1$
			sbuf.append(introRootPages.get(i));
		}
		String key = pid + "_" + INTRO_ROOT_PAGES; //$NON-NLS-1$
		uprefs.put(key, sbuf.toString());
		if (toAll) {
			key = INTRO_ROOT_PAGES;
			uprefs.put(key, sbuf.toString());
		}
		// Store font style
		key = pid + "_" + FontSelection.VAR_FONT_STYLE; //$NON-NLS-1$
		String fontStyle = useRelativeFonts.getSelection() ? FontSelection.FONT_RELATIVE :
			FontSelection.FONT_ABSOLUTE;
		if (fontStyle.equals(FontSelection.FONT_ABSOLUTE)) {
			// reset font scaling for next time relative is selected
			FontSelection.resetScalePercentage();
		}
		iprefs.put(key, fontStyle);
		if (toAll) {
			key = FontSelection.VAR_FONT_STYLE;
			iprefs.put(key, fontStyle);
		}
		// store page layouts
		StringWriter writer = new StringWriter();
		PrintWriter pwriter = new PrintWriter(writer);
		introData.write(pwriter);
		pwriter.close();
		String value = writer.toString();
		key = pid + "_" + INTRO_DATA; //$NON-NLS-1$
		uprefs.put(key, value);
		if (toAll) {
			key = INTRO_DATA;
			uprefs.put(key, value);
		}
		if (introTheme != null) {
			key = pid + "_" + INTRO_THEME; //$NON-NLS-1$
			value = introTheme.getId();
			iprefs.put(key, value);
		}
		if (toAll) {
			key = INTRO_THEME;
			iprefs.put(key, value);
		}
		try {
			uprefs.flush();
			iprefs.flush();
		} catch (BackingStoreException e) {
			e.printStackTrace();
		}
	}

	private void addHomePage() {
		TabItem item = new TabItem(tabFolder, SWT.NULL);
		item.setText(Messages.WelcomeCustomizationPreferencePage_home);
		Composite container = new Composite(tabFolder, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		container.setLayout(layout);
		Composite leftColumn = new Composite(container, SWT.NULL);
		layout = new GridLayout();
		layout.marginWidth = layout.marginHeight = 0;
		leftColumn.setLayout(layout);
		leftColumn.setLayoutData(new GridData(GridData.FILL_BOTH));
		Composite rightColumn = new Composite(container, SWT.NULL);
		layout = new GridLayout();
		layout.marginWidth = layout.marginHeight = 0;
		rightColumn.setLayout(layout);
		rightColumn.setLayoutData(new GridData(GridData.FILL_BOTH));

		Label themeLabel = new Label(leftColumn, SWT.NULL);
		themeLabel.setText(Messages.WelcomeCustomizationPreferencePage_background);
		GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
		themeLabel.setLayoutData(gd);
		themes = new TableViewer(leftColumn, SWT.BORDER);
		themes.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
		themes.setContentProvider(contentProvider);
		themes.setLabelProvider(labelProvider);
		themes.addSelectionChangedListener(e -> {
			Object sel = ((StructuredSelection) e.getSelection()).getFirstElement();
			introTheme = (IntroTheme) sel;
			themePreview.redraw();
			enableFontsButton();
		});
		loadThemes();
		Label previewLabel = new Label(rightColumn, SWT.NULL);
		previewLabel.setText(Messages.WelcomeCustomizationPreferencePage_preview);
		themePreview = new Canvas(rightColumn, SWT.BORDER);
		gd = new GridData();
		gd.widthHint = 160+20;
		gd.heightHint = 120+20;
		themePreview.setLayoutData(gd);
		themePreview.addPaintListener(e -> {
			if (introTheme == null)
				return;
			Image bgImage = introTheme.getPreviewImage();
			if (bgImage == null)
				return;
			//Rectangle carea = themePreview.getClientArea();
			Rectangle ibounds = bgImage.getBounds();
			e.gc.drawImage(bgImage, 0, 0, ibounds.width, ibounds.height, 10, 10, 160, 120);
		});
		Label label = new Label(container, SWT.NULL);
		label.setText(Messages.WelcomeCustomizationPreferencePage_rootpages);
		gd = new GridData();
		gd.horizontalSpan = 2;
		label.setLayoutData(gd);
		rootPages = CheckboxTableViewer.newCheckList(container, SWT.BORDER);
		rootPages.setContentProvider(contentProvider);
		rootPages.setLabelProvider(labelProvider);
		// Filter empty pages
		ViewerFilter[] rootPageFilters = new ViewerFilter[] {
			new ViewerFilter() {
				@Override
				public boolean select(Viewer viewer, Object parentElement,
						Object element) {
					if (element instanceof RootPage) {
						RootPage rootPageElement = (RootPage) element;
						String rootPageId = rootPageElement.getId();
						return (introData.getPage(rootPageId) != null);
					}
					return false;
				}
			}
		};
		rootPages.setFilters(rootPageFilters);
		gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
		gd.horizontalSpan = 2;
		rootPages.getControl().setLayoutData(gd);
		rootPages.addCheckStateListener(event -> {
			RootPage page = (RootPage) event.getElement();
			boolean checked = event.getChecked();
			onPageChecked(page.id, checked);
		});
		item.setControl(container);
	}

	private void loadThemes() {
		IConfigurationElement [] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.ui.intro.configExtension"); //$NON-NLS-1$
		for (int i=0; i<elements.length; i++) {
			if (elements[i].getName().equals("theme")) { //$NON-NLS-1$
				themeList.add(new IntroTheme(elements[i]));
			}
		}
	}

	private void addPage(String id) {
		if (!getRootPageSelected(id))
			return;
		TabItem item = new TabItem(tabFolder, SWT.NULL);
		item.setText(getRootPageName(id));
		item.setControl(pageContainer);
		item.setData(id);
		PageData pd = introData.getPage(id);
		item.setData("pageData", pd); //$NON-NLS-1$
	}

	private void onPageChecked(String id, boolean checked) {
		TabItem[] items = tabFolder.getItems();
		if (checked) {
			for (int i = 0; i < items.length; i++) {
				TabItem item = items[i];
				if (item.getData() != null)
					item.dispose();
			}
			introRootPages.add(id);
			addRootPages();
		} else {
			for (int i = 0; i < items.length; i++) {
				TabItem item = items[i];
				String itemId = (String) item.getData();
				if (itemId != null && itemId.equals(id)) {
					item.dispose();
					introRootPages.remove(id);
					return;
				}
			}
		}
	}

	private String getRootPageName(String id) {
		for (int i = 0; i < ROOT_PAGE_TABLE.length; i++) {
			if (ROOT_PAGE_TABLE[i].id.equals(id))
				return ROOT_PAGE_TABLE[i].getName();
		}
		return "?"; //$NON-NLS-1$
	}

	private boolean getRootPageSelected(String id) {
		for (int i = 0; i < introRootPages.size(); i++) {
			String cid = introRootPages.get(i);
			if (cid.equals(id))
				return true;
		}
		return false;
	}

	public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
			throws CoreException {
	}

	private void createPopupMenu(final TableViewer viewer) {
		MenuManager manager = new MenuManager();
		manager.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(manager.getMenu());
		manager.setRemoveAllWhenShown(true);
		manager.addMenuListener(manager1 -> fillPopupMenu(manager1, viewer));
	}

	private void addDNDSupport(TableViewer viewer) {
		viewer.addDragSupport(DND.DROP_MOVE, TRANSFER_TYPES, new TableDragSourceListener(viewer));
		viewer.addDropSupport(DND.DROP_MOVE, TRANSFER_TYPES, new TableDropTargetListener(viewer));
	}

	private TableViewer createTableViewer(Composite parent, String id) {
		final Table table = new Table(parent, SWT.BORDER | SWT.FULL_SELECTION);
		final TableColumn column1 = new TableColumn(table, SWT.NULL);
		column1.setMoveable(false);
		column1.setWidth(20);
		column1.setResizable(false);
		final TableColumn column2 = new TableColumn(table, SWT.NULL);
		column2.setResizable(true);
		final TableViewer viewer = new TableViewer(table);
		CellEditor[] editors = new CellEditor[2];
		editors[0] = new ComboBoxCellEditor(table, ExtensionData.IMPORTANCE_NAME_TABLE, SWT.READ_ONLY);
		viewer.setCellEditors(editors);
		viewer.setColumnProperties(new String[] { IUniversalIntroConstants.P_IMPORTANCE,
				IUniversalIntroConstants.P_NAME });
		viewer.setCellModifier(new ICellModifier() {

			@Override
			public boolean canModify(Object element, String property) {
				return property.equals(IUniversalIntroConstants.P_IMPORTANCE);
			}

			@Override
			public Object getValue(Object element, String property) {
				if (element instanceof ExtensionData) {
					ExtensionData ed = (ExtensionData) element;
					if (property.equals(IUniversalIntroConstants.P_IMPORTANCE))
						return new Integer(ed.getImportance());
				}
				return null;
			}

			@Override
			public void modify(Object element, String property, Object value) {
				Integer ivalue = (Integer) value;
				TableItem item = (TableItem) element;
				ExtensionData ed = (ExtensionData) item.getData();
				ed.setImportance(ivalue.intValue());
				viewer.update(ed, new String [] {IUniversalIntroConstants.P_IMPORTANCE});
			}
		});
		viewer.setContentProvider(contentProvider);
		viewer.setLabelProvider(labelProvider);
		viewer.setData("id", id); //$NON-NLS-1$
		createPopupMenu(viewer);
		addDNDSupport(viewer);
		return viewer;
	}

	private void fillPopupMenu(IMenuManager manager, final TableViewer viewer) {
		StructuredSelection ssel = (StructuredSelection) viewer.getSelection();

		manager.add(new Separator());
		Action addSeparator = new Action(Messages.WelcomeCustomizationPreferencePage_addSeparator) {
			@Override
			public void run() {
				doAddSeparator(viewer);
			}
		};

		manager.add(addSeparator);
		manager.add(new Separator());

		if (ssel.size() == 1 && viewer != available) {
			Action upAction = new Action(Messages.WelcomeCustomizationPreferencePage_up) {

				@Override
				public void run() {
					doMove(viewer, true);
				}
			};
			Action downAction = new Action(Messages.WelcomeCustomizationPreferencePage_down) {

				@Override
				public void run() {
					doMove(viewer, false);
				}
			};
			BaseData ed = (BaseData) ssel.getFirstElement();
			GroupData gd = (GroupData) viewer.getInput();
			upAction.setEnabled(gd.canMoveUp(ed));
			downAction.setEnabled(gd.canMoveDown(ed));
			manager.add(upAction);
			manager.add(downAction);
		}
		if (ssel.size() > 0) {
			manager.add(new Separator());
			MenuManager menu = new MenuManager(Messages.WelcomeCustomizationPreferencePage_moveTo);
			addMoveToAction(menu, available, viewer,
					Messages.WelcomeCustomizationPreferencePage_menu_available);
			addMoveToAction(menu, topLeft, viewer, Messages.WelcomeCustomizationPreferencePage_menu_top_left);
			addMoveToAction(menu, topRight, viewer, Messages.WelcomeCustomizationPreferencePage_menu_top_right);
			addMoveToAction(menu, bottomLeft, viewer, Messages.WelcomeCustomizationPreferencePage_menu_bottom_left);
			addMoveToAction(menu, bottomRight, viewer, Messages.WelcomeCustomizationPreferencePage_menu_bottom_right);
			manager.add(menu);

			boolean addDeleteSeparator=false;

			for (Iterator<?> iter=ssel.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof SeparatorData)
					addDeleteSeparator=true;
				else {
					addDeleteSeparator=false;
					break;
				}
			}
			if (addDeleteSeparator) {
				Action deleteSeparator = new Action(Messages.WelcomeCustomizationPreferencePage_removeSeparator) {
					@Override
					public void run() {
						doRemoveSeparators(viewer);
					}
				};
				manager.add(deleteSeparator);
			}
		}
	}

	private void addMoveToAction(MenuManager menu, final TableViewer target, final TableViewer source,
			String name) {
		if (source == target)
			return;
		Action action = new Action(name) {

			@Override
			public void run() {
				doMoveTo(source, target);
			}
		};
		menu.add(action);
	}

	private void doMove(Viewer viewer, boolean up) {
		Object obj = ((StructuredSelection) viewer.getSelection()).getFirstElement();
		GroupData gd = (GroupData) viewer.getInput();
		if (up)
			gd.moveUp((BaseData) obj);
		else
			gd.moveDown((BaseData) obj);
		viewer.refresh();
	}

	private void doAddSeparator(Viewer viewer) {
		Object obj = ((StructuredSelection) viewer.getSelection()).getFirstElement();
		GroupData gd = (GroupData) viewer.getInput();
		if (gd == null) {
			gd = createTargetGd(viewer);
			viewer.setInput(gd);
		}
		gd.addSeparator((BaseData)obj);
		viewer.refresh();
		updateColumnSizes((TableViewer)viewer);
	}

	private void doRemoveSeparators(Viewer viewer) {
		StructuredSelection ssel = ((StructuredSelection) viewer.getSelection());
		GroupData gd = (GroupData) viewer.getInput();
		for (Iterator<SeparatorData> iter=ssel.iterator(); iter.hasNext();) {
			SeparatorData sdata = iter.next();
			gd.remove(sdata);
		}
		viewer.refresh();
	}

	private void doMoveTo(TableViewer source, TableViewer target) {
		Object[] selObjs = ((StructuredSelection) source.getSelection()).toArray();
		GroupData sourceGd = (GroupData) source.getInput();
		GroupData targetGd = (GroupData) target.getInput();
		if (targetGd == null) {
			targetGd = createTargetGd(target);
		}
		for (int i = 0; i < selObjs.length; i++) {
			BaseData ed = (BaseData) selObjs[i];
			sourceGd.remove(ed);
			targetGd.add(ed);
		}
		source.refresh();
		updateColumnSizes(source);
		if (target.getInput() != null)
			target.refresh();
		else
			target.setInput(targetGd);
		updateColumnSizes(target);
	}

	private void updateColumnSizes(TableViewer viewer) {
		TableColumn sc = viewer.getTable().getColumn(1);
		sc.pack();
	}

	private GroupData createTargetGd(Viewer target) {
		GroupData targetGd = null;
		if (target == topLeft)
			targetGd = new GroupData(PageData.P_TOP_LEFT, false);
		else if (target == topRight)
			targetGd = new GroupData(PageData.P_TOP_RIGHT, false);
		else if (target == bottomLeft)
			targetGd = new GroupData(PageData.P_BOTTOM_LEFT, false);
		else if (target == bottomRight)
			targetGd = new GroupData(PageData.P_BOTTOM_RIGHT, false);
		else if (target == available)
			targetGd = new GroupData(IUniversalIntroConstants.HIDDEN, false);
		else
			return null;
		TabItem[] items = tabFolder.getSelection();
		PageData pd = (PageData) items[0].getData("pageData"); //$NON-NLS-1$
		if (pd == null) {
			String pageId = (String)items[0].getData();
			pd = new PageData(pageId);
			items[0].setData("pageData", pd); //$NON-NLS-1$
			introRootPages.add(pageId);
		}
		pd.add(targetGd);
		return targetGd;
	}

	private void selectFirstPage() {
		if (firstPageId == null)
			return;
		TabItem[] items = tabFolder.getItems();
		for (int i = 0; i < items.length; i++) {
			TabItem item = items[i];
			PageData pd = (PageData) item.getData("pageData"); //$NON-NLS-1$
			if (pd != null && pd.getId().equals(firstPageId)) {
				tabFolder.setSelection(i);
				onTabChange(item);
				return;
			}
		}
	}

	public void setCurrentPage(String pageId) {
		firstPageId = pageId;
	}

	public void setShell(Shell shell) {
		this.shell = shell;
	}
}
