/*******************************************************************************
 * Copyright (c) 2006, 2014 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.IMenuListener;
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.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
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.SelectionChangedEvent;
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.PaintEvent;
import org.eclipse.swt.events.PaintListener;
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(), new Runnable() {
			@Override
			public void run() {
				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(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent 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(new PaintListener() {

			@Override
			public void paintControl(PaintEvent 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(new ICheckStateListener() {

			@Override
			public void checkStateChanged(CheckStateChangedEvent 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(new IMenuListener() {

			@Override
			public void menuAboutToShow(IMenuManager manager) {
				fillPopupMenu(manager, 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;
	}
}
