/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.internal.preferences;

import java.util.Vector;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.sse.core.internal.encoding.CommonCharsetNames;
import org.eclipse.wst.xml.ui.internal.Logger;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;

/**
 * EncodingSettings is a composite that can be used to display the set of
 * encoding values that are available to the user. The list of encoding values
 * is based off the SupportedJavaEncoding class. As the user selects an
 * encoding from the combo box, the readonly field below it changes to show
 * the IANA tag for that particular encoding description. The labels for the
 * widgets are configurable and the initial value to display to the user can
 * be set using the setIANATag(). The currently selected entry's IANA tag can
 * be retrieved with getIANATag(). Entries displayed to the user can be added
 * and removed.
 */
public class EncodingSettings extends Composite {

	private class ComboListener implements ModifyListener {
		public void modifyText(ModifyEvent e) {
			int i = encodingCombo.getSelectionIndex();
			if (i >= 0 && i < ianaVector.size())
				ianaText.setText((String) (ianaVector.elementAt(encodingCombo.getSelectionIndex())));
		}
	}

	private static String ENCODING_LABEL = XMLUIMessages.EncodingSettings_1; //$NON-NLS-1$

	private static String IANA_LABEL = XMLUIMessages.EncodingSettings_0; //$NON-NLS-1$

	private ModifyListener comboListener = new ComboListener();
	protected Combo encodingCombo;
	protected Label encodingLabel, ianaLabel;
	protected Text ianaText;
	protected Vector ianaVector;

	/**
	 * Method EncodingSettings.
	 * 
	 * @param parent
	 */
	public EncodingSettings(Composite parent) {
		super(parent, SWT.NONE);
		init(IANA_LABEL, ENCODING_LABEL);
	}

	/**
	 * Method EncodingSettings.
	 * 
	 * @param parent
	 * @param encodingLabel -
	 *            text label to use beside the locale sensitive description of
	 *            the currently selected encoding
	 */
	public EncodingSettings(Composite parent, String encodingLabel) {
		super(parent, SWT.NONE);
		init(IANA_LABEL, encodingLabel);
	}

	/**
	 * Method EncodingSettings.
	 * 
	 * @param parent
	 * @param ianaLabel =
	 *            text label to use beside the display only IANA field
	 * @param encodingLabel -
	 *            text label to use beside the locale sensitive description of
	 *            the currently selected encoding
	 */
	public EncodingSettings(Composite parent, String ianaLabel, String encodingLabel) {
		super(parent, SWT.NONE);
		init(ianaLabel, encodingLabel);
	}

	/**
	 * Method addEntry. Add an entry to the end of the Encoding Combobox
	 * 
	 * @param description -
	 *            encoding description to display
	 * @param ianaTag -
	 *            IANA tag for the description
	 */
	public void addEntry(String description, String ianaTag) {
		encodingCombo.add(description);
		ianaVector.add(ianaTag);
	}

	/**
	 * Method addEntry. Add an entry to the Encoding Combobox at index index
	 * 
	 * @param description -
	 *            encoding description to display
	 * @param ianaTag -
	 *            IANA tag for the description
	 * @param index -
	 *            index into the combo to add to
	 */
	public void addEntry(String description, String ianaTag, int index) {
		if (index == ianaVector.size()) {
			// just add to the end
			addEntry(description, ianaTag);
			return;
		}

		if (0 <= index && index < ianaVector.size()) {
			encodingCombo.add(description, index);
			ianaVector.add(index, ianaTag);
		}
	}

	protected Combo createComboBox(Composite parent, boolean isReadOnly) {
		int style = isReadOnly == true ? SWT.READ_ONLY : SWT.DROP_DOWN;

		Combo combo = new Combo(parent, style);

		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		combo.setLayoutData(data);
		return combo;
	}

	/**
	 * Helper method for creating labels.
	 */
	protected Label createLabel(Composite parent, String text) {
		Label label = new Label(parent, SWT.LEFT);
		label.setText(text);

		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		label.setLayoutData(data);
		return label;
	}

	protected Text createTextField(Composite parent, int width) {
		Text text = new Text(parent, SWT.SINGLE | SWT.READ_ONLY);

		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		data.widthHint = width;
		text.setLayoutData(data);

		return text;
	}

	/**
	 * @see org.eclipse.swt.widgets.Widget#dispose()
	 */
	public void dispose() {
		encodingCombo.removeModifyListener(comboListener);
		super.dispose();
	}

