/*******************************************************************************
 * Copyright (c) 2005, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.ui.editparts;

import org.eclipse.bpel.model.EventHandler;
import org.eclipse.bpel.model.FaultHandler;
import org.eclipse.bpel.model.Process;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.bpel.ui.adapters.IEventHandlerHolder;
import org.eclipse.bpel.ui.adapters.IFaultHandlerHolder;
import org.eclipse.bpel.ui.adapters.ILabeledElement;
import org.eclipse.bpel.ui.editparts.policies.BPELSelectionEditPolicy;
import org.eclipse.bpel.ui.figures.CenteredConnectionAnchor;
import org.eclipse.bpel.ui.figures.ILayoutAware;
import org.eclipse.bpel.ui.uiextensionmodel.StartNode;
import org.eclipse.bpel.ui.util.BPELDragEditPartsTracker;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.ModelHelper;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ImageFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.NodeEditPart;
import org.eclipse.gef.Request;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;


public class StartNodeEditPart extends BPELEditPart implements NodeEditPart, ILayoutAware{
	
	protected Image image;
	protected int imageWidth;
	protected int imageHeight;
	
	//Determines the border which will be added to both sides (left/right)
	//As a result this value is the distance to any attached handlers. 
	public static final int BORDER_WIDTH = 8;
	
	// Whether the process has a fault handler and event handler
	protected boolean hasFH, hasEH;
	
	// Whether to show each of the actual handlers.
	// TODO: Initialize these from the preferences store
	protected boolean showFH = false, showEH = false;

	// Fault handler, Compensation handler and Event handler support
	protected int faultImageWidth, faultImageHeight;
	protected int eventImageWidth, eventImageHeight;
	protected Image faultImage;
	protected Image eventImage;
	protected Rectangle rectFault;
	protected Rectangle rectEvent;
	
	private IFigure faultImageFigure;
	private IFigure eventImageFigure;

	private class StartNodeFigure extends ImageFigure {
		/**
		 * 
		 */
		public StartNodeFigure() {
			super(image);
		}
		
		/**
		 * @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics)
		 */
		@Override
		public void paint(Graphics graphics) {
			super.paint(graphics);
			computeHandlerIconPositions(ModelHelper.isHorizontalLayout(getModel()));
			if (hasFH) {
				graphics.pushState();
				graphics.setClip(faultImageFigure.getBounds().getCopy());
				faultImageFigure.paint(graphics);
				graphics.popState();
			}
			if (hasEH) {
				graphics.pushState();
				graphics.setClip(eventImageFigure.getBounds().getCopy());
				eventImageFigure.paint(graphics);
				graphics.popState();
			}
		}
	}
	
	/** 
	 * Brand new shiny start edit part.
	 */
	public StartNodeEditPart() {
		// Initialize images for fault and event handler decorations
		this.faultImage = BPELUIPlugin.INSTANCE.getImage(IBPELUIConstants.ICON_FAULT_INDICATOR);
		org.eclipse.swt.graphics.Rectangle r = faultImage.getBounds();
		this.faultImageWidth = r.width;
		this.faultImageHeight = r.height;

		this.eventImage = BPELUIPlugin.INSTANCE.getImage(IBPELUIConstants.ICON_EVENT_INDICATOR);
		r = eventImage.getBounds();
		this.eventImageWidth = r.width;
		this.eventImageHeight = r.height;
	}
	
	@Override
	protected void addAllAdapters() {
		super.addAllAdapters();
		adapter.addToObject(getProcess());
	}
	
	
	@Override
	protected void removeAllAdapters() {
		adapter.removedFrom(getProcess());
		super.removeAllAdapters();
	} 
	
	@Override
	protected IFigure createFigure() {
		if (image == null) {
			ILabeledElement element = BPELUtil.adapt(getStartNode(), ILabeledElement.class);
			image = element.getSmallImage(getStartNode());
			Rectangle rect = image.getBounds();
			imageWidth = rect.width;
			imageHeight = rect.height;
		}
		this.hasFH = getFaultHandler() != null;
		this.hasEH = getEventHandler() != null;
		// Cause the handlerIcons don't belong to the 
		// bounds of the StartNodeFigure (as a result of 
		// moving them a bit to the right in vertical layout and a bit to to the bottom
		// in horizontal layout) hit testing
		// doesn't reach the Startnode. So add an invisible
		// border
		StartNodeFigure snf = new StartNodeFigure();
		if(!ModelHelper.isHorizontalLayout(getModel()))
			snf.setBorder(new MarginBorder(0,7+BORDER_WIDTH,0,7+BORDER_WIDTH));
		else
			snf.setBorder(new MarginBorder(5,0,5,0));
		
		
		faultImageFigure = new ImageFigure(faultImage);
		faultImageFigure.setParent(snf);
		
		eventImageFigure = new ImageFigure(eventImage);
		eventImageFigure.setParent(snf);
		
		return snf;
	}
	
	/**
	 * @see org.eclipse.bpel.ui.editparts.BPELEditPart#refreshVisuals()
	 */
	@Override
	public void refreshVisuals() {
		super.refreshVisuals();
		// Refresh any decorations on this edit part
		this.hasFH = getFaultHandler() != null;
		this.hasEH = getEventHandler() != null;
		// Force a repaint, as the decorations.
		getFigure().repaint();
	}
	
	/**
	 * Return the start node.
	 * @return return the start node.
	 */
	public StartNode getStartNode() {
		return (StartNode)getModel();
	}

	/**
	 * Return the process.
	 * @return the process
	 */
	
	public Process getProcess() {
		return getStartNode().getProcess();
	}
	
	@Override
	protected void createEditPolicies() {
		// Don't call super because we don't want a component edit policy
		// or a direct edit policy.
		
		// Show the selection rectangle
		installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new BPELSelectionEditPolicy(false, false){
			@Override
			protected int getWestInset() {
				Insets ins = ((StartNodeEditPart)getHost()).getFigure().getInsets();
				if(ins != null){
					return ins.left;
				}
				return super.getWestInset();
			}
			
			@Override
			protected int getEastInset() {
				Insets ins = ((StartNodeEditPart)getHost()).getFigure().getInsets();
				if(ins != null){
					return ins.right;
				}
				return super.getEastInset();
			}
		});
	}

	public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connEditPart) {
		// Start nodes cannot be the target of a connection.
		return null;
	}

	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connEditPart) {
		// Start nodes can be the source of an implicit connection
		// anchored at the bottom centre of the node.
		return new CenteredConnectionAnchor(getFigure(), CenteredConnectionAnchor.BOTTOM, 0);
	}
	
	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
		// TODO: Translate point to figure, call other method
		return getSourceConnectionAnchor((ConnectionEditPart)null);
	}
	
	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
		// TODO: Translate point to figure, call other method
		return getTargetConnectionAnchor((ConnectionEditPart)null);
	}

	public void setShowFaultHandler(boolean showFaultHandler) {
		this.showFH = showFaultHandler;
		// Notify the process too.
		ProcessEditPart processEditPart = (ProcessEditPart)getParent();
		processEditPart.setShowFaultHandler(showFaultHandler);
		// Call refresh so that both refreshVisuals and refreshChildren will be called.
		refresh();
	}

	public void setShowEventHandler(boolean showEventHandler) {
		this.showEH = showEventHandler;
		// Notify the process too.
		ProcessEditPart processEditPart = (ProcessEditPart)getParent();
		processEditPart.setShowEventHandler(showEventHandler);
		// Call refresh so that both refreshVisuals and refreshChildren will be called.
		refresh();
	}
		
	public boolean getShowFaultHandler() {
		return showFH;
	}
	
	public boolean getShowEventHandler() {
		return showEH;
	}
	
	
	public FaultHandler getFaultHandler() {
		IFaultHandlerHolder holder = BPELUtil.adapt(getProcess(), IFaultHandlerHolder.class);
		if (holder != null) {
			return holder.getFaultHandler(getProcess());
		}
		return null;
	}
		
	public EventHandler getEventHandler() {
		IEventHandlerHolder holder = BPELUtil.adapt(getProcess(), IEventHandlerHolder.class);
		if (holder != null) {
			return holder.getEventHandler(getProcess());
		}
		return null;
	}
	/**
	 * Is point in fault image.
	 * @param x
	 * @param y
	 * @return true if it is, false if its not.
	 */
	public boolean isPointInFaultImage(int x, int y) {
		if (hasFH) {
			Point p = new Point(x, y);
			getFigure().translateToRelative(p);
			return rectFault.contains(p.x, p.y);
		}
		return false;
	}	

	/**
	 * Is point in event image.
	 * @param x
	 * @param y
	 * @return true if it is, false if its not.
	 */
	public boolean isPointInEventImage(int x, int y) {
		if (hasEH) {
			Point p = new Point(x, y);
			getFigure().translateToRelative(p);
			return rectEvent.contains(p.x, p.y);
		}
		return false;
	}	
	
	
	/**
	 * @see org.eclipse.bpel.ui.editparts.BPELEditPart#getDragTracker(org.eclipse.gef.Request)
	 */
	@Override
	public DragTracker getDragTracker(Request request) {
		return new BPELDragEditPartsTracker(this) {
			@Override
			protected boolean handleDoubleClick(int button) {
				return true;
			}
			
			@Override
			protected boolean handleButtonDown(int button) {
				Point point = getLocation();
				if (isPointInFaultImage(point.x, point.y)) {
					setShowFaultHandler(!showFH);
					return true;
				}
				if (isPointInEventImage(point.x, point.y)) {
				    setShowEventHandler(!showEH);
				    return true;
				}
				return super.handleButtonDown(button);
			}
		};	
	}
	
	private void computeHandlerIconPositions(boolean horizontal){
		org.eclipse.draw2d.geometry.Rectangle bounds = getFigure().getBounds();
		if(horizontal){
			rectFault = new Rectangle(bounds.x, bounds.y + bounds.height - faultImageHeight, faultImageWidth, faultImageHeight);
			rectEvent = new Rectangle(bounds.x +faultImageWidth, bounds.y + bounds.height - eventImageHeight, eventImageWidth, eventImageHeight);
			
		}else{
			rectFault = new Rectangle(bounds.x + bounds.width - faultImageWidth - BORDER_WIDTH, bounds.y-1, faultImageWidth, faultImageHeight);
			rectEvent = new Rectangle(bounds.x + bounds.width - eventImageWidth - BORDER_WIDTH, bounds.y + bounds.height - eventImageHeight+1, eventImageWidth, eventImageHeight);
		}
		
		// Apply the bounds to the figures
		faultImageFigure.setBounds(new org.eclipse.draw2d.geometry.Rectangle(rectFault.x,rectFault.y,rectFault.width,rectFault.height));
		eventImageFigure.setBounds(new org.eclipse.draw2d.geometry.Rectangle(rectEvent.x,rectEvent.y,rectEvent.width,rectEvent.height));
	}
	
	public Rectangle getRectFault() {
		return rectFault;
	}

	public Rectangle getRectEvent() {
		return rectEvent;
	}

	public void switchLayout(boolean horizontal) {
		if(horizontal){
			getFigure().setBorder(new MarginBorder(5,0,5,0));
		}else{
			getFigure().setBorder(new MarginBorder(0,7+BORDER_WIDTH,0,7+BORDER_WIDTH));
		}
		
	}

	public IFigure getFaultImageFigure() {
		return faultImageFigure;
	}

	public IFigure getEventImageFigure() {
		return eventImageFigure;
	}
}
