/*******************************************************************************
 * Copyright (c) 2004, 2007 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
 *     Daniel Megert daniel_megert@ch.ibm.com Bug 169696
 *******************************************************************************/
package org.eclipse.ui.ide.dialogs;

import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.util.List;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.WorkbenchEncoding;
import org.eclipse.ui.ide.IDEEncoding;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;

/**
 * The abstract superclass of field editors used to set an encoding. Any user
 * entered encodings will be added to the list of encodings available via
 * {@link org.eclipse.ui.ide.IDEEncoding}.
 * <p>
 * Subclasses may extend, but must call <code>createEncodingGroup</code>
 * during <code>doFillIntoGrid</code>.
 * </p>
 * 
 * @see org.eclipse.ui.ide.IDEEncoding
 * @since 3.1
 */
public abstract class AbstractEncodingFieldEditor extends FieldEditor {

	private Composite container;

	private Button defaultEncodingButton;

	private String defaultEnc;

	private Button otherEncodingButton;

	private Combo encodingCombo;

	private boolean isValid = true;

	private String oldSelectedEncoding;

	private String groupTitle = IDEWorkbenchMessages.WorkbenchPreference_encoding;

	/**
	 * Creates a new encoding field editor with no settings set.
	 */
	protected AbstractEncodingFieldEditor() {
		super();
	}

	/**
	 * Creates a new encoding field editor with the given preference name, label
	 * and parent.
	 * 
	 * @param name
	 *            the name of the preference this field editor works on
	 * @param labelText
	 *            the label text of the field editor
	 * @param parent
	 *            the parent of the field editor's control
	 */
	protected AbstractEncodingFieldEditor(String name, String labelText,
			Composite parent) {
		super(name, labelText, parent);
	}

