/*
 * Copyright 2006 Maskat Project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.maskat.ide.property.descriptor;

import java.text.MessageFormat;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.maskat.ide.property.EventProperty;

public class EventPropertyDescriptor extends PropertyDescriptor {

	public static final String EVENT_ON_DISP = "on";

	public static final String EVENT_OFF_DISP = "off";

	public EventPropertyDescriptor(Object id, String displayName) {
		super(id, displayName);
	}

	public CellEditor createPropertyEditor(Composite parent) {
		ComboCellEditor editor = new ComboCellEditor(parent);
		if (getValidator() != null) {
			editor.setValidator(getValidator());
		}
		return editor;
	}

	private class ComboCellEditor extends CellEditor {

		private CCombo combo;

		private Object value;

		public ComboCellEditor(Composite parent) {
			super(parent, SWT.NONE);
			combo.add(EVENT_OFF_DISP);
			combo.add(EVENT_ON_DISP);
		}

		protected Control createControl(Composite parent) {
			combo = new CCombo(parent, SWT.READ_ONLY);
			combo.addFocusListener(new FocusAdapter() {
				public void focusLost(FocusEvent e) {
					if (isActivated()) {
						Object newValue = combo.getText();
						updateValue(newValue);
					}
				}
			});
			combo.addKeyListener(new KeyAdapter() {
				public void keyReleased(KeyEvent e) {
					if (e.character == '\u001b') { // Escape
						fireCancelEditor();
					}
				}
			});

			combo.addSelectionListener(new SelectionAdapter() {
				public void widgetDefaultSelected(SelectionEvent e) {
					Object newValue = combo.getText();
					updateValue(newValue);
				}
			});
			return combo;
		}

		private void updateValue(Object newValue) {
			if (newValue != null) {
				boolean newValidState = isCorrect(newValue);
				if (newValidState) {
					markDirty();
					doSetValue(newValue);
				} else {
					setErrorMessage(MessageFormat.format(getErrorMessage(),
							new Object[] { newValue.toString() }));
				}
				fireApplyEditorValue();
				deactivate();
			}
		}

		protected Object doGetValue() {
			return value;
		}

		protected void doSetFocus() {
			combo.setFocus();
		}

		protected void doSetValue(Object value) {
			this.value = value;
			if (value instanceof String) {
				combo.setText((String) value);
			}
			if (value instanceof EventProperty) {
				EventProperty ep = (EventProperty) value;
				if (ep.isEnable()) {
					combo.setText(EVENT_ON_DISP);
				} else {
					combo.setText(EVENT_OFF_DISP);
				}
			}
		}
	}
}
