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

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.maskat.framework.IBasicDefVisitor;
import org.maskat.framework.eventdef.Component;
import org.maskat.framework.eventdef.Event;
import org.maskat.framework.screendef.ButtonDef;
import org.maskat.framework.screendef.CheckboxDef;
import org.maskat.framework.screendef.CodeLibDef;
import org.maskat.framework.screendef.ComboDef;
import org.maskat.framework.screendef.ComboItemDef;
import org.maskat.framework.screendef.DivHtmlDef;
import org.maskat.framework.screendef.DivSplitDef;
import org.maskat.framework.screendef.FrameDef;
import org.maskat.framework.screendef.GridCellComboDef;
import org.maskat.framework.screendef.GridDef;
import org.maskat.framework.screendef.GridHeaderDef;
import org.maskat.framework.screendef.IComponentDef;
import org.maskat.framework.screendef.ImageDef;
import org.maskat.framework.screendef.LabelDef;
import org.maskat.framework.screendef.PopupDef;
import org.maskat.framework.screendef.RadioDef;
import org.maskat.framework.screendef.RadioGroupDef;
import org.maskat.framework.screendef.RadioMemberDef;
import org.maskat.framework.screendef.SplitterDef;
import org.maskat.framework.screendef.TabFolderDef;
import org.maskat.framework.screendef.TabItemDef;
import org.maskat.framework.screendef.TextDef;
import org.maskat.framework.screendef.TreeNodeDef;
import org.maskat.framework.screendef.TreeViewDef;
import org.maskat.framework.screendef.customize.CustCompPropDescKey;
import org.maskat.framework.screendef.customize.IPluginComponentDef;
import org.maskat.framework.screendef.customize.PluginDefFactory;
import org.maskat.framework.screendef.customize.PluginDefUnavailableException;
import org.maskat.framework.screendef.customize.PropertyPluginConfig;
import org.maskat.ide.MaskatIDEPlugin;
import org.maskat.ide.gef.models.TabDef;
import org.maskat.ide.property.descriptor.EventPropertyDescriptor;
import org.maskat.ide.property.descriptor.IPropertyIDConstants;
import org.maskat.ide.property.descriptor.PropDescriptors;

/**
 * 画面XML情報とイベント定義XML情報両方持っている
 * 
 * @author shengshen
 * 
 */
