//
// PlayN Performance Tests
// http://github.com/threerings/playn-perf/blob/master/LICENSE

package com.threerings.perf.core;

import java.util.HashSet;
import java.util.Set;

import react.Value;

import playn.core.Image;
import playn.core.Keyboard;
import playn.core.Mouse;
import playn.core.Pointer;
import playn.core.gl.GLContext;
import static playn.core.PlayN.*;

import tripleplay.game.Screen;
import tripleplay.util.Hud;
import tripleplay.util.Ref;

/**
 * The base class for a performance test.
 */
public abstract class AbstractTest extends Screen
{
    /** Called when the user taps/clicks once. */
    public void onTap () {
    }

    @Override public void wasShown () {
        super.wasShown();
        _hud.add("Shader info:", true);
        _hud.add(_quadShader);
        _hud.add(_trisShader);
        _hud.add("Per second:", true);
        _hud.add("Frames:", _frames);
        _hud.add("Shader creates:", _shaderCreates);
        _hud.add("FB creates:", _fbCreates);
        _hud.add("Tex creates:", _texCreates);
        _hud.add("Per frame:", true);
        _hud.add("Shader binds:", _shaderBinds);
        _hud.add("FB binds:", _fbBinds);
        _hud.add("Tex binds:", _texBinds);
        _hud.add("Quads drawn:", _rQuads);
        _hud.add("Tris drawn:", _rTris);
        _hud.add("Shader flushes:", _shaderFlushes);
        addHudBits(_hud);
        _hud.layer.setDepth(Short.MAX_VALUE);
        layer.add(_hud.layer);

        // wire up listeners for tapping and going back to the menu
        _hud.layer.addListener(new Mouse.LayerAdapter() {
            @Override public void onMouseDown(Mouse.ButtonEvent event) {
                switch (event.button()) {
                case Mouse.BUTTON_RIGHT: pop(); break;
                default: break;
                }
            }
        });
        _hud.layer.addListener(new Pointer.Adapter() {
            @Override public void onPointerStart(Pointer.Event event) {
                _tapStart = currentTime();
            }
            @Override public void onPointerEnd(Pointer.Event event) {
                double duration = currentTime() - _tapStart;
                if (duration > 1000) pop();
                else onTap();
            }
            @Override public void onPointerCancel(Pointer.Event event) {
            }
            protected double _tapStart;
        });
        keyboard().setListener(new Keyboard.Adapter() {
            @Override public void onKeyDown(Keyboard.Event event) {
                switch (event.key()) {
                case ESCAPE:
                case BACK: pop(); break;
                case SPACE: onTap(); break;
                default: break;
                }
            }
        });
    }

    @Override public void wasHidden () {
        super.wasHidden();
        keyboard().setListener(null);
    }

    @Override public void update (float delta) {
        super.update(delta);
        long now = System.currentTimeMillis();
        if (now > _nextSec) {
            GLContext.Stats stats = graphics().ctx().stats();
            int frames = Math.max(stats.frames, 1);
            _frames.update(frames);
            _shaderCreates.update(stats.shaderCreates);
            _fbCreates.update(stats.frameBufferCreates);
            _texCreates.update(stats.texCreates);
            _shaderBinds.update(stats.shaderBinds/frames);
            _fbBinds.update(stats.frameBufferBinds/frames);
            _texBinds.update(stats.texBinds/frames);
            _rQuads.update(stats.quadsRendered/frames);
            _rTris.update(stats.trisRendered/frames);
            _shaderFlushes.update(stats.shaderFlushes/frames);
            stats.reset();
            _quadShader.update("Quad: " + graphics().ctx().quadShaderInfo());
            _trisShader.update("Tris: " + graphics().ctx().trisShaderInfo());
            _hud.update();
            _nextSec = now + 1000;
        }
    }

    protected void pop () {
        PerfTest.stack.remove(this);
    }

    protected Image getImage (String path) {
        return assets().getImage("images/" + path);
    }

    /** Override this and add UI elements to the HUD as needed. */
    protected void addHudBits (Hud hud) {
    }

    private final Hud _hud = new Hud();
    private long _nextSec;

    private final Value<Integer> _frames = Value.create(0);
    private final Value<Integer> _shaderCreates = Value.create(0);
    private final Value<Integer> _fbCreates = Value.create(0);
    private final Value<Integer> _texCreates = Value.create(0);
    private final Value<Integer> _shaderBinds = Value.create(0);
    private final Value<Integer> _fbBinds = Value.create(0);
    private final Value<Integer> _texBinds = Value.create(0);
    private final Value<Integer> _rQuads = Value.create(0);
    private final Value<Integer> _rTris = Value.create(0);
    private final Value<Integer> _shaderFlushes = Value.create(0);

