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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.tools.DragEditPartsTracker;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
import org.eclipse.jst.pagedesigner.converter.ConverterFactoryRegistry;
import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
import org.eclipse.jst.pagedesigner.converter.ITagConverter;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
import org.eclipse.jst.pagedesigner.css2.layout.CSSWidgetLayout;
import org.eclipse.jst.pagedesigner.css2.style.AbstractStyle;
import org.eclipse.jst.pagedesigner.css2.widget.HiddenProvider;
import org.eclipse.jst.pagedesigner.editpolicies.ElementMenuBar;
import org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy;
import org.eclipse.jst.pagedesigner.elementedit.ElementEditFactoryRegistry;
import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
import org.eclipse.jst.pagedesigner.figurehandler.FigureFactory;
import org.eclipse.jst.pagedesigner.figurehandler.IFigureHandler;
import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
import org.eclipse.jst.pagedesigner.range.RangeUtil;
import org.eclipse.jst.pagedesigner.tools.ObjectModeDragTracker;
import org.eclipse.jst.pagedesigner.tools.RangeDragTracker;
import org.eclipse.jst.pagedesigner.utils.CMUtil;
import org.eclipse.jst.pagedesigner.viewer.DesignRange;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * @author mengbo
 * @version 1.5
 */
public class ElementEditPart extends SubNodeEditPart {
	private static Logger _log = PDPlugin.getLogger(ElementEditPart.class);

	private Element _elementNode;

	private ITagConverter _tagConverter;
    
    private ElementMenuBar  _nonVisualElementBar;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.EditPart#setModel(java.lang.Object)
	 */
	public void setModel(Object model) {
		super.setModel(model);
		_elementNode = (Element) model;
		_tagConverter = getTagConverter(_elementNode);
		_tagConverter.convertRefresh(null);
		adaptEditProxy();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#getDragTracker(org.eclipse.gef.Request)
	 */
	public DragTracker getDragTracker(Request request) {
		EditPolicy policy = this
				.getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);
		if (policy instanceof ElementResizableEditPolicy) {
			if (((ElementResizableEditPolicy) policy)
					.shouldUseObjectMode(request)) {
				return new ObjectModeDragTracker(this);
			}
            return new RangeDragTracker(this);
		}
        // should not happen
        return new DragEditPartsTracker(this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#createEditPolicies()
	 */
	protected void createEditPolicies() {
		super.createEditPolicies();
		IElementEdit support = getElementEdit();
		if (support != null) {
			support.createEditPolicies(this);
		}

		// if ElementEdit didn't install special SELECTION_FEEDBACK_ROLE policy,
		// then default
		if (this.getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE) == null) {
			this.installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE,
					new ElementResizableEditPolicy());
		}
	}

