/*******************************************************************************
 * 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;

	private static String IANA_LABEL = XMLUIMessages.EncodingSettings_0;

	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);
		}
	}

}