	/**
	 * Creates a new encoding field editor with the given preference name, label
	 * and parent.
	 * 
	 * @param name
	 *            the name of the preference this field editor works on
	 * @param labelText
	 *            the label text of the field editor
	 * @param groupTitle
	 *            the title for the field editor's control. If groupTitle is 
	 *            <code>null</code> the control will be unlabelled
	 *            (by default a {@link Composite} instead of a {@link Group}.
	 * @param parent
	 *            the parent of the field editor's control
	 * @see AbstractEncodingFieldEditor#setGroupTitle(String)
	 * @since 3.3
	 */
	protected AbstractEncodingFieldEditor(String name, String labelText,
			String groupTitle, Composite parent) {
		init(name, labelText);
		this.groupTitle = groupTitle;
		createControl(parent);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int)
	 */
	protected void adjustForNumColumns(int numColumns) {
		((GridData) getContainer().getLayoutData()).horizontalSpan = numColumns;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(org.eclipse.swt.widgets.Composite,
	 *      int)
	 */
	protected void doFillIntoGrid(Composite parent, int numColumns) {
		container = createEncodingGroup(parent, numColumns);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#doLoad()
	 */
	protected void doLoad() {
		if (encodingCombo != null) {
			List encodings = IDEEncoding.getIDEEncodings();
			String resourcePreference = getStoredValue();
			populateEncodingsCombo(encodings, resourcePreference);
			updateEncodingState(resourcePreference == null);
		}
	}

	/**
	 * Returns the value that is currently stored for the encoding.
	 * 
	 * @return the currently stored encoding
	 */
	protected abstract String getStoredValue();

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault()
	 */
	protected void doLoadDefault() {
		updateEncodingState(true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls()
	 */
	public int getNumberOfControls() {
		return 1;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#isValid()
	 */
	public boolean isValid() {
		return isValid;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#refreshValidState()
	 */
	protected void refreshValidState() {
		updateValidState();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore)
	 */
	public void setPreferenceStore(IPreferenceStore store) {
		super.setPreferenceStore(store);
		defaultEnc = store.getDefaultString(getPreferenceName());
		updateDefaultEncoding();
	}

	private void updateDefaultEncoding() {
		defaultEncodingButton.setText(defaultButtonText());
	}

	private Composite getContainer() {
		return container;
	}

	/**
	 * Creates a composite with all the encoding controls.
	 * <p>
	 * Subclasses may extend.
	 * </p>
	 * 
	 * @param parent
	 *            the parent widget
	 * @param numColumns
	 *            the number of columns in the parent
	 * @return the group control
	 */
	protected Composite createEncodingGroup(Composite parent, int numColumns) {

		Composite topControl;
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;

		if (groupTitle == null){
			topControl = new Composite(parent, SWT.NONE);
			layout.marginWidth = 0;
			layout.marginHeight = 0;
		}
		else {
			Group top = new Group(parent, SWT.NONE);
			top.setText(groupTitle);
			topControl = top;
		}

		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		topControl.setLayoutData(data);		
		topControl.setLayout(layout);

		SelectionAdapter buttonListener = new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateEncodingState(defaultEncodingButton.getSelection());
				updateValidState();
			}
		};

		defaultEncodingButton = new Button(topControl, SWT.RADIO);
		defaultEnc = findDefaultEncoding();
		defaultEncodingButton.setText(defaultButtonText());
		data = new GridData();
		data.horizontalSpan = 2;
		defaultEncodingButton.setLayoutData(data);
		defaultEncodingButton.addSelectionListener(buttonListener);

		otherEncodingButton = new Button(topControl, SWT.RADIO);
		otherEncodingButton
				.setText(IDEWorkbenchMessages.WorkbenchPreference_otherEncoding);
		otherEncodingButton.addSelectionListener(buttonListener);

		encodingCombo = new Combo(topControl, SWT.NONE);
		data = new GridData();
		encodingCombo.setLayoutData(data);
		encodingCombo.addSelectionListener(new SelectionAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
			 */
			public void widgetSelected(SelectionEvent e) {
				updateValidState();
			}
		});
		encodingCombo.addKeyListener(new KeyAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
			 */
			public void keyReleased(KeyEvent e) {
				updateValidState();
			}
		});

		return topControl;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.preference.FieldEditor#setEnabled(boolean,
	 *      org.eclipse.swt.widgets.Composite)
	 * @since 3.3
	 */
	public void setEnabled(boolean enabled, Composite parent) {
		if (container != null)
			container.setEnabled(enabled);
		if (defaultEncodingButton != null)
			defaultEncodingButton.setEnabled(enabled);
		if (otherEncodingButton != null)
			otherEncodingButton.setEnabled(enabled);
		if (encodingCombo != null)
			encodingCombo.setEnabled(enabled);
		
	}

	/**
	 * Returns the default encoding for the object being shown.
	 * 
	 * @return the default encoding for the object being shown
	 */
	protected String findDefaultEncoding() {
		return WorkbenchEncoding.getWorkbenchDefaultEncoding();
	}

	/**
	 * Returns the text for the default encoding button.
	 * 
	 * @return the text for the default encoding button
	 */
	protected String defaultButtonText() {
		return NLS.bind(
				IDEWorkbenchMessages.WorkbenchPreference_defaultEncoding,
				defaultEnc);
	}

	/**
	 * Populates the encodings combo. Sets the text based on the selected
	 * encoding. If there is no selected encoding, the text is set to the
	 * default encoding.
	 * 
	 * @param encodings
	 *            the list of encodings (list of String)
	 * @param selectedEncoding
	 *            the selected encoding, or <code>null</code>
	 */
	private void populateEncodingsCombo(List encodings, String selectedEncoding) {
		String[] encodingStrings = new String[encodings.size()];
		encodings.toArray(encodingStrings);
		encodingCombo.setItems(encodingStrings);

		if (selectedEncoding == null) {
			encodingCombo.setText(getDefaultEnc());
		} else {
			encodingCombo.setText(selectedEncoding);
		}
	}

	private void updateEncodingState(boolean useDefault) {
		defaultEncodingButton.setSelection(useDefault);
		otherEncodingButton.setSelection(!useDefault);
		if (useDefault) {
			encodingCombo.setText(getDefaultEnc());
		}
		encodingCombo.setEnabled(!useDefault);
		setPresentsDefaultValue(useDefault);
		updateValidState();
	}

	private void updateValidState() {
		boolean isValidNow = isEncodingValid();
		if (isValidNow != isValid) {
			isValid = isValidNow;
			if (isValid) {
				clearErrorMessage();
			} else {
				showErrorMessage(IDEWorkbenchMessages.WorkbenchPreference_unsupportedEncoding);
			}
			fireStateChanged(IS_VALID, !isValid, isValid);
		}
		String newValue = getSelectedEncoding();
		if (isValid && !newValue.equals(oldSelectedEncoding)) {
			fireValueChanged(VALUE, oldSelectedEncoding, newValue);
			oldSelectedEncoding = newValue;
		}
	}

	/**
	 * Returns the currently selected encoding.
	 * 
	 * @return the currently selected encoding
	 */
	protected String getSelectedEncoding() {
		if (defaultEncodingButton.getSelection()) {
			return defaultEnc;
		}
		return encodingCombo.getText();
	}

	private boolean isEncodingValid() {
		return defaultEncodingButton.getSelection()
				|| isValidEncoding(encodingCombo.getText());
	}

	/**
	 * Returns whether or not the given encoding is valid.
	 * 
	 * @param enc
	 *            the encoding to validate
	 * @return <code>true</code> if the encoding is valid, <code>false</code>
	 *         otherwise
	 */
	private boolean isValidEncoding(String enc) {
		try {
			return Charset.isSupported(enc);
		} catch (IllegalCharsetNameException e) {
			// This is a valid exception
			return false;
		}

	}

	/**
	 * Returns the default encoding.
	 * 
	 * @return the default encoding
	 */
	protected String getDefaultEnc() {
		return defaultEnc;
	}

	/**
	 * Returns whether or not the encoding setting changed.
	 * 
	 * @param encodingSetting
	 *            the setting from the page.
	 * @return boolean <code>true</code> if the resource encoding is the same
	 *         as before.
	 */
	protected boolean hasSameEncoding(String encodingSetting) {

		String current = getStoredValue();

		if (encodingSetting == null) {
			// Changed if default is selected and there is no setting
			return current == null || current.length() == 0;
		}
		return encodingSetting.equals(current);
	}

	/**
	 * Return whether or not the default has been selected.
	 * 
	 * @return <code>true</code> if the default button has been selected.
	 */
	boolean isDefaultSelected() {
		return defaultEncodingButton.getSelection();
	}

	/**
	 * Set the title of the group to groupTitle. If this is not called a default
	 * title is used. If groupTitle is <code>null</code> the control will be
	 * unlabelled (by default a {@link Composite} instead of a {@link Group}.
	 * 
	 * <strong>NOTE</strong> this value must be set before
	 * {@link #createControl(Composite)} is called or it will be ignored.
	 * 
	 * @param groupTitle
	 *            The groupTitle to set.
     * @since 3.3
	 */
	public void setGroupTitle(String groupTitle) {
		this.groupTitle = groupTitle;
	}

}
