/*******************************************************************************
 * 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
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 515362
 *******************************************************************************/
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.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
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.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 CTabFolder 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 CTabFolder(container, SWT.BORDER);
		tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
		tabFolder.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				CTabItem selection = tabFolder.getSelection();
				onTabChange(selection);
			}
		});
		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.png"); //$NON-NLS-1$
		ihighImage = ImageUtil.createImage("full/obj16/ihigh_obj.png"); //$NON-NLS-1$
		ilowImage = ImageUtil.createImage("full/obj16/ilow_obj.png"); //$NON-NLS-1$
		inewImage = ImageUtil.createImage("full/obj16/inew_obj.png"); //$NON-NLS-1$
		icalloutImage = ImageUtil.createImage("full/obj16/icallout_obj.png"); //$NON-NLS-1$
		themeImage = ImageUtil.createImage("welcome16.png"); //$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(CTabItem 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
		CTabItem[] 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() {
		CTabItem item = new CTabItem(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;
		CTabItem item = new CTabItem(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) {
		CTabItem[] items = tabFolder.getItems();
		if (checked) {
			for (int i = 0; i < items.length; i++) {
				CTabItem item = items[i];
				if (item.getData() != null)
					item.dispose();
			}
			introRootPages.add(id);
			addRootPages();
		} else {
			for (int i = 0; i < items.length; i++) {
				CTabItem 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;
		CTabItem item = tabFolder.getSelection();
		PageData pd = (PageData) item.getData("pageData"); //$NON-NLS-1$
		if (pd == null) {
			String pageId = (String)item.getData();
			pd = new PageData(pageId);
			item.setData("pageData", pd); //$NON-NLS-1$
			introRootPages.add(pageId);
		}
		pd.add(targetGd);
		return targetGd;
	}

	private void selectFirstPage() {
		if (firstPageId == null)
			return;
		CTabItem[] items = tabFolder.getItems();
		for (int i = 0; i < items.length; i++) {
			CTabItem 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;
	}
}
