/*******************************************************************************
 * 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.jsf.common.ui.internal.dialogfield;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.jst.jsf.common.ui.internal.utils.StyleCombo;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.forms.widgets.FormToolkit;

/**
 * This class provides a common color choice DialogFiled.
 * 
 * @author mengbo
 */
public class ColorButtonDialogField extends StyleComboDialogField {
	// color selection button
	private Button _button;

	// the button enable flag
	private boolean _buttonEnabled;

	// the current color
	private Color _color;

	// the current color RGB
	private RGB _colorValue;

	// the combo control
	private StyleCombo _combo;

	// when no color is set or selected, using the empty image
	private Image _emptyImage;

	// size of color image
	private Point _extent;

	// the color image
	private Image _image;
    
    private ColorPalette    _colorPalette;

	/**
	 * @param flags
	 * @param colorPalette
	 */
	public ColorButtonDialogField(int flags, ColorPalette colorPalette) {
		super(flags);
		_buttonEnabled = true;
        _colorPalette = colorPalette;
	}

	private void buttonPressed() {
		ColorDialog colorDialog = new ColorDialog(_button.getShell());
		colorDialog.setRGB(_colorValue);
		RGB newColor = colorDialog.open();
		if (newColor != null && !newColor.equals(_colorValue)) {
			_colorValue = newColor;
			setText(ColorPalette.getStringColor(newColor));
			updateColorImage();
		}
	}

	/**
	 * Compute the size of the image to be displayed.
	 * 
	 * @param window -
	 *            the window used to calculate
	 * @return <code>Point</code>
	 */
	private Point computeImageSize(Control window) {
		GC gc = new GC(window);
		Font f = _button.getFont();
		gc.setFont(f);
		int height = gc.getFontMetrics().getHeight();

		Point p = new Point(height * 3 - 6, height - 2);
		gc.dispose();
		return p;
	}

