package ei.engine.input;

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;

import ei.engine.LWJGLGameWindow;
import ei.engine.math.Vector2f;
import ei.engine.math.Vector3f;
import ei.engine.scene.Node;
import ei.engine.scene.Sprite;

/**
 * Handles the mouse input
 * @author Ziver
 *
 */
public abstract class MouseInput extends Input{
	public static final int LEFT_MOUSE_BUTTON = 0;
	public static final int RIGHT_MOUSE_BUTTON = 1;
	public static final int MIDDLE_MOUSE_BUTTON = 2;
	// The x pos of the mouse
	private static int cursorX;
	// The y pos of the mouse
	private static int cursorY;
	// The texute for the mouse
	private Sprite cursor;
	private Node mouseNode;

	public MouseInput(String name) {
		super(name);
        // init mouse: this will hide the native cursor (see drawCursor())
        Mouse.setGrabbed(false);
        mouseNode = new Node("MouseInputNode");
        
        // set initial cursor pos to center screen
        cursorX = (int) LWJGLGameWindow.getWidth() / 2;
        cursorY = (int) LWJGLGameWindow.getHeight() / 2;
	}
	
	public MouseInput(String name,String texture){
		super(name);
        // init mouse: this will hide the native cursor (see drawCursor())
        Mouse.setGrabbed(true);
        cursor = new Sprite(name+" spatial",texture);
        mouseNode = new Node("MouseInputNode");
        
        // set initial cursor pos to center screen
        cursorX = (int) LWJGLGameWindow.getWidth() / 2;
        cursorY = (int) LWJGLGameWindow.getHeight() / 2;
	}
	
	/**
	 * Returns the sprite of th mouse
	 * 
	 * @return The sprite of the mouse
	 */
	public Sprite getSprite(){
		return cursor;
	}
	
	/**
	 * Returns the sprite of th mouse
	 * 
	 * @return The sprite of the mouse
	 */
	public Node getNode(){
		return mouseNode;
	}

	/**
	 * Renders the mous texture if texture set
	 */
	public void render() {
		mouseNode.render();
		if(cursor != null){
			GL11.glPushMatrix();
				Vector3f v = LWJGLGameWindow.getCamera().getLocation();
				GL11.glTranslatef(v.getX(),v.getY(), v.getZ());
				cursor.render();
			GL11.glPopMatrix();
		}
	}

	/**
	 * Updates the pos of the mouse and send any 
	 * change to mouseMove(), mouseDown() or mouseUp()
	 */
	public void update() {
        int mouseDX = Mouse.getDX();
        int mouseDY = Mouse.getDY();
        int mouseDW = Mouse.getDWheel();
        if (mouseDX != 0 || mouseDY != 0 || mouseDW != 0) {
            cursorX += mouseDX;
            cursorY -= mouseDY;
            if (cursorX < 0) {
                cursorX = 0;
            }
            else if (cursorX > LWJGLGameWindow.getWidth()) {
                cursorX = LWJGLGameWindow.getWidth();
            }
            if (cursorY < 0) {
                cursorY = 0;
            }
            else if (cursorY > LWJGLGameWindow.getHeight()) {
                cursorY = LWJGLGameWindow.getHeight();
            }
        }
        mouseUpdate(cursorX,cursorY,mouseDW);
		
        while ( Mouse.next() ) {
            if(Mouse.getEventButton() >= 0 && Mouse.getEventButtonState() == true) {
              mouseDown(Mouse.getEventButton(),cursorX, cursorY);
            }
            if(Mouse.getEventButton() >= 0 && Mouse.getEventButtonState() == false) {
              mouseUp(Mouse.getEventButton(),cursorX, cursorY);
            }
        }
        
        if(cursor != null){
        	cursor.setLocation(new Vector2f(cursorX, cursorY));		
        }
	}
	
    /**
     * Called by update() when mouse moves
     */
    public abstract void mouseUpdate(int x, int y, int w);
    
    /**
     * Called by update() when mouse button is pressed
     */
    public abstract void mouseDown(int event,int x, int y);

    /**
     * Called by update() when mouse button is released
     */
    public abstract void mouseUp(int event,int x, int y);

}
