content: package ts.eclipse.ide.internal.ui.wizards;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.stream.Collectors;
  
  import org.eclipse.core.resources.IFile;
  import org.eclipse.core.resources.IProject;
  import org.eclipse.core.resources.IResource;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IStatus;
  import org.eclipse.core.runtime.Status;
  import org.eclipse.jface.dialogs.ControlEnableState;
  import org.eclipse.jface.viewers.ArrayContentProvider;
  import org.eclipse.jface.viewers.ComboViewer;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.events.SelectionAdapter;
  import org.eclipse.swt.events.SelectionEvent;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Button;
  import org.eclipse.swt.widgets.Combo;
  /**
   *  Copyright (c) 2015-2017 Angelo ZERR.
   *  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:
   *  Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
   *
   */
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Group;
  
  import ts.cmd.tsc.CompilerOptions;
  import ts.cmd.tsc.Plugin;
  import ts.eclipse.ide.core.TypeScriptCorePlugin;
  import ts.eclipse.ide.internal.ui.TypeScriptUIMessages;
  import ts.eclipse.ide.terminal.interpreter.LineCommand;
  import ts.eclipse.ide.terminal.interpreter.TerminalCommandAdapter;
  import ts.eclipse.ide.ui.widgets.NpmInstallWidget;
  import ts.eclipse.ide.ui.wizards.AbstractWizardPage;
  import ts.repository.ITypeScriptRepository;
  import ts.resources.jsonconfig.TsconfigJson;
  
  public class TSLintWizardPage extends AbstractWizardPage {
  
  	private static final String PAGE_NAME = "TSLintWizardPage";
  
  	private ControlEnableState fBlockEnableState;
  	private Button enableTslint;
  	private Composite controlsComposite;
  
  	// tslint Runtime
  	private Button useEmbeddedTslintRuntimeButton;
  	private boolean useEmbeddedTslintRuntime;
  	private Combo embeddedTslintRuntime;
  	private NpmInstallWidget installTslintRuntime;
  
  	// tslint Plugin
  	private Button useEmbeddedTslintPluginButton;
  	private boolean useEmbeddedTslintPlugin;
  	private Combo embeddedTslintPlugin;
  	private NpmInstallWidget installTslintPlugin;
  
  	protected TSLintWizardPage() {
  		super(PAGE_NAME, TypeScriptUIMessages.TSLintWizardPage_title, null);
  		super.setDescription(TypeScriptUIMessages.TSLintWizardPage_description);
  	}
  
  	@Override
  	protected void createBody(Composite parent) {
  		Composite composite = new Composite(parent, SWT.NONE);
  		GridLayout layout = new GridLayout();
  		layout.marginHeight = 0;
  		layout.marginWidth = 0;
  		composite.setLayout(layout);
  		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
  
  		enableTslint = new Button(composite, SWT.CHECK);
  		enableTslint.setText(TypeScriptUIMessages.TSLintWizardPage_enableTslint_text);
  		enableTslint.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(SelectionEvent e) {
  				enableTslintContent(enableTslint.getSelection());
  			}
  		});
  
  		controlsComposite = new Composite(composite, SWT.NONE);
  		controlsComposite.setFont(composite.getFont());
  		controlsComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  
  		layout = new GridLayout();
  		layout.marginHeight = 0;
  		layout.marginWidth = 0;
  		layout.numColumns = 1;
  		controlsComposite.setLayout(layout);
  		createTslintRuntimeBody(controlsComposite);
  		createTslintPluginBody(controlsComposite);
  	}
  
  	// ------------------- tslint Runtime content
  
  	private void createTslintRuntimeBody(Composite parent) {
  		Group group = new Group(parent, SWT.NONE);
  		group.setFont(parent.getFont());
  		group.setText(TypeScriptUIMessages.TSLintWizardPage_tslint_group_label);
  		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  
  		int nColumns = 2;
  		GridLayout layout = new GridLayout();
  		layout.numColumns = nColumns;
  		group.setLayout(layout);
  
  		// Embedded tslint
  		createEmbeddedTslintField(group);
  		// Install Typetslint
  		createInstallTslintField(group);
  	}
  
  	private void createEmbeddedTslintField(Composite parent) {
  		useEmbeddedTslintRuntimeButton = new Button(parent, SWT.RADIO);
  		useEmbeddedTslintRuntimeButton.setText(TypeScriptUIMessages.TSLintWizardPage_useEmbeddedTslintRuntime_label);
  		useEmbeddedTslintRuntimeButton.addListener(SWT.Selection, this);
  		useEmbeddedTslintRuntimeButton.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(SelectionEvent e) {
  				updateTslintRuntimeMode();
  			}
  		});
  
  		embeddedTslintRuntime = new Combo(parent, SWT.READ_ONLY);
  		embeddedTslintRuntime.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  
  		ComboViewer viewer = new ComboViewer(embeddedTslintRuntime);
  		viewer.setContentProvider(ArrayContentProvider.getInstance());
  		viewer.setLabelProvider(new TypeScriptRepositoryLabelProvider(true, false));
  		List<ITypeScriptRepository> repositories = Arrays
  				.stream(TypeScriptCorePlugin.getTypeScriptRepositoryManager().getRepositories())
  				.filter(r -> r.getTslintFile() != null).collect(Collectors.toList());
  		viewer.setInput(repositories);
  	}
  
  	private void createInstallTslintField(Composite parent) {
  		Button useInstallTslintRuntime = new Button(parent, SWT.RADIO);
  		useInstallTslintRuntime.setText(TypeScriptUIMessages.TSLintWizardPage_useInstallTslintRuntime_label);
  		useInstallTslintRuntime.addListener(SWT.Selection, this);
  		useInstallTslintRuntime.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(SelectionEvent e) {
  				updateTslintRuntimeMode();
  			}
  		});
  		installTslintRuntime = new NpmInstallWidget("tslint", this, parent, SWT.NONE);
  		installTslintRuntime.getVersionText().addListener(SWT.Modify, this);
  	}
  
  	private void updateTslintRuntimeMode() {
  		useEmbeddedTslintRuntime = useEmbeddedTslintRuntimeButton.getSelection();
  		embeddedTslintRuntime.setEnabled(useEmbeddedTslintRuntime);
  		installTslintRuntime.setEnabled(!useEmbeddedTslintRuntime);
  	}
  
  	private IStatus validateTslintRuntime() {
  		if (useEmbeddedTslintRuntimeButton.getSelection()) {
  			return Status.OK_STATUS;
  		}
  		return installTslintRuntime.getStatus();
  	}
  
  	// ------------------- tslint Plugin content
  
  	private void createTslintPluginBody(Composite parent) {
  		Group group = new Group(parent, SWT.NONE);
  		group.setFont(parent.getFont());
  		group.setText(TypeScriptUIMessages.TSLintWizardPage_tslintPlugin_group_label);
  		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  
  		int nColumns = 2;
  		GridLayout layout = new GridLayout();
  		layout.numColumns = nColumns;
  		group.setLayout(layout);
  
  		// Embedded tslint plugin
  		createEmbeddedTslintPluginField(group);
  		// Install tslint plugin
  		createInstallTslintPluginField(group);
  	}
  
  	private void createEmbeddedTslintPluginField(Composite parent) {
  		useEmbeddedTslintPluginButton = new Button(parent, SWT.RADIO);
  		useEmbeddedTslintPluginButton.setText(TypeScriptUIMessages.TSLintWizardPage_useEmbeddedTslintPlugin_label);
  		useEmbeddedTslintPluginButton.addListener(SWT.Selection, this);
  		useEmbeddedTslintPluginButton.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(SelectionEvent e) {
  				updateTslintPluginMode();
  			}
  		});
  
  		embeddedTslintPlugin = new Combo(parent, SWT.READ_ONLY);
  		embeddedTslintPlugin.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  
  		ComboViewer viewer = new ComboViewer(embeddedTslintPlugin);
  		viewer.setContentProvider(ArrayContentProvider.getInstance());
  		viewer.setLabelProvider(new TypeScriptRepositoryLabelProvider(false, true));
  		List<ITypeScriptRepository> repositories = Arrays
  				.stream(TypeScriptCorePlugin.getTypeScriptRepositoryManager().getRepositories())
  				.filter(r -> r.getTslintLanguageServiceName() != null).collect(Collectors.toList());
  		viewer.setInput(repositories);
  	}
  
  	private void createInstallTslintPluginField(Composite parent) {
  		Button useInstallTslintPlugin = new Button(parent, SWT.RADIO);
  		useInstallTslintPlugin.setText(TypeScriptUIMessages.TSLintWizardPage_useInstallTslintPlugin_label);
  		useInstallTslintPlugin.addListener(SWT.Selection, this);
  		useInstallTslintPlugin.addSelectionListener(new SelectionAdapter() {
  			@Override
  			public void widgetSelected(SelectionEvent e) {
  				updateTslintPluginMode();
  			}
  		});
  		installTslintPlugin = new NpmInstallWidget("tslint-language-service", this, parent, SWT.NONE);
  		installTslintPlugin.getVersionText().addListener(SWT.Modify, this);
  	}
  
  	private void updateTslintPluginMode() {
  		useEmbeddedTslintPlugin = useEmbeddedTslintPluginButton.getSelection();
  		embeddedTslintPlugin.setEnabled(useEmbeddedTslintPlugin);
  		installTslintPlugin.setEnabled(!useEmbeddedTslintPlugin);
  	}
  
  	private IStatus validateTslintPlugin() {
  		if (useEmbeddedTslintPluginButton.getSelection()) {
  			return Status.OK_STATUS;
  		}
  		return installTslintPlugin.getStatus();
  	}
  
  	@Override
  	protected void initializeDefaultValues() {
  		// Default values for tslint runtime
  		if (embeddedTslintRuntime.getItemCount() > 0) {
  			embeddedTslintRuntime.select(0);
  		}
  		useEmbeddedTslintRuntimeButton.setSelection(true);
  		updateTslintRuntimeMode();
  
  		if (embeddedTslintPlugin.getItemCount() > 0) {
  			embeddedTslintPlugin.select(0);
  		}
  		useEmbeddedTslintPluginButton.setSelection(true);
  		updateTslintPluginMode();
  
  		// Disable tslint
  		enableTslint.setSelection(false);
  		enableTslintContent(false);
  	}
  
  	@Override
  	protected IStatus[] validatePage() {
  		IStatus[] status = new IStatus[2];
  		status[0] = validateTslintRuntime();
  		status[1] = validateTslintPlugin();
  		return status;
  	}
  
  	protected void enableTslintContent(boolean enable) {
  		if (enable) {
  			if (fBlockEnableState != null) {
  				fBlockEnableState.restore();
  				fBlockEnableState = null;
  			}
  		} else {
  			if (fBlockEnableState == null) {
  				fBlockEnableState = ControlEnableState.disable(controlsComposite);
  			}
  		}
  	}
  
  	public String getNpmInstallCommand() {
  		if (useEmbeddedTslintRuntime) {
  			return null;
  		}
  		return installTslintRuntime.getNpmInstallCommand();
  	}
  
  	public void updateTsconfig(TsconfigJson tsconfig) {
  		if (enableTslint.getSelection()) {
  			CompilerOptions compilerOptions = tsconfig.getCompilerOptions();
  			if (compilerOptions == null) {
  				compilerOptions = new CompilerOptions();
  				tsconfig.setCompilerOptions(compilerOptions);
  			}
  			List<Plugin> plugins = compilerOptions.getPlugins();
  			if (plugins == null) {
  				plugins = new ArrayList<>();
  				compilerOptions.setPlugins(plugins);
  			}
  
  			Plugin plugin = new Plugin();
  			plugin.setName("tslint-language-service");
  			plugins.add(plugin);
  		}
  
  	}
  
  	@Override
  	public void updateCommand(List<LineCommand> commands, IProject project) {
  		if (!useEmbeddedTslintRuntime) {
  			commands.add(new LineCommand(installTslintRuntime.getNpmInstallCommand()));
  			// generate a tslint.json file by using tslint toolings
  			commands.add(new LineCommand("node node_modules/tslint/bin/tslint -i", new TerminalCommandAdapter() {
  				@Override
  				public void onTerminateCommand(LineCommand lineCommand) {
  					IFile tslintJsonFile = project.getFile("tslint.json");
  					try {
  						tslintJsonFile.refreshLocal(IResource.DEPTH_INFINITE, null);
  					} catch (CoreException e) {
  						e.printStackTrace();
  					}
  				}
  			}));
  		}
  		if (!useEmbeddedTslintPlugin) {
  			commands.add(new LineCommand(installTslintPlugin.getNpmInstallCommand()));
  		}
  	}
  }
  