/*
 * Copyright (c) 2006-2008 Maskat Project.
 *
 * 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:
 *     Maskat Project - initial API and implementation
 */
package org.maskat.ui.editors.layout.outline;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BasicDynaBean;
import org.eclipse.core.runtime.Platform;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractTreeEditPart;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.views.properties.IPropertySource;
import org.maskat.core.MaskatElement;
import org.maskat.core.layout.Button;
import org.maskat.core.layout.Checkbox;
import org.maskat.core.layout.CodeLib;
import org.maskat.core.layout.Combo;
import org.maskat.core.layout.ComboItem;
import org.maskat.core.layout.Component;
import org.maskat.core.layout.ComponentPart;
import org.maskat.core.layout.DivHtml;
import org.maskat.core.layout.DivSplit;
import org.maskat.core.layout.Frame;
import org.maskat.core.layout.Grid;
import org.maskat.core.layout.GridCell;
import org.maskat.core.layout.GridCellCombo;
import org.maskat.core.layout.GridHeader;
import org.maskat.core.layout.GridLine;
import org.maskat.core.layout.Label;
import org.maskat.core.layout.Layout;
import org.maskat.core.layout.Popup;
import org.maskat.core.layout.Radio;
import org.maskat.core.layout.Splitter;
import org.maskat.core.layout.StructuredComponent;
import org.maskat.core.layout.TabFolder;
import org.maskat.core.layout.TabItem;
import org.maskat.core.layout.Text;
import org.maskat.core.layout.TreeNode;
import org.maskat.core.layout.TreeView;
import org.maskat.core.layout.Window;
import org.maskat.core.layout.custom.DynaComponent;
import org.maskat.ui.ISharedImages;
import org.maskat.ui.MaskatUIPlugin;
import org.maskat.ui.editors.layout.editparts.DynaComponentEditPartFactory;
import org.maskat.ui.editors.layout.editparts.LabelDirectEditable;
import org.maskat.ui.editors.layout.editpolicies.MaskatComponentEditPolicy;
import org.maskat.ui.views.properties.AbstractComponentPropertySource;
import org.maskat.ui.views.properties.DynaBeanPropertySource;
import org.maskat.ui.views.properties.LayoutPropertySource;

public class OutLineTreeEditPart extends AbstractTreeEditPart 
	implements PropertyChangeListener {
	
	private EditPart layoutEditPart = null;
//	private EditPart relationEditPart = null;
	
	private Image image = null;

	public void activate() {
		super.activate();
		if (getModel() instanceof Component) {
			((Component) getModel()).addPropertyChangeListener(this);
		}
	}

	public void deactivate() {
		if (getModel() instanceof Component) {
			((Component) getModel()).removePropertyChangeListener(this);
		}
		super.deactivate();
	}

	public void propertyChange(PropertyChangeEvent evt) {
		String name = evt.getPropertyName();
		if ("addChild".equals(name) || "removeChild".equals(name)) {
			refresh();
		} else 	if ("gridHeaderTitle".equals(name)) {
			for (Iterator it = this.getChildren().iterator(); it != null
				&& it.hasNext();) {
				((EditPart) it.next()).refresh();
			}
		}
		refreshVisuals();
	}

	protected List getModelChildren() {
		List result = null;
		Object model = getModel();
		if (model instanceof MaskatElement) {
			List list = ((MaskatElement) model).getUnmodifiableChildren();
			if (list != null) {
				result = new ArrayList();
				for (int i = 0; i < list.size(); i++) {
					Object element = list.get(i);
					if (element instanceof Component ||
						(model instanceof StructuredComponent &&
							element instanceof ComponentPart &&
							((StructuredComponent) model).
								canAddPart((ComponentPart) element))) {
						result.add(element);
					}
//					if (element instanceof Component || element instanceof GridHeader 
//							|| element instanceof GridLine ||  element instanceof GridCell 
//							|| element instanceof GridCellCombo) {
//						result.add(element);
//					}
				}
			}
		}
		return (result != null) ? result : super.getModelChildren(); 
	}

	protected void refreshVisuals() {
		setWidgetText(getOutlineText());
		setWidgetImage(getOutlineImage());
	}

	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.COMPONENT_ROLE, new MaskatComponentEditPolicy());
		//installEditPolicy(DataBindingEditPolicy.ROLE, new DataBindingEditPolicy());
	}

	public void setLayoutEditPart(EditPart editPart) {
		layoutEditPart = editPart;
	}
	
	public EditPart getLayoutEditPart() {
		return layoutEditPart;
	}
	
