/*******************************************************************************
 * 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.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.common.encoding.CommonCharsetNames;
import org.eclipse.wst.sse.ui.Logger;
import org.eclipse.wst.xml.ui.nls.ResourceHandler;


/**
 * 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 = ResourceHandler.getString("EncodingSettings.1"); //$NON-NLS-1$

	private static String IANA_LABEL = ResourceHandler.getString("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);
		}
	}

}
