/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.ui.dialogs;

import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jst.pagedesigner.common.dialogfield.ColorButtonDialogField;
import org.eclipse.jst.pagedesigner.common.dialogfield.DialogField;
import org.eclipse.jst.pagedesigner.common.dialogfield.IDialogFieldApplyListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.wst.css.core.internal.util.declaration.CSSPropertyContext;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

/**
 * @author mengbo
 * @version 1.5
 */
public class TextPreferencePage extends PreferencePage {
	private CSSPropertyContext _style;

	private StyleCombo _fontFamilyCombo, _fontSizeNumberCombo,
			_fontSizeUnitCombo, _fontWeightCombo, _fontStyleCombo,
			_fontVariantCombo, _fontLineHeightNumberCombo,
			_fontLineHeightUnitCombo, _textTransformCombo;

	private ColorButtonDialogField _colorField;

	private Button _textDecorationUnderlineButton,
			_textDecorationOverlineButton, _textDecorationLineThroughButton,
			_textDecorationBlinkButton, _textDecorationNoneButton;

	public TextPreferencePage(IDOMElement element, CSSPropertyContext style) {
		super();
		_style = style;

		// Set the preference store for the preference page.
		// IPreferenceStore store =
		// JMTIntegrationPlugin.getDefault().getPreferenceStore();
		// setPreferenceStore(store);
		setTitle(DialogsMessages.getString("TextPreferencePage.Title")); //$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.jface.preference.
	 *      PreferencePage#createContents(Composite)
	 */
	protected Control createContents(Composite parent) {
		GridLayout layout;
		GridData data;

		Composite top = new Composite(parent, SWT.NONE);
		layout = new GridLayout(5, false);
		data = new GridData(GridData.FILL_BOTH);
		top.setLayout(layout);
		top.setLayoutData(data);

		Label fontLabel = new Label(top, SWT.NONE);
		fontLabel.setText(DialogsMessages.getString("TextPreferencePage.Font")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		fontLabel.setLayoutData(data);

		_fontFamilyCombo = new StyleCombo(top, SWT.NONE);
		_fontFamilyCombo.setItems(IStyleConstants.FONT_FAMILY);
		data = new GridData(GridData.FILL_HORIZONTAL);
		data.horizontalSpan = 4;
		_fontFamilyCombo.setLayoutData(data);
		_fontFamilyCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				_style.setFontFamily(_fontFamilyCombo.getText());
			}
		});

