/*
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 */

/*

The glass.jar in this example is in /Volumes/work/jfx/artifacts/sdk/build/lib/desktop/
The libglass.dylib in this example is in /Volumes/work/jfx/artifacts/sdk/rt/bin/

Adjust those paths below as needed

To compile:

javac -classpath /Volumes/work/jfx/artifacts/sdk/build/lib/desktop/glass.jar SimpleMouse.java

To run:

java -Djava.library.path=/Volumes/work/jfx/artifacts/sdk/rt/bin/ -classpath /Volumes/work/jfx/artifacts/sdk/build/lib/desktop/glass.jar:. SimpleMouse

*/

import com.sun.glass.ui.*;
import com.sun.glass.events.*;

import java.util.Map;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;

public class SimpleMouse implements Launchable
{
    Pixels pixels;
    
    public static void main(String args[])
    {
        Application.Run(args, new SimpleMouse());
    }
    
    public void finishLaunching(String[] args)
    {
        try
        {
            Application app = Application.GetApplication();
            app.setTerminateWhenLastWindowClosed(true);
            app.setEventHandler(new Application.EventHandler()
            {
                @Override
                public void handleQuitAction(Application app, long time)
                {
                    app.terminate();
                }
            });
            
            Window window = app.createWindow(Screen.getMainScreen(), Window.TITLED|Window.CLOSABLE);
            window.setEventHandler(new CloseEventHandler());
            
            MenuBar menuBar = app.createMenuBar();
            app.installDefaultMenus(menuBar);
            window.setMenuBar(menuBar);
            
            View view = app.createView(new PixelGraphics());
            view.setEventHandler(new ViewEventHandler());
            
            window.setView(view);
            window.setBackground(0, 0, 0);
            window.setTitle("");
            window.setPosition(101, 102);
            window.setContentSize(514, 515);
            
            ByteBuffer data = ByteBuffer.allocateDirect(4*window.getWidth()*window.getHeight());
            data.order(ByteOrder.nativeOrder());
            data.rewind();
            this.pixels = app.createPixels(window.getWidth(), window.getHeight(), data);
            
            window.setVisible(true);
        }
        catch (Throwable t)
        {
            System.err.println(t);
        }
    }
    
    class CloseEventHandler extends Window.EventHandler
    {
        @Override
        public void handleWindowEvent(Window window, long time, int type)
        {
            if (type == WindowEvent.CLOSE)
            {
                Application.GetApplication().terminate();
            }
        }
    }
    
    class ViewEventHandler extends View.EventHandler
    {
        long stamp = 0;
        int count = 0;
        
        void paint(int x, int y, int value, int width, int height)
        {
            ByteBuffer data = (ByteBuffer)pixels.getPixels();
            data.putInt(4*((y*width)+x), value);
        }
        
        @Override
        public void handleMouseEvent(View view, long time, int type, int button, int x, int y, int xAbs, int yAbs, int clickCount, int modifiers, boolean isPopupTrigger, boolean isSythesized)
        {
            if (this.stamp == 0)
            {
                this.stamp = time;
            }
            
            if ((time-this.stamp) > 1000000000)
            {
                view.getWindow().setTitle(this.count+" mouse events per second");
                this.stamp = time;
                this.count = 0;
            }
            else
            {
                this.count++;
            }
            
            if (type == MouseEvent.MOVE)
            {
                paint(x, y, 0xffffffff, view.getWidth(), view.getHeight());
                view.scheduleRepaint();
            }
            else if (type == MouseEvent.DRAG)
            {
                if ((x >= 0) && (x < view.getWidth()) && (y >= 0) && (y < view.getHeight()))
                {
                    paint(x, y, 0x00ffffff, view.getWidth(), view.getHeight());
                    view.scheduleRepaint();
                }
            }
        }
    }
    
    class PixelGraphics extends Pen
    {
        @Override
        public Map getCapabilities()
        {
            Map capabilities = addCapability(null, View.Capability.k3dKey, new Boolean(true));
            return addCapability(capabilities, View.Capability.k3dKey, new Boolean(true));
        }
        
        @Override
        public void paint(long time, int width, int height)
        {
            if (pixels != null)
            {
                getView().uploadPixels(pixels);
            }
        }
    }
}