//	public void setRelationEditPart(EditPart editPart) {
//		relationEditPart = editPart;
//	}
//	
//	public EditPart getRelationEditPart() {
//		return relationEditPart;
//	}
	
	public Object getAdapter(Class key) {
		if (key.equals(IPropertySource.class)) {
			Object object = Platform.getAdapterManager().getAdapter(getModel(), key);
			if (object instanceof AbstractComponentPropertySource) {
				((AbstractComponentPropertySource)object).setCommandStack(getViewer().getEditDomain().getCommandStack());
			}else if (object instanceof LayoutPropertySource) {
				((LayoutPropertySource)object).setCommandStack(getViewer().getEditDomain().getCommandStack());
			}else if (object instanceof DynaBeanPropertySource) {
				((DynaBeanPropertySource)object).setCommandStack(getViewer().getEditDomain().getCommandStack());
			} 
			return object;
		} else if (key.isAssignableFrom(getModel().getClass())) {
			return getModel();
		}
		return super.getAdapter(key);
	}
	
	private String getOutlineText() {
		Object model = getModel();
		if (layoutEditPart == null) {
			if (model != null) {
				String name = model.getClass().getName();
				return name.substring(name.lastIndexOf(".") + 1);
			}
			return null;
		}
		LabelDirectEditable direct = null;
		if (layoutEditPart != null) {
			direct = (LabelDirectEditable)
				layoutEditPart.getAdapter(LabelDirectEditable.class);
		}
//		LabelDirectEditable directRelation = null;
//		if (relationEditPart != null) {
//			directRelation = (LabelDirectEditable)
//			relationEditPart.getAdapter(LabelDirectEditable.class);
//		}
		
		StringBuffer sb = new StringBuffer(" "); //$NON-NLS-1$
		if (model instanceof Component && !(model instanceof ComboItem)) {
			String name = ((Component) model).getName();
			if (name != null) {
				sb.append(((Component) model).getName());
				sb.append(" - ");	//$NON-NLS-1$
			}
		}
		String className = null;
		if (model instanceof BasicDynaBean) {
			className = ((BasicDynaBean) model).getDynaClass().getName();
		} else {
			className = model.getClass().getName();
		}
		className = className.substring(className.lastIndexOf(".") + 1);
		sb.append(className);

		if (direct != null) {
			sb.append(" - ("); //$NON-NLS-1$
			String v = direct.getLabel();
			sb.append(v == null ? "" : v); //$NON-NLS-1$
			sb.append(")"); //$NON-NLS-1$
		}
//		if (directRelation != null) {
//			sb.append(" - ("); //$NON-NLS-1$
//			String v = directRelation.getLabel();
//			sb.append(v == null ? "" : v); //$NON-NLS-1$
//			sb.append(")"); //$NON-NLS-1$
//		}
		return sb.toString();
	}
	
	private Image getOutlineImage() {
		if (image != null) {
			return image;
		}
		//MaskatComponentLibrary
		Object model = getModel();
				
		if (model instanceof Layout) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_LAYOUT);
		} else if (model instanceof Button) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_BUTTON);
		} else if (model instanceof Checkbox) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_CHECKBOX);
		} else if (model instanceof CodeLib) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_CODELIB);
		} else if (model instanceof Combo) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_COMBO);
		} else if (model instanceof ComboItem) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_COMBOITEM);
		} else if (model instanceof DivHtml) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_DIVHTML);				
		} else if (model instanceof Frame) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_FRAME);
		} else if (model instanceof Grid) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_GRID);
		} else if (model instanceof GridHeader) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_GRIDHEADER);
		} else if (model instanceof org.maskat.core.layout.Image) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_IMAGE);
		} else if (model instanceof Label) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_LABEL);
		} else if (model instanceof Popup) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_POPUP);	
		} else if (model instanceof Radio) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_RADIO);				
		} else if (model instanceof Splitter) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_SPLITTER);
		} else if (model instanceof DivSplit) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_FRAME);
		} else if (model instanceof TabFolder) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_TABFOLDER);
		} else if (model instanceof TabItem) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_TABITEM);
		} else if (model instanceof Text) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_TEXT);
		} else if (model instanceof TreeView) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_TREE);
		} else if (model instanceof TreeNode) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_TREENODE);	
		} else if (model instanceof GridLine) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_GRIDLINE);	
		} else if (model instanceof GridCell) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_GRIDCELL);	
		} else if (model instanceof GridCellCombo) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_GRIDCELLCOMBO);	
		} else if (model instanceof Window) {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_WINDOW);
		} else if (model instanceof DynaComponent) {
			ImageDescriptor desc = DynaComponentEditPartFactory.getImageDescriptor(model);
			if (desc == null) {
				image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_CUSTOM);
			} else {
				image = desc.createImage();
			}
		} else {
			image = MaskatUIPlugin.getImage(ISharedImages.IMG_COMPONENT_UNKNOWN);
		}

		return image;
	}
}