	private void fillCombo() {
		try {
			String[] ianaTags = CommonCharsetNames.getCommonCharsetNames();
			int totalNum = ianaTags.length;
			for (int i = 0; i < totalNum; i++) {
				String iana = ianaTags[i];
				String enc = CommonCharsetNames.getDisplayString(iana);

				if (enc != null) {
					encodingCombo.add(enc);
				} else {
					Logger.log(Logger.WARNING, "CommonCharsetNames.getDisplayString(" + iana + ") returned null"); //$NON-NLS-1$ //$NON-NLS-2$
					encodingCombo.add(iana);
				}
				ianaVector.add(iana);
			}
		} catch (Exception e) {
			//e.printStackTrace();
			//MessageDialog.openError(getShell(), "Resource exception",
			// "Unable to obtain encoding strings. Check resource file");
			//XMLEncodingPlugin.getPlugin().getMsgLogger().write(e.toString());
			//XMLEncodingPlugin.getPlugin().getMsgLogger().writeCurrentThread();
			Logger.log(Logger.ERROR, "Exception", e); //$NON-NLS-1$
		}
	}

	/**
	 * <code>getEncoding</code> Get the descriptive encoding name that was
	 * selected.
	 * 
	 * @return a <code>String</code> value
	 */
	public String getEncoding() {
		return encodingCombo.getText();
	}

	/**
	 * Method getEncodingCombo. Returns the combo used to display the encoding
	 * descriptions.
	 * 
	 * @return Combo
	 */
	public Combo getEncodingCombo() {
		return encodingCombo;
	}

	/**
	 * <code>getIANATag</code> Get the IANA tag equivalent of the selected
	 * descriptive encoding name
	 * 
	 * @return a <code>String</code> value
	 */
	public String getIANATag() {
		int i = encodingCombo.getSelectionIndex();
		if (i >= 0) {
			return (String) (ianaVector.elementAt(i));
		}
		return ""; //$NON-NLS-1$
	}

	protected void init(String ianaLabelStr, String encodingLabelStr) {
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		setLayout(layout);
		GridData data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		setLayoutData(data);

		encodingLabel = createLabel(this, encodingLabelStr);
		encodingCombo = createComboBox(this, true);
		ianaLabel = createLabel(this, ianaLabelStr);
		ianaText = createTextField(this, 20);
		ianaVector = new Vector();

		fillCombo();
		resetToDefaultEncoding();
		encodingCombo.addModifyListener(comboListener);
	}

	/**
	 * <code>isEncodingInList</code> Checks whether the encoding name is in
	 * the combo
	 * 
	 * @param enc
	 *            a <code>string</code> value. The encoding name.
	 * @return a <code>boolean</code> value. TRUE if encoding is in list.
	 *         FALSE if encoding is not in list.
	 */
	public boolean isEncodingInList(String enc) {
		int i = encodingCombo.indexOf(enc);
		if (i >= 0) {
			return true;
		}
		return false;
	}

	/**
	 * <code>isIANATagInList</code> Checks whether the IANA tag is in the
	 * combo
	 * 
	 * @param ianaTag
	 *            a <code>string</code> value. The IANA tag.
	 * @return a <code>boolean</code> value. TRUE if tag is in list. FALSE
	 *         if tag is not in list.
	 */
	public boolean isIANATagInList(String ianaTag) {
		int i = ianaVector.indexOf(ianaTag);
		if (i >= 0) {
			return true;
		}
		return false;
	}

	/**
	 * Method removeEntry. Removes both the description and the IANA tag at
	 * the specified index
	 * 
	 * @param index
	 */
	public void removeEntry(int index) {
		if (0 <= index && index < ianaVector.size()) {
			encodingCombo.remove(index);
			ianaVector.remove(index);
		}
	}

	/**
	 * Method resetToDefaultEncoding. Reset the control to the default
	 * encoding. Currently UTF-8
	 */
	public void resetToDefaultEncoding() {
		String defaultIANATag = "UTF-8"; //$NON-NLS-1$
		ianaText.setText(defaultIANATag);
		setIANATag(defaultIANATag);
	}

	/**
	 * Method setEnabled. Enable/disable the EncodingSettings composite.
	 * 
	 * @param enabled
	 */
	public void setEnabled(boolean enabled) {
		encodingCombo.setEnabled(enabled);
		encodingLabel.setEnabled(enabled);
		ianaLabel.setEnabled(enabled);
		ianaText.setEnabled(enabled);
	}

	/**
	 * <code>setEncoding</code> Set the selection in the combo to the
	 * descriptive encoding name.
	 * 
	 * @param enc
	 *            a <code>string</code> value. Note this is not the IANA
	 *            tag.
	 */
	public void setEncoding(String enc) {
		encodingCombo.setText(enc);
		encodingCombo.select(encodingCombo.indexOf(enc));
	}

	/**
	 * <code>setIANATag</code> Set the IANA tag for the combo
	 * 
	 * @param ianaTag
	 *            a <code>string</code> value. The IANA tag.
	 */
	public void setIANATag(String ianaTag) {
		int i = ianaVector.indexOf(ianaTag);
		if (i >= 0) {
			encodingCombo.select(i);
		}
	}

}
