/*******************************************************************************
 * Copyright (c) 2005, 2007 BEA Systems, Inc.
 * 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:
 *   wharley@bea.com - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.apt.ui.internal.preferences;

import java.io.IOException;
import java.util.Map.Entry;

import org.eclipse.jdt.apt.core.internal.util.FactoryContainer;
import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
import org.eclipse.jdt.apt.ui.internal.util.ExceptionHandler;
import org.eclipse.jdt.apt.ui.internal.util.IAptHelpContextIds;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * Dialog to display "advanced options" on a FactoryPathEntry,
 * typically in the context of the factory path config UI.
 * Advanced options are those which do not normally need to
 * be configured, and which may require deeper-than-usual
 * understanding of the annotation processing architecture.
 */
public class AdvancedFactoryPathOptionsDialog extends Dialog {
	
	private final static int LIST_WIDTH= 70; // width (in chars) of factory list
	private final static int LIST_HEIGHT= 10; // number of lines in factory list
	
	private class FieldAdapter implements IDialogFieldListener {
		public void dialogFieldChanged(DialogField field) {
		}
	}
	
	// shallow copies, because they are not changed by this code
	private final FactoryContainer _fc;
	private final FactoryPath.Attributes _attr;
	
	// Dialog controls
	private SelectionButtonDialogField _batchModeField;
	private ListViewer _contentsField;
	
	public AdvancedFactoryPathOptionsDialog(
			Shell parent, FactoryContainer fc, FactoryPath.Attributes attr) {
		super(parent);
		setShellStyle(getShellStyle() | SWT.RESIZE);
		_fc= fc;
		_attr= attr;
	}
	
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText(Messages.AdvancedFactoryPathOptionsDialog_advancedOptions);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IAptHelpContextIds.ADVANCED_FACTORYPATH_OPTIONS_DIALOG);
    }
    
	protected Control createDialogArea(Composite parent) {
		Composite dlgArea= (Composite) super.createDialogArea(parent);
		
		// Set up "batch mode" checkbox.
		FieldAdapter adapter = new FieldAdapter();
		_batchModeField = new SelectionButtonDialogField(SWT.CHECK);
		_batchModeField.setSelection(_attr.runInBatchMode());
		_batchModeField.setLabelText(Messages.AdvancedFactoryPathOptionsDialog_batchMode);
		_batchModeField.setDialogFieldListener(adapter);
		_batchModeField.doFillIntoGrid(dlgArea, 2);
			// Plugins can't run in APT compatibility mode.
		boolean isPlugin = _fc.getType() == FactoryContainer.FactoryType.PLUGIN;
		_batchModeField.setEnabled(!isPlugin);
		
		DialogField.createEmptySpace(dlgArea, 1);

		// Set up label for processor contents list
		Label description= new Label(dlgArea, SWT.WRAP);
		description.setText(Messages.AdvancedFactoryPathOptionsDialog_label_processorsInThisContainer); 
		GridData gdLabel= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gdLabel.horizontalSpan= 2;
		description.setLayoutData(gdLabel);

		// Set up processor contents list
		_contentsField= new ListViewer(dlgArea, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
        data.heightHint = convertHeightInCharsToPixels(LIST_HEIGHT);
        data.widthHint = convertWidthInCharsToPixels(LIST_WIDTH);
        _contentsField.getList().setLayoutData(data);
        _contentsField.getList().setFont(parent.getFont());
        try {
	        for (Entry<String, String> entry : _fc.getFactoryNames().entrySet()) {
	        	String name = entry.getKey();
	        	_contentsField.add(name);
	        	//TODO: display the processor type (i.e., entry.getValue())
	        }
        }
        catch (IOException e) {
			final String message = "Unable to load factory names from container [" + _fc.getId() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
			ExceptionHandler.log(e, message);
        }
        _contentsField.setSelection(null, false);
        
		applyDialogFont(dlgArea);		
		return dlgArea;
	}
		
	/**
	 * Return a new Attributes representing the original value updated
	 * with any changes made by the user.  Changes will be included even
	 * if the dialog was cancelled, so this should only be called if the
	 * dialog returned OK.
	 */
	public FactoryPath.Attributes getResult() {
		boolean batchMode = _batchModeField.isSelected();
		return new FactoryPath.Attributes(_attr.isEnabled(), batchMode);
	}
}
