/*******************************************************************************
 * 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.draw2d.geometry.Point;
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.requests.LocationRequest;
import org.eclipse.gef.tools.DragEditPartsTracker;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.jsf.core.internal.tld.CMUtil;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
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.dtmanager.DTManager;
import org.eclipse.jst.pagedesigner.editpolicies.ElementMenuBar;
import org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy;
import org.eclipse.jst.pagedesigner.editpolicies.IEnhancedSelectionEditPolicy;
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.requests.PageDesignerRequestConstants;
import org.eclipse.jst.pagedesigner.viewer.DesignRange;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.swt.graphics.Cursor;
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 (PageDesignerRequestConstants.REQ_SELECTION_TRACKER.equals(request.getType())
                || org.eclipse.gef.RequestConstants.REQ_SELECTION.equals(request.getType()))
        {
            if (policy instanceof IEnhancedSelectionEditPolicy
                    && request instanceof LocationRequest)
            {
                return ((IEnhancedSelectionEditPolicy)policy).getSelectionDragTracker((LocationRequest)request);
            }
            
            return null;
        }
        
        // 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());
		}
	}

	/**
	 * @return the associated element edit
	 */
	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 DTManager.getInstance().getTagConverter(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(DTManager.getInstance().getTagConverter(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 = ((IDOMElement) result)
					.getAttribute(IJSPCoreConstants.ATTR_TAGDIR);
				if (appendString == null)
					appendString = ""; //$NON-NLS-1$
			}
		}
		Image image = _tagConverter.getVisualImage();
		HiddenProvider provider = new HiddenProvider(image, this);
		((CSSFigure) getFigure()).setCSSStyle(provider.getCSSStyle());
		provider.setLabel(appendString);
		return provider;
	}

	/**
	 * called by the
	 * @param recursive
	 * 
	 */
	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);
	}

	/**
	 * @param recursive
	 */
	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 true if we are in range mode and this is in 
	 * the selection range
	 */
	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 true if our model node can have direct text children
	 */
	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; //$NON-NLS-1$
        }
        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"); //$NON-NLS-1$
		}

		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);
		}
        
        if (childEditPart instanceof NonVisualComponentEditPart)
        {
            _nonVisualElementBar.removeNonVisualChild((NonVisualComponentEditPart) childEditPart);
        }
        // this only applies to visual edit parts
        else
        {
    		// 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 the associated tag converter
	 */
	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) {
        // XXX: this can cause multiple refreshes on the same edit part for the 
        // same change.  I can also cause incorrect child refreshes...
		refresh();
	}

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

	/**
	 * @return true this part's node has non whitespace child nodes
	 */
	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;
    }

    /**
     * @return the element menu bar for this element
     */
    public ElementMenuBar getElementMenuBar() {
        return getNonVisualElementBar();
    }

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

    public Cursor getCursor(Point mouseLocation) {
        // let the selection edit policy dictate
        EditPolicy  editPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);
        
        if (editPolicy instanceof IEnhancedSelectionEditPolicy)
        {
            return  ((IEnhancedSelectionEditPolicy)editPolicy).getSelectionToolCursor(mouseLocation);
        }
        return super.getCursor(mouseLocation);
    }
    
    
}