	private void disposeResources() {
		if (_image != null) {
			_image.dispose();
			_image = null;
		}
		if (_emptyImage != null) {
			_emptyImage.dispose();
			_emptyImage = null;
		}
		if (_color != null) {
			_color.dispose();
			_color = null;
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField#doFillIntoGrid(org.eclipse.ui.forms.widgets.FormToolkit,
	 *      org.eclipse.swt.widgets.Composite, int)
	 */
	public Control[] doFillIntoGrid(FormToolkit toolkit, Composite parent,
			int nColumns) {
		assertEnoughColumns(nColumns);

		Control requiredLabel = getRequiredLabelControl(toolkit, parent);
		requiredLabel.setLayoutData(gridDataForLabel(1));

		Control label = getLabelControl(toolkit, parent);
		label.setLayoutData(gridDataForLabel(1));

		StyleCombo combo = getComboControl(toolkit, parent);
		combo.setLayoutData(gridDataForCombo(nColumns - 3));

		_button = getChangeControl(toolkit, parent);
		_button.setLayoutData(gridDataForButton(1));

		return new Control[] { requiredLabel, label, combo, _button };
	}

	/**
	 * Sets the enable state of the button.
	 * @param enable 
	 */
	public void enableButton(boolean enable) {
		if (isOkToUse(_button)) {
			_button.setEnabled(isEnabled() && enable);
		}
		_buttonEnabled = enable;
	}

	/**
	 * Creates or returns the created buttom widget.
	 * @param toolkit 
	 * 
	 * @param parent
	 *            The parent composite or <code>null</code> if the widget has
	 *            already been created.
	 * @return  the button widget
	 */
	public Button getChangeControl(FormToolkit toolkit, Composite parent) {
		if (_button == null) {
			assertCompositeNotNull(parent);
			if (toolkit != null) {
				_button = toolkit.createButton(parent, "", SWT.PUSH); //$NON-NLS-1$
			} else {
				_button = new Button(parent, SWT.PUSH);
			}
			_button.setEnabled(isEnabled() && _buttonEnabled);

			_button.addSelectionListener(new SelectionListener() {
				public void widgetDefaultSelected(SelectionEvent e) {
					buttonPressed();
				}

				public void widgetSelected(SelectionEvent e) {
					buttonPressed();
				}
			});

			_button.addDisposeListener(new DisposeListener() {
				public void widgetDisposed(DisposeEvent event) {
					disposeResources();
				}
			});

			_extent = computeImageSize(parent);
			_image = new Image(parent.getDisplay(), _extent.x, _extent.y);
			_emptyImage = new Image(parent.getDisplay(), _extent.x, _extent.y);
			initEmptyImage(_button);
			updateColorImage();
		}

		return _button;
	}

	private String[] getColorList() {
		Map map = _colorPalette.getExtendedColorMap();
		List list = new ArrayList(map.keySet());
		Collections.sort(list);
		return (String[]) list.toArray(new String[list.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.StringDialogField#getTextControl(org.eclipse.ui.forms.widgets.FormToolkit,
	 *      org.eclipse.swt.widgets.Composite)
	 */
	public StyleCombo getComboControl(FormToolkit toolkit, Composite parent) {

		if (_combo == null) {
			_combo = super.getComboControl(toolkit, parent);

			_combo.addSelectionListener(new SelectionListener() {

				public void widgetDefaultSelected(SelectionEvent e) {
					updateImageAfterChanged();
				}

				public void widgetSelected(SelectionEvent e) {
					updateImageAfterChanged();
				}
			});
			_combo.addFocusListener(new FocusAdapter() {
				public void focusLost(FocusEvent e) {
					updateImageAfterChanged();
				}
			});
			_combo.setItems(getColorList());
		}
		return _combo;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.DialogField#getNumberOfControls()
	 */
	public int getNumberOfControls() {
		return 4;
	}
	private GridData gridDataForButton(int span) {
		GridData gd = new GridData();
		gd.horizontalAlignment = GridData.FILL;
		gd.grabExcessHorizontalSpace = false;
		gd.horizontalSpan = span;
		gd.widthHint = LayoutUtil.getButtonWidthHint(_button);
		gd.heightHint = _combo.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
		return gd;
	}

	private void initEmptyImage(Control parent) {
		Color transparentColor = parent.getForeground();
		ImageData imageData = _emptyImage.getImageData();
		imageData.transparentPixel = 0;
		GC gc = new GC(_emptyImage);
		gc.setBackground(transparentColor);
		gc.fillRectangle(0, 0, _emptyImage.getBounds().width, _emptyImage
				.getBounds().height);
	}

	/**
	 * Set the current color value and update the control.
	 * 
	 * @param rgb
	 *            The new color.
	 */
	public void setColorValue(RGB rgb) {
		_colorValue = rgb;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.jsf.common.ui.internal.dialogfield.ComboDialogField#setTextWithoutUpdate(java.lang.String)
	 */
	public void setTextWithoutUpdate(String text) {
		super.setTextWithoutUpdate(text);
		updateImageAfterChanged();
	}

	/**
	 * Update the image being displayed on the button using the current color
	 * setting.
	 */
	protected void updateColorImage() {
		if (_button.isDisposed()) {
			return;
		}

		if (_colorValue == null) {
			_button.setImage(_emptyImage);
			return;
		}

		Display display = _button.getDisplay();
		GC gc = new GC(_image);
		gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
		gc.drawRectangle(0, 0, _extent.x - 1, _extent.y - 1);
		if (_color != null) {
			_color.dispose();
		}
		_color = new Color(display, _colorValue);
		gc.setBackground(_color);
		gc.fillRectangle(1, 1, _extent.x - 2, _extent.y - 2);
		gc.dispose();
		_button.setImage(_image);
	}

	/*
	 * @see DialogField#updateEnableState
	 */
	protected void updateEnableState() {
		super.updateEnableState();
		if (isOkToUse(_button)) {
			_button.setEnabled(isEnabled() && _buttonEnabled);
		}
	}

	private void updateImageAfterChanged() {
		String newColor = getText().trim();
		setColorValue(_colorPalette.getExtendedColorRGB(newColor));
		updateColorImage();
	}
}