public class ComponentProperty extends Component implements IPropertySource,
		IPropertyIDConstants {

	// 基本的に画面のコンポーネントと対応するが、GridHeaderDefとかにも対応するためにObject
	private Object componentDef;

	public ComponentProperty() {
	}

	public Object getEditableValue() {
		return this;
	}

	public void setComponentDef(Object componentDef) {
		this.componentDef = componentDef;
	}

	public IPropertyDescriptor[] getPropertyDescriptors() {
		IPropertyDescriptor[] propDescs = localGetPropertyDescriptors();
		for (int i = 0; i < propDescs.length; i++) {
			IPropertyDescriptor propDesc = propDescs[i];
			if (propDesc == PropDescriptors.getInst().getNamePropDesc()) {
				PropertyDescriptor nameDesc = (PropertyDescriptor) propDesc;
				nameDesc.setValidator(new ICellEditorValidator() {
					public String isValid(Object value) {
						if (value == null || "".equals(((String) value).trim())) {
							String errorMsg = "コンポーネントname属性を入力してください。";
							WorkbenchWindow win = (WorkbenchWindow) PlatformUI
									.getWorkbench().getActiveWorkbenchWindow();
							win.getStatusLineManager().setErrorMessage(errorMsg);
							// TODO return errorMsgだけではエラーメッセージ表示されないから
							// ですから、ここでわざとstatuslineにエラーメッセージ表示

							return errorMsg;
						}

						final String compName = (String) value;
						IComponentDef compDef = (IComponentDef) componentDef;

						RepeatedNameVisitor visitor = new RepeatedNameVisitor(compDef,
								compName);
						compDef.getLayoutDef().accept(visitor);
						if (visitor.nameConflict) {
							String errorMsg = "コンポーネント名(" + compName + ")は重複しています。 ";
							WorkbenchWindow win = (WorkbenchWindow) PlatformUI
									.getWorkbench().getActiveWorkbenchWindow();
							win.getStatusLineManager().setErrorMessage(errorMsg);
							// TODO return errorMsgだけではエラーメッセージ表示されないから
							// ですから、ここでわざとstatuslineにエラーメッセージ表示

							return errorMsg;
						}
						return null;
					}
				});
				break;
			}
		}
		return propDescs;
	}

	private IPropertyDescriptor[] localGetPropertyDescriptors() {
		// componentDefのclassより、PropertyDescriptor[]を決める

		if (componentDef instanceof IPluginComponentDef) {
			return PluginDefFactory.getPropDescs(((IPluginComponentDef) componentDef)
					.getProxy().getNodeName());
		}
		if (componentDef instanceof LabelDef) {
			return PropDescriptors.getInst().LABEL_PROPDESC;
		}
		if (componentDef instanceof ButtonDef) {
			return PropDescriptors.getInst().BUTTON_PROPDESC;
		}
		if (componentDef instanceof FrameDef) {
			return PropDescriptors.getInst().FRAME_PROPDESC;
		}
		if (componentDef instanceof ImageDef) {
			return PropDescriptors.getInst().IMAGE_PROPDESC;
		}
		if (componentDef instanceof TextDef) {
			return PropDescriptors.getInst().TEXT_PROPDESC;
		}
		if (componentDef instanceof RadioDef) {
			return PropDescriptors.getInst().RADIO_PROPDESC;
		}
		if (componentDef instanceof CheckboxDef) {
			return PropDescriptors.getInst().CHECKBOX_PROPDESC;
		}
		if (componentDef instanceof ComboDef) {
			return PropDescriptors.getInst().COMBO_PROPDESC;
		}
		if (componentDef instanceof GridDef) {
			return PropDescriptors.getInst().GRID_PROPDESC;
		}
		if (componentDef instanceof GridHeaderDef) {
			return PropDescriptors.getInst().GRIDHEADER_PROPDESC;
		}
		if (componentDef instanceof TreeViewDef) {
			return PropDescriptors.getInst().TREEVIEW_PROPDESC;
		}
		if (componentDef instanceof SplitterDef) {
			return PropDescriptors.getInst().SPLITTER_PROPDESC;
		}
		if (componentDef instanceof DivSplitDef) {
			return PropDescriptors.getInst().DIVSPLIT_PROPDESC;
		}
		if (componentDef instanceof TabFolderDef) {
			return PropDescriptors.getInst().TABFOLDER_PROPDESC;
		}
		if (componentDef instanceof TabDef) {
			return PropDescriptors.getInst().TABITEM_PROPDESC;
		}
		if (componentDef instanceof CodeLibDef) {
			return PropDescriptors.getInst().CODELIB_PROPDESC;
		}
		if (componentDef instanceof DivHtmlDef) {
			return PropDescriptors.getInst().DIVHTML_PROPDESC;
		}
		if (componentDef instanceof ComboItemDef) {
			return PropDescriptors.getInst().COMBOITEM_PROPDESC;
		}
		if (componentDef instanceof PopupDef) {
			return PropDescriptors.getInst().POPUP_PROPDESC;
		}
		if (componentDef instanceof TreeNodeDef) {
			return PropDescriptors.getInst().TREENODE_PROPDESC;
		}

		return PropDescriptors.getInst().COMMON_PROPERTYDESC_ARRAY;
	}

	public Object getPropertyValue(Object id) {
		if (PROP_LEFT.equals(id)) {
			if (componentDef instanceof IComponentDef)
				return Integer.toString(((IComponentDef) componentDef).getLeft());
		}
		if (PROP_TOP.equals(id)) {
			if (componentDef instanceof IComponentDef)
				return Integer.toString(((IComponentDef) componentDef).getTop());
		}
		if (PROP_WIDTH.equals(id)) {
			if (componentDef instanceof IComponentDef)
				return Integer.toString(((IComponentDef) componentDef).getWidth());
		}
		if (PROP_HEIGHT.equals(id)) {
			if (componentDef instanceof IComponentDef)
				return Integer.toString(((IComponentDef) componentDef).getHeight());
		}
		if (PROP_NAME.equals(id)) {
			if (componentDef instanceof IComponentDef)
				return ((IComponentDef) componentDef).getName();
			if (componentDef instanceof TabDef)
				return ((TabDef) componentDef).getName();
		}
		if (PROP_TEXT.equals(id)) {
			if (componentDef instanceof ButtonDef) {
				return ((ButtonDef) componentDef).getTitle();
			}
			if (componentDef instanceof LabelDef) {
				return ((LabelDef) componentDef).getText();
			}
		}
		if (PROP_TABINDEX.equals(id)) {
			if (componentDef instanceof IComponentDef) {
				return ((IComponentDef) componentDef).getTabIndex();
			}
		}

		if (componentDef instanceof FrameDef) {
			FrameDef theDef = (FrameDef) componentDef;
			if (PROP_TITLE.equals(id))
				return theDef.getTitle();
			if (PROP_POSITION.equals(id))
				return theDef.getPosition();
			if (PROP_DRAGGABLE.equals(id))
				return theDef.getDraggable();
			if (PROP_AUTORESIZEPARENT.equals(id))
				return theDef.getAutoResizeParent();
			if (PROP_DYNAMIC.equals(id))
				return theDef.getDynamic();
			if (PROP_PRINTTITLE.equals(id))
				return theDef.getPrintTitle();
			if (PROP_AUTORESIZECONTENU.equals(id))
				return theDef.getAutoResizeContenu();
			if (PROP_BOOLPRINT.equals(id))
				return theDef.getBoolPrint();
			if (PROP_BOOLMAXI.equals(id))
				return theDef.getBoolMaxi();
		}
		if (componentDef instanceof SplitterDef) {
			SplitterDef theDef = (SplitterDef) componentDef;
			if (PROP_ORIENTATION.equals(id))
				return theDef.getOrientation();
			if (PROP_STYLE.equals(id))
				return theDef.getStyle();
			if (PROP_PROP.equals(id))
				return theDef.getProp();
			if (PROP_LIMINF.equals(id))
				return theDef.getLimInf();
			if (PROP_LIMSUP.equals(id))
				return theDef.getLimSup();
			if (PROP_WITHIMG.equals(id))
				return theDef.getWithImg();
			if (PROP_REVERSECLOSE.equals(id))
				return theDef.getReverseClose();
			if (PROP_AUTORESIZEPARENT.equals(id))
				return theDef.getAutoResizeParent();
			if (PROP_AUTORESIZABLEH.equals(id))
				return theDef.getAutoResizableH();
			if (PROP_AUTORESIZABLEW.equals(id))
				return theDef.getAutoResizableW();
			if (PROP_TAILLECURS.equals(id))
				return theDef.getTailleCurs();
			if (PROP_AUTORESIZECONTENU.equals(id))
				return theDef.getAutoResizeContenu();
			if (PROP_OVERFLOW.equals(id))
				return theDef.getOverflow();
			if (PROP_MODELIM.equals(id))
				return theDef.getModeLim();
		}
		if (componentDef instanceof DivSplitDef) {
			DivSplitDef theDef = (DivSplitDef) componentDef;
			if (PROP_BACKGROUNDCOLOR.equals(id))
				return theDef.getBackgroundColor();
		}
		if (componentDef instanceof TabFolderDef) {
			TabFolderDef theDef = (TabFolderDef) componentDef;
			if (PROP_WIDTHTABNAME.equals(id))
				return theDef.getWidthTabName();
			if (PROP_NOACTIVETAB.equals(id))
				return theDef.getNoActiveTab();
			if (PROP_AUTOREDIMTAB.equals(id))
				return theDef.getAutoRedimTab();
			if (PROP_AUTORESIZEPARENT.equals(id))
				return theDef.getAutoResizeParent();
			if (PROP_DRAGGABLEITEM.equals(id))
				return theDef.getDraggableItem();
			if (PROP_ISCLOSABLE.equals(id))
				return theDef.getIsClosable();
			if (PROP_AUTORESIZECONTENU.equals(id))
				return theDef.getAutoResizeContenu();
		}
		if (componentDef instanceof TabItemDef) {
			TabItemDef theDef = (TabItemDef) componentDef;
			if (PROP_TITLE.equals(id))
				return theDef.getTitle();
			if (PROP_NAME.equals(id))
				return theDef.getName();
		}
		if (componentDef instanceof TabDef) {
			TabDef theDef = (TabDef) componentDef;
			if (PROP_TITLE.equals(id))
				return theDef.getTitle();
		}
		if (componentDef instanceof ImageDef) {
			ImageDef theDef = (ImageDef) componentDef;
			if (PROP_ALTERNATETEXT.equals(id))
				return theDef.getAlternateText();
			if (PROP_IMAGEON.equals(id))
				return theDef.getImageOn();
			if (PROP_IMAGEOUT.equals(id))
				return theDef.getImageOut();
			if (PROP_IMAGEDISABLED.equals(id))
				return theDef.getImageDisabled();
			if (PROP_BOOLFLOATLEFT.equals(id))
				return theDef.getBoolFloatLeft();
			if (PROP_BOOLFLOATRIGHT.equals(id))
				return theDef.getBoolFloatRight();
		}
		if (componentDef instanceof LabelDef) {
			LabelDef theDef = (LabelDef) componentDef;
			if (PROP_CLASSNAME.equals(id))
				return theDef.getClassName();
		}
		if (componentDef instanceof TextDef) {
			TextDef theDef = (TextDef) componentDef;
			if (PROP_DATATYPE.equals(id))
				return theDef.getDatatype();
			if (PROP_ISREQUIRED.equals(id))
				return theDef.getIsRequired();
			if (PROP_DISABLE.equals(id))
				return theDef.getDisable();
			if (PROP_AUTOUP.equals(id))
				return theDef.getAutoUp();
			if (PROP_ROWS.equals(id))
				return theDef.getRows();
			if (PROP_INITVALUE.equals(id))
				return theDef.getInitValue();
			if (PROP_ACCESSKEY.equals(id))
				return theDef.getAccessKey();
			if (PROP_NBCHAR.equals(id))
				return theDef.getNbchar();
		}
		if (componentDef instanceof CodeLibDef) {
			CodeLibDef theDef = (CodeLibDef) componentDef;
			if (PROP_URL.equals(id))
				return theDef.getUrl();
			if (PROP_BOOLWITHLABEL.equals(id))
				return theDef.getBoolWithLabel();
			if (PROP_ARRVALUE.equals(id))
				return theDef.getArrValue();
			if (PROP_SUBMITONLOAD.equals(id))
				return theDef.getSubmitOnload();
			if (PROP_ALWAYSREFRESH.equals(id))
				return theDef.getAlwaysRefresh();
			if (PROP_CODEWIDTH.equals(id))
				return theDef.getCodeWidth();
		}
		if (componentDef instanceof ButtonDef) {
			ButtonDef theDef = (ButtonDef) componentDef;
			if (PROP_TITLE.equals(id))
				return theDef.getTitle();
			if (PROP_ALT.equals(id))
				return theDef.getAlt();
			if (PROP_ENABLE.equals(id))
				return theDef.getEnable();
		}
		if (componentDef instanceof RadioDef) {
			RadioDef theDef = (RadioDef) componentDef;
			if (PROP_TEXT.equals(id))
				return theDef.getText();
			if (PROP_CLASSNAME.equals(id))
				return theDef.getClassName();
			if (PROP_GROUP.equals(id))
				return theDef.getGroup();
			if (PROP_CHECKED.equals(id))
				return theDef.getChecked();
		}
		if (componentDef instanceof CheckboxDef) {
			CheckboxDef theDef = (CheckboxDef) componentDef;
			if (PROP_TEXT.equals(id))
				return theDef.getText();
			if (PROP_CLASSNAME.equals(id))
				return theDef.getClassName();
			if (PROP_CHECKED.equals(id))
				return theDef.getChecked();
		}
		if (componentDef instanceof ComboDef) {
			ComboDef theDef = (ComboDef) componentDef;
			if (PROP_HEIGHTITEM.equals(id))
				return theDef.getHeightItem();
			if (PROP_ENABLE.equals(id))
				return theDef.getEnable();
			if (PROP_TABDATA.equals(id))
				return theDef.getTabData();
			if (PROP_SUGGEST.equals(id))
				return theDef.getSuggest();
		}
		if (componentDef instanceof ComboItemDef) {
			ComboItemDef theDef = (ComboItemDef) componentDef;
			if (PROP_TEXT.equals(id))
				return theDef.getText();
			if (PROP_VALUE.equals(id))
				return theDef.getValue();
		}
		if (componentDef instanceof GridDef) {
			GridDef theDef = (GridDef) componentDef;
			if (PROP_RANG.equals(id))
				return theDef.getRang();
			if (PROP_LINEHEIGHT.equals(id))
				return theDef.getLineHeight();
			if (PROP_MULTISELECT.equals(id))
				return theDef.getMultiSelect();
			if (PROP_ACTIFCLIC.equals(id))
				return theDef.getActifClic();
			if (PROP_CELLACTIVE.equals(id))
				return theDef.getCellActive();
			if (PROP_BNAVIG.equals(id))
				return theDef.getBNavig();
			if (PROP_BOOLPRINT.equals(id))
				return theDef.getBoolPrint();
			if (PROP_AUTORESIZEPARENT.equals(id))
				return theDef.getAutoResizeParent();
			if (PROP_SWITCHABLE.equals(id))
				return theDef.getSwitchable();
			if (PROP_WRITABLE.equals(id))
				return theDef.getWritable();
			if (PROP_WIDTHLASTCELL.equals(id))
				return theDef.getWidthLastCell();
			if (PROP_SORTABLE.equals(id))
				return theDef.getSortable();
			if (PROP_TABENTETE.equals(id))
				return theDef.getTabEntete();
			if (PROP_PRINTTITLE.equals(id))
				return theDef.getPrintTitle();
			if (PROP_AUTORESIZECONTENU.equals(id))
				return theDef.getAutoResizeContenu();
			if (PROP_TABTYPECOL.equals(id))
				return theDef.getTabTypeCol();
		}
		if (componentDef instanceof GridHeaderDef) {
			GridHeaderDef theDef = (GridHeaderDef) componentDef;
			if (PROP_TITLE.equals(id))
				return theDef.getTitle();
			if (PROP_TYPE.equals(id))
				return theDef.getType();
			if (PROP_WIDTH.equals(id))
				return theDef.getWidth();
			/*
			 * if (PROP_GRIDCOMBO.equals(id)) return new
			 * ChildAppendableProperty(theDef, GridCellComboDef.class,
			 * "gridCellCombo");
			 */
		}
		if (componentDef instanceof TreeViewDef) {
			TreeViewDef theDef = (TreeViewDef) componentDef;
			if (PROP_BOOLSELACTIVE.equals(id))
				return theDef.getBoolSelActive();
			if (PROP_WITHROOT.equals(id))
				return theDef.getWithRoot();
			if (PROP_ROOTOPEN.equals(id))
				return theDef.getRootOpen();
			if (PROP_WITHT.equals(id))
				return theDef.getWithT();
			if (PROP_AUTORESIZABLEH.equals(id))
				return theDef.getAutoResizableH();
			if (PROP_AUTORESIZABLEW.equals(id))
				return theDef.getAutoResizableW();
			if (PROP_DRAGGABLENODE.equals(id))
				return theDef.getDraggableNode();
			if (PROP_ROOTNODE.equals(id))
				return theDef.getRootNode();
		}
		if (componentDef instanceof DivHtmlDef) {
			DivHtmlDef theDef = (DivHtmlDef) componentDef;
			if (PROP_POSITION.equals(id))
				return theDef.getPosition();
			if (PROP_CLASSNAME.equals(id))
				return theDef.getClassName();
			if (PROP_HTML.equals(id))
				return theDef.getHtml();
		}
		if (componentDef instanceof PopupDef) {
			PopupDef theDef = (PopupDef) componentDef;
			if (PROP_TITLE.equals(id))
				return theDef.getTitle();
			if (PROP_CONTENU.equals(id))
				return theDef.getContenu();
			if (PROP_MODECONTAINER.equals(id))
				return theDef.getModeContainer();
			if (PROP_BSANSBTONCLOSE.equals(id))
				return theDef.getBSansBtonClose();
			if (PROP_SUFFFOND.equals(id))
				return theDef.getSuffFond();
		}
		if (componentDef instanceof TreeNodeDef) {
			TreeNodeDef theDef = (TreeNodeDef) componentDef;
			if (PROP_STEXT.equals(id))
				return theDef.getSText();
			if (PROP_SICON.equals(id))
				return theDef.getSIcon();
			if (PROP_SICON2.equals(id))
				return theDef.getSIcon2();
			if (PROP_OPEN.equals(id))
				return theDef.getOpen();
			if (PROP_RELOAD.equals(id))
				return theDef.getReload();
			if (PROP_URL.equals(id))
				return theDef.getUrl();
			if (PROP_TYPEINFO.equals(id))
				return theDef.getTypeInfo();
			if (PROP_ONCLICKATTR.equals(id))
				return theDef.getOnclick();
		}

		boolean isEventProperty = false;
		String eventId = null;// String like onclick,onblur....
		if (componentDef instanceof IPluginComponentDef) {
			IPluginComponentDef theDef = (IPluginComponentDef) componentDef;
			CustCompPropDescKey theId = (CustCompPropDescKey) id;
			try {
				PropertyPluginConfig propConfig = PluginDefFactory.getPropConfig(theId
						.getCompNodeName(), theId.getPropName());
				isEventProperty = propConfig.isEventProp();
				eventId = propConfig.getName();
			} catch (PluginDefUnavailableException e) {
				MaskatIDEPlugin.getDefault().getLog().log(
						new Status(IStatus.ERROR, MaskatIDEPlugin.PLUGIN_ID,
								IStatus.ERROR, e.getMessage(), e));
				return null;
			}
			if (!isEventProperty)
				return theDef.getAttribute(theId.getPropName());
			// If it is not a event property, get the property from the
			// PluginComponentDef.
		}
		if (PropDescriptors.getInst().isEventPropID(id)) {
			isEventProperty = true;
			eventId = PropDescriptors.getInst().getEventID(id);
		}

		if (isEventProperty == true) {
			Event evtProperty = findEvent(eventId);
			if (evtProperty != null) {
				if (evtProperty.isEnable())
					return evtProperty;
				return String.valueOf(evtProperty);
			}
			return EventPropertyDescriptor.EVENT_OFF_DISP;
		}
		return null;
	}

	public boolean isPropertySet(Object id) {
		return false;
	}

	public void resetPropertyValue(Object id) {
	}

	public void setPropertyValue(Object id, Object value) {

		if (PROP_LEFT.equals(id)) {
			if (componentDef instanceof IComponentDef)
				((IComponentDef) componentDef).setLeft(Integer.parseInt((String) value));
		}
		if (PROP_TOP.equals(id)) {
			if (componentDef instanceof IComponentDef)
				((IComponentDef) componentDef).setTop(Integer.parseInt((String) value));
		}
		if (PROP_WIDTH.equals(id)) {
			if (componentDef instanceof IComponentDef)
				((IComponentDef) componentDef).setWidth(Integer.parseInt((String) value));
		}
		if (PROP_HEIGHT.equals(id)) {
			if (componentDef instanceof IComponentDef)
				((IComponentDef) componentDef)
						.setHeight(Integer.parseInt((String) value));
		}
		if (PROP_TEXT.equals(id)) {
			if (componentDef instanceof LabelDef) {
				((LabelDef) componentDef).setText((String) value);
			}
		}

		// イベントプロパティであるかどうか
		boolean isEventProperty = false;
		if (value instanceof EventProperty) {
			// EventPropertyのgetEditableValueメソッドを参考してください
			// そこはString値を戻るから、この分岐をたどることはないはずです。
			// isEventProperty = true;
			// UNDOの対応：
			// on->offに設定すると、SetValueCommandにgetPropertyValue()の戻り値が記録される(EventPropertyオブジェクト)
			// undoの際、このEventPropertyオブジェクトはsetPropertyValueのvalueパラメータとして渡される
			// eventEnable = ((EventProperty) value).isEnable();
			// throw new IllegalArgumentException("eventEnable:" + eventEnable);
		}
		String eventId = null;
		if (value instanceof String && PropDescriptors.getInst().isEventPropID(id)) {
			isEventProperty = true;
			eventId = PropDescriptors.getInst().getEventID(id);
		}
		if (componentDef instanceof IPluginComponentDef) {
			CustCompPropDescKey theId = (CustCompPropDescKey) id;
			try {
				PropertyPluginConfig propConfig = PluginDefFactory.getPropConfig(theId
						.getCompNodeName(), theId.getPropName());
				isEventProperty = propConfig.isEventProp();
				// If id is the event property for customize component.
				eventId = propConfig.getName();
			} catch (PluginDefUnavailableException e) {
				MaskatIDEPlugin.getDefault().getLog().log(
						new Status(IStatus.ERROR, MaskatIDEPlugin.PLUGIN_ID,
								IStatus.ERROR, e.getMessage(), e));
				return;
			}
		}

		if (isEventProperty) {
			// イベントはenableにするかどうか
			boolean eventEnable = EventPropertyDescriptor.EVENT_ON_DISP.equals(value);
			Event event = findEvent(eventId);
			// if (event != null && !(event instanceof EventProperty)) {
			// throw new
			// IllegalArgumentException("eventのタイプはEventPropertyではありません。");
			// }
			// EventProperty evtProperty = (EventProperty) event;
			if (event == null) {
				event = new Event();
				event.setId(eventId);
				event.addChild(new ParamProperty());
				event.addChild(new ResultProperty());

				addChild(event);
			}
			event.setEnable(eventEnable);
			return;// the following operation has nothing to do with
			// eventProperty, so return.
		}

		if (PROP_NAME.equals(id)) {
			setId((String) value);
			if (componentDef instanceof IComponentDef)
				((IComponentDef) componentDef).setName((String) value);
			if (componentDef instanceof TabDef)
				((TabDef) componentDef).setName((String) value);
		}
		if (PROP_TABINDEX.equals(id)) {
			if (componentDef instanceof IComponentDef)
				((IComponentDef) componentDef).setTabIndex((String) value);
		}

		if (componentDef instanceof FrameDef) {
			FrameDef theDef = (FrameDef) componentDef;
			if (PROP_TITLE.equals(id))
				theDef.setTitle((String) value);
			if (PROP_POSITION.equals(id))
				theDef.setPosition((String) value);
			if (PROP_DRAGGABLE.equals(id))
				theDef.setDraggable((String) value);
			if (PROP_AUTORESIZEPARENT.equals(id))
				theDef.setAutoResizeParent((String) value);
			if (PROP_DYNAMIC.equals(id))
				theDef.setDynamic((String) value);
			if (PROP_PRINTTITLE.equals(id))
				theDef.setPrintTitle((String) value);
			if (PROP_AUTORESIZECONTENU.equals(id))
				theDef.setAutoResizeContenu((String) value);
			if (PROP_BOOLPRINT.equals(id))
				theDef.setBoolPrint((String) value);
			if (PROP_BOOLMAXI.equals(id))
				theDef.setBoolMaxi((String) value);
		}
		if (componentDef instanceof SplitterDef) {
			SplitterDef theDef = (SplitterDef) componentDef;
			if (PROP_ORIENTATION.equals(id))
				theDef.setOrientation((String) value);
			if (PROP_STYLE.equals(id))
				theDef.setStyle((String) value);
			if (PROP_PROP.equals(id))
				theDef.setProp((String) value);
			if (PROP_LIMINF.equals(id))
				theDef.setLimInf((String) value);
			if (PROP_LIMSUP.equals(id))
				theDef.setLimSup((String) value);
			if (PROP_WITHIMG.equals(id))
				theDef.setWithImg((String) value);
			if (PROP_REVERSECLOSE.equals(id))
				theDef.setReverseClose((String) value);
			if (PROP_AUTORESIZEPARENT.equals(id))
				theDef.setAutoResizeParent((String) value);
			if (PROP_AUTORESIZABLEH.equals(id))
				theDef.setAutoResizableH((String) value);
			if (PROP_AUTORESIZABLEW.equals(id))
				theDef.setAutoResizableW((String) value);
			if (PROP_TAILLECURS.equals(id))
				theDef.setTailleCurs((String) value);
			if (PROP_AUTORESIZECONTENU.equals(id))
				theDef.setAutoResizeContenu((String) value);
			if (PROP_OVERFLOW.equals(id))
				theDef.setOverflow((String) value);
			if (PROP_MODELIM.equals(id))
				theDef.setModeLim((String) value);
		}
		if (componentDef instanceof DivSplitDef) {
			DivSplitDef theDef = (DivSplitDef) componentDef;
			if (PROP_BACKGROUNDCOLOR.equals(id))
				theDef.setBackgroundColor((String) value);
		}
		if (componentDef instanceof TabFolderDef) {
			TabFolderDef theDef = (TabFolderDef) componentDef;
			if (PROP_WIDTHTABNAME.equals(id))
				theDef.setWidthTabName((String) value);
			if (PROP_NOACTIVETAB.equals(id))
				theDef.setNoActiveTab((String) value);
			if (PROP_AUTOREDIMTAB.equals(id))
				theDef.setAutoRedimTab((String) value);
			if (PROP_AUTORESIZEPARENT.equals(id))
				theDef.setAutoResizeParent((String) value);
			if (PROP_DRAGGABLEITEM.equals(id))
				theDef.setDraggableItem((String) value);
			if (PROP_ISCLOSABLE.equals(id))
				theDef.setIsClosable((String) value);
			if (PROP_AUTORESIZECONTENU.equals(id))
				theDef.setAutoResizeContenu((String) value);
		}
		if (componentDef instanceof TabItemDef) {
			TabItemDef theDef = (TabItemDef) componentDef;
			if (PROP_TITLE.equals(id))
				theDef.setTitle((String) value);
		}
		if (componentDef instanceof ImageDef) {
			ImageDef theDef = (ImageDef) componentDef;
			if (PROP_ALTERNATETEXT.equals(id))
				theDef.setAlternateText((String) value);
			if (PROP_IMAGEON.equals(id))
				theDef.setImageOn((String) value);
			if (PROP_IMAGEOUT.equals(id))
				theDef.setImageOut((String) value);
			if (PROP_IMAGEDISABLED.equals(id))
				theDef.setImageDisabled((String) value);
			if (PROP_BOOLFLOATLEFT.equals(id))
				theDef.setBoolFloatLeft((String) value);
			if (PROP_BOOLFLOATRIGHT.equals(id))
				theDef.setBoolFloatRight((String) value);
		}
		if (componentDef instanceof LabelDef) {
			LabelDef theDef = (LabelDef) componentDef;
			if (PROP_CLASSNAME.equals(id))
				theDef.setClassName((String) value);
		}
		if (componentDef instanceof TextDef) {
			TextDef theDef = (TextDef) componentDef;
			if (PROP_DATATYPE.equals(id))
				theDef.setDatatype((String) value);
			if (PROP_ISREQUIRED.equals(id))
				theDef.setIsRequired((String) value);
			if (PROP_DISABLE.equals(id))
				theDef.setDisable((String) value);
			if (PROP_AUTOUP.equals(id))
				theDef.setAutoUp((String) value);
			if (PROP_ROWS.equals(id))
				theDef.setRows((String) value);
			if (PROP_INITVALUE.equals(id))
				theDef.setInitValue((String) value);
			if (PROP_ACCESSKEY.equals(id))
				theDef.setAccessKey((String) value);
			if (PROP_NBCHAR.equals(id))
				theDef.setNbchar((String) value);
		}
		if (componentDef instanceof CodeLibDef) {
			CodeLibDef theDef = (CodeLibDef) componentDef;
			if (PROP_URL.equals(id))
				theDef.setUrl((String) value);
			if (PROP_BOOLWITHLABEL.equals(id))
				theDef.setBoolWithLabel((String) value);
			if (PROP_ARRVALUE.equals(id))
				theDef.setArrValue((String) value);
			if (PROP_SUBMITONLOAD.equals(id))
				theDef.setSubmitOnload((String) value);
			if (PROP_ALWAYSREFRESH.equals(id))
				theDef.setAlwaysRefresh((String) value);
			if (PROP_CODEWIDTH.equals(id))
				theDef.setCodeWidth((String) value);
		}
		if (componentDef instanceof ButtonDef) {
			ButtonDef theDef = (ButtonDef) componentDef;
			if (PROP_TITLE.equals(id))
				theDef.setTitle((String) value);
			if (PROP_ALT.equals(id))
				theDef.setAlt((String) value);
			if (PROP_ENABLE.equals(id))
				theDef.setEnable((String) value);
		}
		if (componentDef instanceof RadioDef) {
			RadioDef theDef = (RadioDef) componentDef;
			if (PROP_TEXT.equals(id))
				theDef.setText((String) value);
			if (PROP_CLASSNAME.equals(id))
				theDef.setClassName((String) value);
			if (PROP_GROUP.equals(id)) {
				// TODO sync group tabIndex(set tabIndex according to the group)
				theDef.getLayoutDef().removeRadioMemberFromGroup(theDef.getGroup(),
						theDef.getName());
				if (value != null) {
					RadioGroupDef rgd = theDef.getLayoutDef().findRadioGroupDef(
							(String) value);
					if (rgd == null)
						rgd = theDef.getLayoutDef().createRadioGroupDef((String) value);

					RadioMemberDef rmd = new RadioMemberDef();
					rmd.setRef(theDef.getName());
					rgd.addChild(rmd);
				}

				theDef.setGroup((String) value);
			}
			if (PROP_CHECKED.equals(id))
				theDef.setChecked((String) value);
		}
		if (componentDef instanceof CheckboxDef) {
			CheckboxDef theDef = (CheckboxDef) componentDef;
			if (PROP_TEXT.equals(id))
				theDef.setText((String) value);
			if (PROP_CLASSNAME.equals(id))
				theDef.setClassName((String) value);
			if (PROP_CHECKED.equals(id))
				theDef.setChecked((String) value);
		}
		if (componentDef instanceof ComboDef) {
			ComboDef theDef = (ComboDef) componentDef;
			if (PROP_HEIGHTITEM.equals(id))
				theDef.setHeightItem((String) value);
			if (PROP_ENABLE.equals(id))
				theDef.setEnable((String) value);
			if (PROP_TABDATA.equals(id))
				theDef.setTabData((String) value);
			if (PROP_SUGGEST.equals(id))
				theDef.setSuggest((String) value);
		}
		if (componentDef instanceof ComboItemDef) {
			ComboItemDef theDef = (ComboItemDef) componentDef;
			if (PROP_TEXT.equals(id))
				theDef.setText((String) value);
			if (PROP_VALUE.equals(id))
				theDef.setValue((String) value);
		}
		if (componentDef instanceof GridDef) {
			GridDef theDef = (GridDef) componentDef;
			if (PROP_RANG.equals(id))
				theDef.setRang((String) value);
			if (PROP_LINEHEIGHT.equals(id))
				theDef.setLineHeight((String) value);
			if (PROP_MULTISELECT.equals(id))
				theDef.setMultiSelect((String) value);
			if (PROP_ACTIFCLIC.equals(id))
				theDef.setActifClic((String) value);
			if (PROP_CELLACTIVE.equals(id))
				theDef.setCellActive((String) value);
			if (PROP_BNAVIG.equals(id))
				theDef.setBNavig((String) value);
			if (PROP_BOOLPRINT.equals(id))
				theDef.setBoolPrint((String) value);
			if (PROP_AUTORESIZEPARENT.equals(id))
				theDef.setAutoResizeParent((String) value);
			if (PROP_SWITCHABLE.equals(id))
				theDef.setSwitchable((String) value);
			if (PROP_WRITABLE.equals(id))
				theDef.setWritable((String) value);
			if (PROP_WIDTHLASTCELL.equals(id))
				theDef.setWidthLastCell((String) value);
			if (PROP_SORTABLE.equals(id))
				theDef.setSortable((String) value);
			if (PROP_TABENTETE.equals(id))
				theDef.setTabEntete((String) value);
			if (PROP_PRINTTITLE.equals(id))
				theDef.setPrintTitle((String) value);
			if (PROP_AUTORESIZECONTENU.equals(id))
				theDef.setAutoResizeContenu((String) value);
			if (PROP_TABTYPECOL.equals(id))
				theDef.setTabTypeCol((String) value);
		}
		if (componentDef instanceof GridHeaderDef) {
			GridHeaderDef theDef = (GridHeaderDef) componentDef;
			if (PROP_TITLE.equals(id))
				theDef.setTitle((String) value);
			if (PROP_TYPE.equals(id))
				theDef.setType((String) value);
			if (PROP_WIDTH.equals(id))
				theDef.setWidth((String) value);
		}
		if (componentDef instanceof GridCellComboDef) {
			GridCellComboDef theDef = (GridCellComboDef) componentDef;
			if (PROP_VALUE.equals(id))
				theDef.setValue((String) value);
			if (PROP_TEXT.equals(id))
				theDef.setText((String) value);
		}
		if (componentDef instanceof TreeViewDef) {
			TreeViewDef theDef = (TreeViewDef) componentDef;
			if (PROP_BOOLSELACTIVE.equals(id))
				theDef.setBoolSelActive((String) value);
			if (PROP_WITHROOT.equals(id))
				theDef.setWithRoot((String) value);
			if (PROP_ROOTOPEN.equals(id))
				theDef.setRootOpen((String) value);
			if (PROP_WITHT.equals(id))
				theDef.setWithT((String) value);
			if (PROP_AUTORESIZABLEH.equals(id))
				theDef.setAutoResizableH((String) value);
			if (PROP_AUTORESIZABLEW.equals(id))
				theDef.setAutoResizableW((String) value);
			if (PROP_DRAGGABLENODE.equals(id))
				theDef.setDraggableNode((String) value);
			if (PROP_ROOTNODE.equals(id))
				theDef.setRootNode((String) value);
		}
		if (componentDef instanceof TabDef) {
			TabDef theDef = (TabDef) componentDef;
			if (PROP_TITLE.equals(id))
				theDef.setTitle((String) value);
		}
		if (componentDef instanceof DivHtmlDef) {
			DivHtmlDef theDef = (DivHtmlDef) componentDef;
			if (PROP_POSITION.equals(id))
				theDef.setPosition((String) value);
			if (PROP_CLASSNAME.equals(id))
				theDef.setClassName((String) value);
			if (PROP_HTML.equals(id))
				theDef.setHtml((String) value);
		}
		if (componentDef instanceof PopupDef) {
			PopupDef theDef = (PopupDef) componentDef;
			if (PROP_TITLE.equals(id))
				theDef.setTitle((String) value);
			if (PROP_CONTENU.equals(id))
				theDef.setContenu((String) value);
			if (PROP_MODECONTAINER.equals(id))
				theDef.setModeContainer((String) value);
			if (PROP_BSANSBTONCLOSE.equals(id))
				theDef.setBSansBtonClose((String) value);
			if (PROP_SUFFFOND.equals(id))
				theDef.setSuffFond((String) value);
		}
		if (componentDef instanceof TreeNodeDef) {
			TreeNodeDef theDef = (TreeNodeDef) componentDef;
			if (PROP_STEXT.equals(id))
				theDef.setSText((String) value);
			if (PROP_SICON.equals(id))
				theDef.setSIcon((String) value);
			if (PROP_SICON2.equals(id))
				theDef.setSIcon2((String) value);
			if (PROP_OPEN.equals(id))
				theDef.setOpen((String) value);
			if (PROP_RELOAD.equals(id))
				theDef.setReload((String) value);
			if (PROP_URL.equals(id))
				theDef.setUrl((String) value);
			if (PROP_TYPEINFO.equals(id))
				theDef.setTypeInfo((String) value);
			if (PROP_ONCLICKATTR.equals(id))
				theDef.setOnclick((String) value);
		}
		if (componentDef instanceof IPluginComponentDef) {
			IPluginComponentDef theDef = (IPluginComponentDef) componentDef;
			CustCompPropDescKey theId = (CustCompPropDescKey) id;
			theDef.setAttribute(theId.getPropName(), (String) value);
		}
	}

	final class RepeatedNameVisitor implements IBasicDefVisitor {

		private boolean nameConflict = false;

		private IComponentDef compDef;

		private String compName;

		RepeatedNameVisitor(IComponentDef compDef, String name) {
			this.compDef = compDef;
			compName = name;
		}

		public void visit(Object def) {
			if (def instanceof IComponentDef) {
				IComponentDef existingComp = (IComponentDef) def;
				if (existingComp.getName().equals(compName) && existingComp != compDef) {
					nameConflict = true;
					return;
				}
			}
		}
	}

}
