/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsdl.ui.internal.actions;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.wsdl.OperationType;


import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Polyline;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditor;
import org.eclipse.wst.wsdl.ui.internal.actions.WSDLDragAction;
import org.eclipse.wst.wsdl.ui.internal.graph.WSDLComponentViewer;
import org.eclipse.wst.wsdl.ui.internal.graph.editparts.WSDLTreeNodeEditPart;
import org.eclipse.wst.wsdl.internal.impl.OperationImpl;
import org.eclipse.gef.EditPart;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class WSDLDragReorderAction extends WSDLDragAction
{
  protected WSDLEditor wsdlEditor;
  protected WSDLElement movingChild;
  protected WSDLElement newParent;
  protected WSDLTreeNodeEditPart leftSiblingEditPart;
  protected WSDLTreeNodeEditPart rightSiblingEditPart;
  protected WSDLElement leftSibElement;
  protected WSDLElement rightSibElement;
  protected boolean canNeverExecute = false;
  
  public WSDLDragReorderAction(WSDLTreeNodeEditPart movingChildEditPart, EditPart pointerEditPart, Point pointerLocation) {
  	this.movingChildEditPart = movingChildEditPart;
  	this.pointerLocation = pointerLocation;

	EditPart possibleParent = getParentEditPart(pointerEditPart);
	
	if (!(possibleParent instanceof WSDLTreeNodeEditPart)) {
		canNeverExecute = true;
		return;
	}
  	
	WSDLTreeNodeEditPart targetParentEditPart = (WSDLTreeNodeEditPart) possibleParent;
	wsdlEditor = ((WSDLComponentViewer) possibleParent.getViewer()).getWSDLEditor();
	
	if (pointerEditPart.getParent() != null) {
		// Sort the siblings (and itself)
		List targetEditPartSiblings = pointerEditPart.getParent().getChildren();
		Collections.sort(targetEditPartSiblings, new VerticalEditPartComparator());
  
		// Get 'left' and 'right' siblings
		leftSiblingEditPart = getVerticalLeftSibling(targetEditPartSiblings, movingChildEditPart, pointerLocation);
		rightSiblingEditPart = getVerticalRightSibling(targetEditPartSiblings, movingChildEditPart, pointerLocation);           	

		if (movingChildEditPart != null)
			movingChild = (WSDLElement) movingChildEditPart.getModel();
		if (leftSiblingEditPart != null)
			leftSibElement = (WSDLElement) leftSiblingEditPart.getModel();
		if (rightSiblingEditPart != null)
			rightSibElement = (WSDLElement) rightSiblingEditPart.getModel();
		
		newParent = (WSDLElement) targetParentEditPart.getModel();
	}
	else {
		newParent = (WSDLElement) targetParentEditPart.getModel();
		leftSibElement = null;
		rightSibElement= null;
	}
  }
            
  public boolean canExecute()
  {
    boolean result = false;

    if (canNeverExecute || newParent == null || movingChild == null) {
    	return false;
    }
    
    if (movingChild instanceof Input) {
    	if (!(leftSibElement instanceof Fault) && newParent.equals(movingChild.eContainer())) {
    		result = true;
    	}
    }
    else if (movingChild instanceof Output) {
    	if (!(leftSibElement instanceof Fault) && newParent.equals(movingChild.eContainer())) {
    		result = true;
    	}
    }
    else if (movingChild instanceof Part) {
    	if (newParent instanceof Message && newParent.equals(movingChild.eContainer())) {
    		result = true;
    	}
    }

    return result;
  }           


  /*
   * @see IAction#run()
   */
  public void run()
  {                            
//    beginRecording();
  	if (canExecute()) {
  		if (movingChild instanceof Input) {
  			Input input = (Input) movingChild;
  			OperationImpl operation = (OperationImpl) input.eContainer();
  			
  			if (leftSiblingEditPart == null) {
  				// Input/Output style
  				setInputOutputOrder(operation, true);
  			}
  			else {
  				// Output/Input style
  				setInputOutputOrder(operation, false);
  			}
  		}
  		else if (movingChild instanceof Output) {
 			Output output = (Output) movingChild;
  			OperationImpl operation = (OperationImpl) output.eContainer();
  			
  			if (leftSiblingEditPart == null) {
  				// Output/Input style
  				setInputOutputOrder(operation, false);
  			}
  			else {
  				// Input/Output style
  				setInputOutputOrder(operation, true);
  			}
  		}
  		else if (movingChild instanceof Part) {
  			Message message = (Message) newParent;
  			List parts = message.getEParts();

  			parts.remove(movingChild);

  			int leftIndex = -1, rightIndex = -1;
  			if (leftSibElement != null) {
  				leftIndex = parts.indexOf(leftSibElement);
  			}
  			if (rightSibElement != null) {
  				rightIndex = parts.indexOf(rightSibElement);
  			}

  			if (leftIndex == -1) {
  				// Add moving child to the front
  				parts.add(0, movingChild);  				
  			}
  			else if (rightIndex == -1) {
  				// Add moving child to the end
  				parts.add(movingChild);
  			}
  			else {
  				// Add moving child after the occurence of the left sibling
  				parts.add(leftIndex + 1, movingChild);
  			}
  		}
  		wsdlEditor.getSelectionManager().setSelection(new StructuredSelection(movingChild));
  	}
//    endRecording();
  }
  
  public IFigure getFeedbackFigure() {
  	IFigure feedbackFigure = null;
    if (feedbackFigure == null && movingChildEditPart instanceof WSDLTreeNodeEditPart)
    {                                       
      feedbackFigure = new Polyline();                         
//  polyLine.setLineStyle(Graphics.LINE_DASHDOT);      
      ((Polyline)feedbackFigure).setLineWidth(2);	
      drawLines((Polyline) feedbackFigure);
    }
    
  	return feedbackFigure;
  }

  /* Return a PointList which will be used to add a feedback figure.  The feedback figure will be a
   * Polyline composed of the Points in the PointList
   */
  private PointList drawLines(Polyline polyLine) {
    PointList pointList = new PointList(); 
    
    if (leftSiblingEditPart != null) {
    	Rectangle leftRectangle = leftSiblingEditPart.getFigure().getBounds();
	   	int xCoord = leftRectangle.x + 15;
	  	int yCoord = leftRectangle.y;
	   	int height = leftRectangle.height;
	   	int width = leftRectangle.width - 15;

	   	// Draw left end line
	   	addLineToPolyline(polyLine, xCoord, yCoord + height + 3, xCoord, yCoord + height - 3);
	   	addLineToPolyline(polyLine, xCoord, yCoord + height - 3, xCoord, yCoord + height);
	   	
	   	// Draw horizontal line
	   	addLineToPolyline(polyLine, xCoord, yCoord + height, xCoord + width, yCoord + height);
	   	
	   	// Draw right end line
	   	addLineToPolyline(polyLine, xCoord + width, yCoord + height, xCoord + width, yCoord + height - 3);
	  	addLineToPolyline(polyLine, xCoord + width, yCoord + height, xCoord + width, yCoord + height + 3);   	
    }
    else if (rightSiblingEditPart != null) {
    	Rectangle rightRectangle = rightSiblingEditPart.getFigure().getBounds();
    	int xCoord = rightRectangle.x + 15;
    	int yCoord = rightRectangle.y;
   		int height = rightRectangle.height;
   		int width = rightRectangle.width - 15;	

   		// Draw left end line
	   	addLineToPolyline(polyLine, xCoord, yCoord + 3, xCoord, yCoord - 3);
	   	addLineToPolyline(polyLine, xCoord, yCoord - 3, xCoord, yCoord);
	   	
	   	// Draw horizontal line
	   	addLineToPolyline(polyLine, xCoord, yCoord, xCoord + width, yCoord);
	   	
	   	// Draw right end line
	   	addLineToPolyline(polyLine, xCoord + width, yCoord, xCoord + width, yCoord - 3);
	  	addLineToPolyline(polyLine, xCoord + width, yCoord, xCoord + width, yCoord + 3);   
    }

    return pointList;
  }                    
  
  protected Polyline addLineToPolyline(Polyline polyline, int x1, int y1, int x2, int y2) {
	polyline.addPoint(new Point(x1, y1));
	polyline.addPoint(new Point(x2, y2));

	return polyline;
  }                                          
  
  /*
   * Pre-condition: The List siblings should be sorted by it's y-coordinate 
   */
  private WSDLTreeNodeEditPart getVerticalRightSibling(List siblings, WSDLTreeNodeEditPart movingEditPart, Point pointerLocation) {
  	WSDLTreeNodeEditPart rightSibling = null;
  	int pointerYLocation = pointerLocation.y;

  	for (int index = 0; index < siblings.size(); index++) {
  		WSDLTreeNodeEditPart sibling = (WSDLTreeNodeEditPart) siblings.get(index);
  		int siblingYLocation = sibling.getSelectionFigure().getBounds().getCenter().y;

  		if (siblingYLocation > pointerYLocation) {
  			rightSibling = sibling;
  			break;
  		}
  	}
  	
  	return rightSibling;
  }

  /*
   * Pre-condition: The List siblings should be sorted by it's y-coordinate 
   */
  private WSDLTreeNodeEditPart getVerticalLeftSibling(List siblings, WSDLTreeNodeEditPart movingEditPart, Point pointerLocation) {
  	WSDLTreeNodeEditPart leftSibling = null;
  	int pointerYLocation = pointerLocation.y;

  	int index;
  	for (index = 0; index < siblings.size(); index++) {
  		WSDLTreeNodeEditPart sibling = (WSDLTreeNodeEditPart) siblings.get(index);
  		int siblingYLocation = sibling.getSelectionFigure().getBounds().getCenter().y;
  	  	
  		if (siblingYLocation > pointerYLocation) {
  			if (index > 0) {
  				leftSibling = (WSDLTreeNodeEditPart) siblings.get(index - 1);
  			}

  			break;
  		}
  	}

  	if (index == siblings.size()) {
  		leftSibling = (WSDLTreeNodeEditPart) siblings.get(index - 1);
  	}

  	return leftSibling;
  }
  
  protected EditPart getParentEditPart(EditPart target)
  {
  	return target.getParent();
  }
  
  // boolean inputFirst = true if the Input is the first in the order of Input and Output
  private void setInputOutputOrder(OperationImpl operation, boolean inputFirst) {
  	// We need to determine more info before we can set the style	
  	if (inputFirst && operation.getEInput() != null) {
  		// Check if there is an Output
  		if (operation.getEOutput() != null) {
  			// Order is: Input, Output
/*  			
  			Node operationNode = operation.getElement();		
  			NodeList childNodeList = operationNode.getChildNodes();
  			
  			Node inputNode = operation.getEInput().getElement();
  			Node outputNode = operation.getEOutput().getElement();
  			
  			Node inputTextNode = inputNode.getNextSibling();
  			Node outputTextNode = outputNode.getNextSibling();
  			
  			int inputNodeIndex = getNodeIndex(childNodeList, inputNode);
  			int outputNodeIndex = getNodeIndex(childNodeList, outputNode);
  			
  			if (inputNodeIndex > outputNodeIndex) {
  				// We need to swap Input and Output
  				operationNode.removeChild(inputNode);
  				operationNode.removeChild(outputNode);
  				
  				operationNode.insertBefore(inputNode, outputTextNode);
  				operationNode.insertBefore(outputNode, inputTextNode);
  			}
*/  			
  			
  			setOperationStyle(operation, OperationType.REQUEST_RESPONSE);
  		}
  		/*
  		else {
  			// Order is: Input
  			setOperationStyle(operation, OperationType.ONE_WAY);
  		}
  		*/
  	}
  	else if (operation.getEOutput() != null) {
  		// Check if there is an Input
  		if (operation.getEInput() != null) {
  			// Order is: Output, Input
/*  			
  			Node operationNode = operation.getElement();		
  			NodeList childNodeList = operationNode.getChildNodes();
  			
  			Node inputNode = operation.getEInput().getElement();
  			Node outputNode = operation.getEOutput().getElement();
  			
  			Node inputTextNode = inputNode.getNextSibling();
  			Node outputTextNode = outputNode.getNextSibling();
  			
  			int inputNodeIndex = getNodeIndex(childNodeList, inputNode);
  			int outputNodeIndex = getNodeIndex(childNodeList, outputNode);
  			
  			if (outputNodeIndex > inputNodeIndex) {
  				// We need to swap Input and Output
  				operationNode.removeChild(inputNode);
  				operationNode.removeChild(outputNode);

  				operationNode.insertBefore(inputNode, outputTextNode);
  				operationNode.insertBefore(outputNode, inputTextNode);
  			}
*/  			
  			setOperationStyle(operation, OperationType.SOLICIT_RESPONSE);
  		}
  		/*
  		else {
  			// Order is: Output
  			setOperationStyle(operation, OperationType.NOTIFICATION);
  		}
  		*/
  	}
  }

/*
 * return -1 if node is not found in the given nodeList
 */
	private int getNodeIndex(NodeList nodeList, Node node) {
		int index = 0;
		while (index < nodeList.getLength() && !(nodeList.item(index).equals(node))) {
			index++;
		}
		
		if (index >= nodeList.getLength()) {
			index = -1;
		}
		
		return index;
	}
  
  private void setOperationStyle(OperationImpl operation, OperationType operationType) {
  	// If there is no style to begin with, don't set one now
  	if (operation.getStyle() == null) {
  		return;
  	}
  	
  	operation.setStyle(operationType);
  }
  
  private class VerticalEditPartComparator implements Comparator {
  	
  	public VerticalEditPartComparator() {
  	}
  	
  	public int compare(Object part1, Object part2) {
  		int compareValue = 0;

  		if (part1 instanceof WSDLTreeNodeEditPart && part2 instanceof WSDLTreeNodeEditPart) {
  			WSDLTreeNodeEditPart editPart1 = (WSDLTreeNodeEditPart) part1;
  			WSDLTreeNodeEditPart editPart2 = (WSDLTreeNodeEditPart) part2;
  			
  			int editPart1Y = editPart1.getSelectionFigure().getBounds().getCenter().y;
  			int editPart2Y = editPart2.getSelectionFigure().getBounds().getCenter().y;
  			
  			Integer integerPart1 = new Integer(editPart1Y);
  			Integer integerPart2 = new Integer(editPart2Y);
  			
  			compareValue = integerPart1.compareTo(integerPart2);
  		}

  		return compareValue;
  	}
  }
}
