/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 21.10.2004
 *
 */
package uk.ac.ic.doc.kevlar.gui.internal;

import org.eclipse.swt.graphics.Point;

/**
 * @author ei02
 *
 */

public abstract class AMouseListenerObject extends ADrawableObject {
	
    public static final int MB_LEFT = 1;
    public static final int MB_MIDDLE = 2;
    public static final int MB_RIGHT = 3;
    
	protected boolean mouseOver;
	protected boolean mouseDown;
	
	public AMouseListenerObject() {
	    
	    super();
	    initialise();
	    
	}
	
	private void initialise() {
    
		mouseOver = false;
		mouseDown = false;
			    
	}
	
	public void concreteMouseExit() {
	    
	    if (mouseOver) {
	        
	        mouseOver = false;
	        mouseExit();
	        
	    }

        for (int i=0; i<children.size(); i++) {
            
            if (children.get(i) instanceof AMouseListenerObject) {
            
                ((AMouseListenerObject)children.get(i)).concreteMouseExit();
                
            }
            
        }
        	    
	}
	
	public boolean concreteMouseMove(Point position) {
	    
/*	    if (visible) {
	        
	        if (x>area.x && y>area.y && x<area.x+area.width && y<area.y+area.height) {
	            
	            mouseMoving(new Point(x - area.x, y - area.y));
	            
	            if (!mouseOver) {
	                
	                mouseOver = true;
	                mouseEnter();
	                
	            }
	            
	            for (int i=0; i<children.size(); i++) {
	                
	                ADrawableObject child = children.get(i);
	                
	                if (child instanceof AMouseListenerObject) {
	                    
	                    ((AMouseListenerObject)child).concreteMouseMove(x-area.x, y-area.y);
	                    
	                }
	                
	            }
	            
	        } else {
	            
	            concreteMouseExit();
	            
	        } 
	        
	    } */
		
	    if (visible) {
	        
	        if (area.contains(position)) {
	            
	            Point localPos = new Point(position.x-area.x, position.y-area.y);

	            boolean found = false;
	            
	            for (int i=children.size()-1; i>=0; i--) {
	                
	                ADrawableObject child = children.get(i);
	                
	                if (child instanceof AMouseListenerObject) {
	                    
	                    if (!found) {
	                    
	                        found = ((AMouseListenerObject)child).concreteMouseMove(localPos);
	                        
	                    } else {
	                        
	                        ((AMouseListenerObject)child).concreteMouseExit();
	                        
	                    }
	                    
	                }
	                
	            }
	            
	            if (!found && capturesMouse()) {

		            if (!mouseOver) {
		                
		                mouseOver = true;
		                mouseEnter();
		                
		            }
	                	            	                
	                mouseMoving(localPos);
//	                System.out.println(this.getClass().getName());
	                
	            }

	            return found || capturesMouse();
	            	            
	        } else {
	            
	            concreteMouseExit();
	            
	        } 
	        
	    }

        return false;
	    
	}
	
	public boolean concreteMouseDown(Point position, int mouseButton) {
		
/*		if (visible && x>area.x && y>area.y && x<area.x+area.width && y<area.y+area.height) {
		    
			if (!mouseDown) {
			    
				mouseDown = true;
				
			}

			mousePress(new Point(x-area.x, y-area.y), mouseButton);
			
			IImmutableList<ADrawableObject> childrenCopy = new ImmutableArrayList<ADrawableObject>(children);
			
	        for (int i=0; i<childrenCopy.size(); i++) {
	            
	            ADrawableObject child = childrenCopy.get(i);
	            
	            if (child instanceof AMouseListenerObject) {
	            
	                ((AMouseListenerObject)child).concreteMouseDown(x-area.x, y-area.y, mouseButton);
	                
	            }
	            
	        }			
			
		} */
	    
	    if (visible) {
	        
	        if (area.contains(position)) {
	            
	            Point localPos = new Point(position.x-area.x, position.y-area.y);
	            
	            boolean found = false;
	            
	            for (int i=children.size()-1; i>=0; i--) {
	                
	                ADrawableObject child = children.get(i);
	                
	                if (child instanceof AMouseListenerObject) {
	                    
	                    if (!found) {
	                    
	                        found = ((AMouseListenerObject)child).concreteMouseDown(localPos, mouseButton);
	                        
	                    }
	                    
	                }
	                
	            }
	            
	            if (!found && capturesMouse()) {
	                
		            if (!mouseDown) {
		                
		                mouseDown = true;
		                
		            }
	                
	                mousePress(localPos, mouseButton);
//	                System.out.println(this.getClass().getName());
	                
	            }

	            return found || capturesMouse();
                	            
	        } 
	        
	    }

        return false;	    
		
	}
	
	public void concreteMouseUp(int x, int y, int mouseButton) {

		if (mouseDown) {
		    
			mouseDown = false;
			mouseRelease(new Point(x-area.x, y-area.y), mouseButton);
			
		}
	    
/*		if (x>area.x && y>area.y && x<area.x+area.width && y<area.y+area.height) {

			mouseRelease(new Point(x-area.x, y-area.y), mouseButton);
			
		} */ 

        for (int i=0; i<children.size(); i++) {
            
            ADrawableObject child = children.get(i);
            
            if (child instanceof AMouseListenerObject) {
            
                ((AMouseListenerObject)child).concreteMouseUp(x-area.x, y-area.y, mouseButton);
                
            }
            
        }			
						
	}
	
	public void getMouseFocus() {
	    
	    CanvasManager.getSingleton().setMouseFocusObject(this);
	    
	}
	
	public void releaseMouseFocus() {
	    
	    CanvasManager.getSingleton().releaseMouseFocusObject(this);
	    
	}
	
	public boolean isMouseOver() {
	    
		return mouseOver;
		
	}
	
	public boolean isMouseDown() {
	    
		return mouseDown;
		
	}
	
/*	public void onDragRelease() {
	    
		for (int i= 0; i<children.size(); i++) {
		    
		    ADrawableObject child = children.get(i);
		    
		    if (child instanceof AMouseListenerObject) {
		    
		        ((AMouseListenerObject)child).onDragRelease();
		        
		    }
			
		}
		
	} */	

	public void mousePress(Point position, int mouseButton) {
	    
	    /* Default implementation for mousePress */
	    
	}
	
	public void mouseRelease(Point position, int mouseButton) {
	    
	    /* Default implementation for mouseRelease */
	    
	}
	
	public void mouseEnter() { 
	    
	    /* Default implementation for mouseEnter */
	    
	}
	
	public void mouseExit() { 
	    
	    /* Default implementation for mouseExit */
	    
	}
	
	public void mouseMoving(Point position) { 
	    
	    /* Default implementation for mouseMoving */
	    
	}

	public boolean capturesMouse() {
	    
	    /* Default implementation for capturesMouse */
	    return false;
	    
	}
		
}