		Label sizeLabel = new Label(top, SWT.NONE);
		sizeLabel.setText(DialogsMessages.getString("TextPreferencePage.Size")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		sizeLabel.setLayoutData(data);

		_fontSizeNumberCombo = new StyleCombo(top, SWT.NONE);
		_fontSizeNumberCombo.setItems(IStyleConstants.FONT_SIZE_NUMBER);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontSizeNumberCombo.setLayoutData(data);
		_fontSizeNumberCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				_fontSizeUnitCombo.setEnabled(true);
				try {
					Integer.valueOf(_fontSizeNumberCombo.getText());
				} catch (NumberFormatException ex) {
					_fontSizeUnitCombo.setEnabled(false);
				}

				String size = _fontSizeNumberCombo.getText();
				if (_fontSizeUnitCombo.isEnabled()) {
					size += _fontSizeUnitCombo.getText();
				}

				_style.setFontSize(size);
			}
		});

		_fontSizeUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
		_fontSizeUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontSizeUnitCombo.setLayoutData(data);
		_fontSizeUnitCombo.select(0);
		_fontSizeUnitCombo.setEnabled(false);
		_fontSizeUnitCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String size = _fontSizeNumberCombo.getText();
				if (_fontSizeUnitCombo.isEnabled()) {
					size += _fontSizeUnitCombo.getText();
				}

				_style.setFontSize(size);
			}
		});

		Label weightLabel = new Label(top, SWT.NONE);
		weightLabel.setText(DialogsMessages
				.getString("TextPreferencePage.Weight")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		weightLabel.setLayoutData(data);

		_fontWeightCombo = new StyleCombo(top, SWT.NONE);
		_fontWeightCombo.setItems(IStyleConstants.FONT_WEIGHT);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontWeightCombo.setLayoutData(data);
		_fontWeightCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String weight = _fontWeightCombo.getText();
				_style.setFontWeight(weight);
			}
		});

		Label stylesLabel = new Label(top, SWT.NONE);
		stylesLabel.setText(DialogsMessages
				.getString("TextPreferencePage.Style")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		stylesLabel.setLayoutData(data);

		_fontStyleCombo = new StyleCombo(top, SWT.NONE);
		_fontStyleCombo.setItems(IStyleConstants.FONT_STYLE);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontStyleCombo.setLayoutData(data);
		_fontStyleCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String style = _fontStyleCombo.getText();
				_style.setFontStyle(style);
			}
		});

		new Label(top, SWT.NONE);

		Label variantLabel = new Label(top, SWT.NONE);
		variantLabel.setText(DialogsMessages
				.getString("TextPreferencePage.Variant")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		variantLabel.setLayoutData(data);

		_fontVariantCombo = new StyleCombo(top, SWT.NONE);
		_fontVariantCombo.setItems(IStyleConstants.FONT_VARIANT);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontVariantCombo.setLayoutData(data);
		_fontVariantCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String variant = _fontVariantCombo.getText();
				_style.setFontVariant(variant);
			}
		});

		Label lineHeightLabel = new Label(top, SWT.NONE);
		lineHeightLabel.setText(DialogsMessages
				.getString("TextPreferencePage.LineHeight")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		lineHeightLabel.setLayoutData(data);

		_fontLineHeightNumberCombo = new StyleCombo(top, SWT.NONE);
		_fontLineHeightNumberCombo.setItems(IStyleConstants.NORMAL);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontLineHeightNumberCombo.setLayoutData(data);
		_fontLineHeightNumberCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				_fontLineHeightUnitCombo.setEnabled(true);
				try {
					Integer.valueOf(_fontLineHeightNumberCombo.getText());
				} catch (NumberFormatException ex) {
					_fontLineHeightUnitCombo.setEnabled(false);
				}

				String height = _fontLineHeightNumberCombo.getText();
				if (_fontLineHeightUnitCombo.isEnabled()) {
					height += _fontLineHeightUnitCombo.getText();
				}

				_style.setLineHeight(height);
			}
		});

		_fontLineHeightUnitCombo = new StyleCombo(top, SWT.READ_ONLY);
		_fontLineHeightUnitCombo.setItems(IStyleConstants.SIZE_UNIT);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_fontLineHeightUnitCombo.setLayoutData(data);
		_fontLineHeightUnitCombo.select(0);
		_fontLineHeightUnitCombo.setEnabled(false);
		_fontLineHeightUnitCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String height = _fontLineHeightNumberCombo.getText();
				if (_fontLineHeightUnitCombo.isEnabled()) {
					height += _fontLineHeightUnitCombo.getText();
				}

				_style.setLineHeight(height);
			}
		});

		Label caseLabel = new Label(top, SWT.NONE);
		caseLabel.setText(DialogsMessages.getString("TextPreferencePage.Case")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		caseLabel.setLayoutData(data);

		_textTransformCombo = new StyleCombo(top, SWT.NONE);
		_textTransformCombo.setItems(IStyleConstants.FONT_TEXTTRANSFORM);
		data = new GridData(GridData.FILL_HORIZONTAL);
		_textTransformCombo.setLayoutData(data);
		_textTransformCombo.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String textTransform = _textTransformCombo.getText();
				_style.setTextTransform(textTransform);
			}
		});

		Label decorationLabel = new Label(top, SWT.NONE);
		decorationLabel.setText(DialogsMessages
				.getString("TextPreferencePage.Decoration")); //$NON-NLS-1$
		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		decorationLabel.setLayoutData(data);

		Composite decorationComposite = new Composite(top, SWT.NONE);
		data = new GridData(GridData.FILL_HORIZONTAL);
		data.horizontalSpan = 4;
		decorationComposite.setLayoutData(data);
		layout = new GridLayout(5, true);
		layout.marginWidth = 0;
		decorationComposite.setLayout(layout);

		_textDecorationUnderlineButton = new Button(decorationComposite,
				SWT.CHECK);
		_textDecorationUnderlineButton
				.setText(IStyleConstants.TEXT_DECORATION[0]);
		_textDecorationUnderlineButton
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (_textDecorationUnderlineButton.getSelection()) {
							_textDecorationNoneButton.setSelection(false);
						}
						_style.setTextDecoration(getTextDecoration());
					}
				});

		_textDecorationOverlineButton = new Button(decorationComposite,
				SWT.CHECK);
		_textDecorationOverlineButton
				.setText(IStyleConstants.TEXT_DECORATION[1]);
		_textDecorationOverlineButton
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (_textDecorationOverlineButton.getSelection()) {
							_textDecorationNoneButton.setSelection(false);
						}
						_style.setTextDecoration(getTextDecoration());
					}
				});

		_textDecorationLineThroughButton = new Button(decorationComposite,
				SWT.CHECK);
		_textDecorationLineThroughButton
				.setText(IStyleConstants.TEXT_DECORATION[2]);
		_textDecorationLineThroughButton
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						if (_textDecorationLineThroughButton.getSelection()) {
							_textDecorationNoneButton.setSelection(false);
						}
						_style.setTextDecoration(getTextDecoration());
					}
				});

		_textDecorationBlinkButton = new Button(decorationComposite, SWT.CHECK);
		_textDecorationBlinkButton.setText(IStyleConstants.TEXT_DECORATION[3]);
		_textDecorationBlinkButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (_textDecorationBlinkButton.getSelection()) {
					_textDecorationNoneButton.setSelection(false);
				}
				_style.setTextDecoration(getTextDecoration());
			}
		});

		_textDecorationNoneButton = new Button(decorationComposite, SWT.CHECK);
		_textDecorationNoneButton.setText(IStyleConstants.TEXT_DECORATION[4]);
		_textDecorationNoneButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (_textDecorationNoneButton.getSelection()) {
					_textDecorationUnderlineButton.setSelection(false);
					_textDecorationOverlineButton.setSelection(false);
					_textDecorationLineThroughButton.setSelection(false);
					_textDecorationBlinkButton.setSelection(false);
				}
				_style.setTextDecoration(getTextDecoration());
			}
		});

		_colorField = new ColorButtonDialogField(SWT.BORDER);
		_colorField.setLabelText(DialogsMessages
				.getString("TextPreferencePage.Color"));

		data = new GridData(GridData.HORIZONTAL_ALIGN_END);
		_colorField.getLabelControl(null, top).setLayoutData(data);

		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = false;
		_colorField.getComboControl(null, top).setLayoutData(data);

		data = new GridData();
		_colorField.getChangeControl(null, top).setLayoutData(data);
		_colorField
				.setDialogFieldApplyListener(new IDialogFieldApplyListener() {
					public void dialogFieldApplied(DialogField field) {
						String color = _colorField.getText();
						_style.setColor(color);
					}
				});

		initializeControls();

		return top;
	}

	private void initializeControls() {
		// font-family
		String fontFamily = _style.getFontFamily();
		if (!isEmptyString(fontFamily)) {
			int index = _fontFamilyCombo.indexOf(fontFamily);
			if (index != -1) {
				_fontFamilyCombo.select(index);
			} else {
				_fontFamilyCombo.setText(fontFamily);
			}
		}

		// font-size
		String fontSize = _style.getFontSize();
		if (!isEmptyString(fontSize)) {
			int index = _fontSizeNumberCombo.indexOf(fontSize);
			if (index != -1) {
				_fontSizeNumberCombo.select(index);
			} else {
				_fontSizeNumberCombo.setText(fontSize);
			}
		}

		// font-weight
		String fontWeight = _style.getFontWeight();
		if (!isEmptyString(fontWeight)) {
			int index = _fontWeightCombo.indexOf(fontWeight);
			if (index != -1) {
				_fontWeightCombo.select(index);
			} else {
				_fontWeightCombo.setText(fontWeight);
			}
		}

		// font-style
		String fontStyle = _style.getFontStyle();
		if (!isEmptyString(fontStyle)) {
			int index = _fontStyleCombo.indexOf(fontStyle);
			if (index != -1) {
				_fontStyleCombo.select(index);
			} else {
				_fontStyleCombo.setText(fontStyle);
			}
		}

		// font-variant
		String fontVariant = _style.getFontVariant();
		if (!isEmptyString(fontVariant)) {
			int index = _fontVariantCombo.indexOf(fontVariant);
			if (index != -1) {
				_fontVariantCombo.select(index);
			} else {
				_fontVariantCombo.setText(fontVariant);
			}
		}

		// line-height
		String lineHeight = _style.getLineHeight();
		if (!isEmptyString(lineHeight)) {
			int index = _fontLineHeightNumberCombo.indexOf(lineHeight);
			if (index != -1) {
				_fontLineHeightNumberCombo.select(index);
			} else {
				_fontLineHeightNumberCombo.setText(lineHeight);
			}
		}

		// text-transform
		String textTransform = _style.getTextTransform();
		if (!isEmptyString(textTransform)) {
			int index = _textTransformCombo.indexOf(textTransform);
			if (index != -1) {
				_textTransformCombo.select(index);
			} else {
				_textTransformCombo.setText(textTransform);
			}
		}

		// text-decoration
		String textDecoration = _style.getTextDecoration();
		if (!isEmptyString(textDecoration)) {
			int index = textDecoration
					.indexOf(IStyleConstants.TEXT_DECORATION[0]);
			if (index != -1) {
				_textDecorationUnderlineButton.setSelection(true);
			} else {
				_textDecorationUnderlineButton.setSelection(false);
			}

			index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[1]);
			if (index != -1) {
				_textDecorationOverlineButton.setSelection(true);
			} else {
				_textDecorationOverlineButton.setSelection(false);
			}

			index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[2]);
			if (index != -1) {
				_textDecorationLineThroughButton.setSelection(true);
			} else {
				_textDecorationLineThroughButton.setSelection(false);
			}

			index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[3]);
			if (index != -1) {
				_textDecorationBlinkButton.setSelection(true);
			} else {
				_textDecorationBlinkButton.setSelection(false);
			}

			index = textDecoration.indexOf(IStyleConstants.TEXT_DECORATION[4]);
			if (index != -1) {
				_textDecorationNoneButton.setSelection(true);
			} else {
				_textDecorationNoneButton.setSelection(false);
			}
		}

		// color
		String color = _style.getColor();
		if (!isEmptyString(color)) {
			_colorField.setTextWithoutUpdate(color);
		}
	}

	private String getTextDecoration() {
		StringBuffer textDecoration = new StringBuffer();
		if (_textDecorationUnderlineButton.getSelection()) {
			textDecoration.append(_textDecorationUnderlineButton.getText())
					.append(' ');
		}
		if (_textDecorationOverlineButton.getSelection()) {
			textDecoration.append(_textDecorationOverlineButton.getText())
					.append(' ');
		}
		if (_textDecorationLineThroughButton.getSelection()) {
			textDecoration.append(_textDecorationLineThroughButton.getText())
					.append(' ');
		}
		if (_textDecorationBlinkButton.getSelection()) {
			textDecoration.append(_textDecorationBlinkButton.getText()).append(
					' ');
		}
		if (_textDecorationNoneButton.getSelection()) {
			textDecoration.append(_textDecorationNoneButton.getText()).append(
					' ');
		}

		return textDecoration.toString().trim();
	}

	public void setVisible(boolean visible) {
		super.setVisible(visible);

		getApplyButton().setVisible(false);
		getDefaultsButton().setVisible(false);
	}

	private boolean isEmptyString(String str) {
		if (str == null || str.length() == 0) {
			return true;
		} else {
			return false;
		}
	}
}