	/**
	 * @param node
	 * @return
	 */
	public IElementEdit getElementEdit() {
		// XXX: should we cache it?
		return ElementEditFactoryRegistry.getInstance().createElementEdit(
				_elementNode);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#addNotify()
	 */
	public void addNotify() {
		if (_tagConverter == null) {
			_tagConverter = getTagConverter(_elementNode);
			_tagConverter.convertRefresh(null);
			adaptEditProxy();
		}
		super.addNotify();
	}

	/**
	 * @param node
	 * @return
	 */
	private ITagConverter getTagConverter(Element node) {
		return ConverterFactoryRegistry.getInstance().createTagConverter(node,
				IConverterFactory.MODE_DESIGNER,
				this.getDestDocumentForDesign());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeNotify()
	 */
	public void removeNotify() {
		super.removeNotify();
		// if (_tagConverter != null)
		// {
		// _tagConverter.dispose();
		// _tagConverter = null;
		// }
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
	 */
	protected List getModelChildren() {
		List children = new ArrayList(_tagConverter.getChildModeList());
        
        for (Iterator it = _tagConverter.getNonVisualChildren().iterator(); it.hasNext();)
        {
            Element nonVisualChild = (Element) it.next();
            children.add(ConverterFactoryRegistry.getInstance().createTagConverter(nonVisualChild,
                IConverterFactory.MODE_DESIGNER,
                this.getDestDocumentForDesign()));
        }
        return children;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
	 */
	protected IFigure createFigure() {
		// if (_tagConverter.isVisualByHTML())
		// {
		// Element result = _tagConverter.getResultElement();
		// return FigureFactory.createFigure(result,
		// true);//_tagConverter.isMultiLevel());
		// }
		// else
		// {
		// CSSWidgetFigure figure = new CSSWidgetFigure(this._elementNode,
		// createHiddenProvider());
		// return figure;
		// }
		return new CSSFigure();
	}

	/**
	 * @return
	 */
	private HiddenProvider createHiddenProvider() {
		Element result = _tagConverter.getHostElement();
		String localName = result.getLocalName();
		String appendString = localName;
		if (localName.equalsIgnoreCase(IJSPCoreConstants.TAG_DIRECTIVE_TAGLIB)) {
			appendString = ((IDOMElement) result)
					.getAttribute(IJSPCoreConstants.ATTR_URI);
			if (appendString == null) {
				appendString = "";
			}
		}
		Image image = _tagConverter.getVisualImage();
		HiddenProvider provider = new HiddenProvider(image, this);
		((CSSFigure) getFigure()).setCSSStyle(provider.getCSSStyle());
		provider.setLabel(appendString);
		return provider;
	}

	/**
	 * called by the
	 * 
	 */
	public void refreshModelChange(boolean recursive) {
		IElementEdit support = getElementEdit();
		if (support == null
				|| !support.handleModelChange(_elementNode, this, recursive)) {
			this.refresh(recursive);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#refresh()
	 */
	public void refresh() {
		refresh(false);
	}

	public void refresh(boolean recursive) {
		if (!_tagConverter.isVisualByHTML()) {
			_tagConverter.convertRefresh(null);
			((CSSFigure) getFigure())
					.setFixedLayoutManager(new CSSWidgetLayout(
							(CSSFigure) getFigure(), createHiddenProvider()));
			// nothing to refresh
			// ((CSSWidgetFigure)
			// getFigure()).setProvider(createHiddenProvider());
			return;
		}
		EditPart editPart;
		Object model;

		Map modelToEditPart = new HashMap();
		List children1 = getChildren();

		for (int i = 0, n = children1.size(); i < n; i++) {
			editPart = (EditPart) children1.get(i);
			modelToEditPart.put(editPart.getModel(), editPart);
			// remove child visual, since we may reconstruct the figure
			// structure of this edit part
			removeChildVisual(editPart);
		}

		Element oldEle = _tagConverter.getResultElement();

		// link parent node.
		Node parent = oldEle.getParentNode();
		_tagConverter.convertRefresh(null);
		if (parent != null) {
			// a new element is generated. replace the old one.
			parent.replaceChild(_tagConverter.getResultElement(), oldEle);
		}

		adaptEditProxy();

		// XXX: comment out the if-else for always deep update.
		// this is for the case when a empty container generate child
		// text node, and then when user input data into the container,
		// the node change from "multiLevel" state to "non-multilevel"
		// state. We don't handle this very well yet, so always to deep
		// update for now. (lium)
		// if (_tagConverter.isMultiLevel())
		// {
		FigureFactory.updateDeepFigure(_tagConverter.getResultElement(),
				oldEle, (CSSFigure) this.getFigure());
		// }
		// else
		// {
		// FigureFactory.updateNonDeepFigure(_tagConverter.getResultElement(),
		// this.getFigure());
		// }

		List modelObjects = getModelChildren();
		if (!recursive) {
			for (int i = 0, n = modelObjects.size(); i < n; i++) {
				model = modelObjects.get(i);

				// Look to see if the EditPart is already around but in the
				// wrong location
				editPart = (EditPart) modelToEditPart.remove(model);

				if (editPart != null) {
					addChildVisual(editPart, i);
				} else {
					// An editpart for this model doesn't exist yet. Create and
					// insert one.
					editPart = createChild(model);
					addChild(editPart, i);
				}
			}
			for (Iterator iter = modelToEditPart.values().iterator(); iter
					.hasNext();) {
				EditPart part = (EditPart) iter.next();
				removeChild(part);
			}
		} else {
			// remove all child, and recreate them.
			for (Iterator iter = modelToEditPart.values().iterator(); iter
					.hasNext();) {
				EditPart part = (EditPart) iter.next();
				removeChild(part);
			}
			for (int i = 0, n = modelObjects.size(); i < n; i++) {
				model = modelObjects.get(i);

				// Look to see if the EditPart is already around but in the
				// wrong location
				// An editpart for this model doesn't exist yet. Create and
				// insert one.
				editPart = createChild(model);
				addChild(editPart, i);
			}
		}
	}

	/**
	 * 
	 */
	private void adaptEditProxy() {
		Element resultEle = _tagConverter.getResultElement();
		if (resultEle instanceof IDOMElement) {
			INodeAdapter adapter = ((IDOMElement) resultEle)
					.getAdapterFor(EditProxyAdapter.class);
			if (adapter != null) {
				((IDOMElement) resultEle).removeAdapter(adapter);
			}
			((IDOMElement) resultEle).addAdapter(new EditProxyAdapter(this));
		}
	}

	/**
	 * @return
	 */
	public boolean isRangeSelected() {
		IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) this.getViewer();
		if (viewer == null || !viewer.isInRangeMode()) {
			return false;
		}
		DesignRange range = viewer.getRangeSelection();
		if (range == null || !range.isValid()) {
			return false;
		}
		return RangeUtil.intersect(range, this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#isWidget()
	 */
	public boolean isWidget() {
		return _tagConverter.isWidget();
	}

	/**
	 * @return
	 */
	public boolean canHaveDirectTextChild() {
		return CMUtil.canHaveDirectTextChild(this._elementNode);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#isResizable()
	 */
	public boolean isResizable() {
		if (!_tagConverter.isVisualByHTML()) {
			return false;
		}
		IElementEdit edit = this.getElementEdit();
		if (edit != null) {
			return edit.isResizable(this._elementNode);
		}
        CMElementDeclaration decl = CMUtil
        		.getElementDeclaration(this._elementNode);
        if (decl != null) {
        	// XXX: default implementation, if this element support "style"
        	// attribute,
        	// then we think it support resize.
        	return decl.getAttributes().getNamedItem("style") != null;
        }
        return true;
	}

	/**
	 * @param parent
	 * @return
	 */
	private IFigure getFigure(Node parent) {
		if (parent instanceof INodeNotifier) {
			IFigureHandler handler = (IFigureHandler) ((INodeNotifier) parent)
					.getAdapterFor(IFigureHandler.class);
			if (handler != null) {
				return handler.getFigure();
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#addChildVisual(org.eclipse.gef.EditPart,
	 *      int)
	 */
	protected void addChildVisual(EditPart childEditPart, int index) {
        
        boolean figureAdded = false;

        if (childEditPart instanceof NonVisualComponentEditPart)
        {
            getNonVisualElementBar().addNonVisualChild(((NonVisualComponentEditPart) childEditPart));
            figureAdded = true;
            //TODO: need better flow of control.
            return;
        }
        
		Node childNode = (Node) childEditPart.getModel();
		IFigure childFigure = ((GraphicalEditPart) childEditPart).getFigure();
		ConvertPosition position = _tagConverter
				.getChildVisualPosition(childNode);
		if (position != null) {
			Node parent = position.getParentNode();
			// link up figure.
			IFigure parentFigure = getFigure(parent);
			if (parentFigure != null) {
				parentFigure.add(childFigure, position.getIndex());
				figureAdded = true;
			}
			// link up style
			if (parent instanceof INodeNotifier) {
				ICSSStyle parentStyle = (ICSSStyle) ((INodeNotifier) parent)
						.getAdapterFor(ICSSStyle.class);
				if (parentStyle != null) {
					ICSSStyle childStyle = (ICSSStyle) ((INodeNotifier) childNode)
							.getAdapterFor(ICSSStyle.class);
					if (childStyle instanceof AbstractStyle) {
						((AbstractStyle) childStyle)
								.setParentStyle(parentStyle);
					}
				}
			}
			// link up the nodeForFigure
			if (childEditPart instanceof SubNodeEditPart) {
				Node nodeForFigure = ((SubNodeEditPart) childEditPart)
						.getNodeForFigure();
				if (nodeForFigure != null /*
											 * && !(nodeForFigure instanceof
											 * PseudoElement)
											 */) {
					parent.appendChild(nodeForFigure);
				}
			}
		} else {
		    _log.error("getChildVisualPosition() return null");
		}

		if (!figureAdded) {
			super.addChildVisual(childEditPart, index);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeChildVisual(org.eclipse.gef.EditPart)
	 */
	protected void removeChildVisual(EditPart childEditPart) {
        // remove figure
        IFigure childFigure = ((GraphicalEditPart) childEditPart).getFigure();
        IFigure parent = childFigure.getParent();

		if (parent != null) {
			parent.remove(childFigure);
		}
        
        // this only applies to visual edit parts
        if (! (childEditPart instanceof NonVisualComponentEditPart))
        {
    		// de-link style
    		Node childNode = (Node) childEditPart.getModel();
    		ICSSStyle childStyle = (ICSSStyle) ((INodeNotifier) childNode)
    				.getAdapterFor(ICSSStyle.class);
    		if (childStyle instanceof AbstractStyle) {
    			((AbstractStyle) childStyle).setParentStyle(null);
    		}
    		// de-link nodeForFigure
    		if (childEditPart instanceof SubNodeEditPart) {
    			Node nodeForFigure = ((SubNodeEditPart) childEditPart)
    					.getNodeForFigure();
    			if (nodeForFigure != null && nodeForFigure.getParentNode() != null) {
    				nodeForFigure.getParentNode().removeChild(nodeForFigure);
    			}
    		}
        }
	}

	/**
	 * @return
	 */
	public ITagConverter getTagConvert() {
		return _tagConverter;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
	 *      int, java.lang.Object, java.lang.Object, java.lang.Object, int)
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType,
			Object changedFeature, Object oldValue, Object newValue, int pos) {
		refresh();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.parts.SubNodeEditPart#getNodeForFigure()
	 */
	public Node getNodeForFigure() {
		return _tagConverter.getResultElement();
	}

	/**
	 * @return
	 */
	public boolean haveNonWhitespaceTextChild() {
		List children1 = this.getChildren();
		for (int i = 0, size = children1.size(); i < size; i++) {
			if (children1.get(i) instanceof TextEditPart) {
				IDOMText xmltext = (IDOMText) ((TextEditPart) children1.get(i))
						.getIDOMNode();
				if (!xmltext.isElementContentWhitespace()) {
					return true;
				}
			}
		}
		return false;
	}

    private ElementMenuBar getNonVisualElementBar()
    {
        if (_nonVisualElementBar == null)
        {
            _nonVisualElementBar = new ElementMenuBar(this);
        }
        return _nonVisualElementBar;
    }

    public ElementMenuBar getElementMenuBar() {
        return getNonVisualElementBar();
    }

    public void deactivate() {
        super.deactivate();
        if (_nonVisualElementBar != null)
        {
            _nonVisualElementBar.dispose();
            _nonVisualElementBar = null;
        }
    }
}