    private final Value<String> _quadShader = Value.create("");
    private final Value<String> _trisShader = Value.create("");
}

@@ -708,640 +708,8 @@
 ();%0A
-        _hud.add(%22Shader info:%22, true);%0A        _hud.add(_quadShader);%0A        _hud.add(_trisShader);%0A        _hud.add(%22Per second:%22, true);%0A        _hud.add(%22Frames:%22, _frames);%0A        _hud.add(%22Shader creates:%22, _shaderCreates);%0A        _hud.add(%22FB creates:%22, _fbCreates);%0A        _hud.add(%22Tex creates:%22, _texCreates);%0A        _hud.add(%22Per frame:%22, true);%0A        _hud.add(%22Shader binds:%22, _shaderBinds);%0A        _hud.add(%22FB binds:%22, _fbBinds);%0A        _hud.add(%22Tex binds:%22, _texBinds);%0A        _hud.add(%22Quads drawn:%22, _rQuads);%0A        _hud.add(%22Tris drawn:%22, _rTris);%0A        _hud.add(%22Shader flushes:%22, _shaderFlushes);%0A
     
@@ -2285,2111 +2285,376 @@
     
-long now = System.currentTimeMillis();%0A        if (now %3E _nextSec) %7B%0A            GLContext.Stats stats = graphics().ctx().stats();%0A            int frames = Math.max(stats.frames, 1);%0A            _frames.update(frames);%0A            _shaderCreates.update(stats.shaderCreates);%0A            _fbCreates.update(stats.frameBufferCreates);%0A            _texCreates.update(stats.texCreates);%0A            _shaderBinds.update(stats.shaderBinds/frames);%0A            _fbBinds.update(stats.frameBufferBinds/frames);%0A            _texBinds.update(stats.texBinds/frames);%0A            _rQuads.update(stats.quadsRendered/frames);%0A            _rTris.update(stats.trisRendered/frames);%0A            _shaderFlushes.update(stats.shaderFlushes/frames);%0A            stats.reset();%0A            _quadShader.update(%22Quad: %22 + graphics().ctx().quadShaderInfo());%0A            _trisShader.update(%22Tris: %22 + graphics().ctx().trisShaderInfo());%0A            _hud.update();%0A            _nextSec = now + 1000;%0A        %7D%0A    %7D%0A%0A    protected void pop () %7B%0A        PerfTest.stack.remove(this);%0A    %7D%0A%0A    protected Image getImage (String path) %7B%0A        return assets().getImage(%22images/%22 + path);%0A    %7D%0A%0A    /** Override this and add UI elements to the HUD as needed. */%0A    protected void addHudBits (Hud hud) %7B%0A    %7D%0A%0A    private final Hud _hud = new Hud();%0A    private long _nextSec;%0A%0A    private final Value%3CInteger%3E _frames = Value.create(0);%0A    private final Value%3CInteger%3E _shaderCreates = Value.create(0);%0A    private final Value%3CInteger%3E _fbCreates = Value.create(0);%0A    private final Value%3CInteger%3E _texCreates = Value.create(0);%0A    private final Value%3CInteger%3E _shaderBinds = Value.create(0);%0A    private final Value%3CInteger%3E _fbBinds = Value.create(0);%0A    private final Value%3CInteger%3E _texBinds = Value.create(0);%0A    private final Value%3CInteger%3E _rQuads = Value.create(0);%0A    private final Value%3CInteger%3E _rTris = Value.create(0);%0A    private final Value%3CInteger%3E _shaderFlushes = Value.create(0);%0A%0A    private final Value%3CString%3E _quadShader = Value.create(%22%22);%0A    private final Value%3CString%3E _trisShader = Value.create(%22%22
+_hud.update(delta);%0A    %7D%0A%0A    protected void pop () %7B%0A        PerfTest.stack.remove(this);%0A    %7D%0A%0A    protected Image getImage (String path) %7B%0A        return assets().getImage(%22images/%22 + path);%0A    %7D%0A%0A    /** Override this and add UI elements to the HUD as needed. */%0A    protected void addHudBits (Hud hud) %7B%0A    %7D%0A%0A    private final Hud.Stock _hud = new Hud.Stock(
 );%0A%7D

Use the stock hud.