@Override
  public EUpdateResult processMouseClick(IInput.MouseClick event) {
    if (event.pressed) {
      // force "repaint" with current brush
      if (event.button == IInput.EMouseButton.LEFT) brushes.current().forceRepaint();

      // change the brush colour
      else if (event.button == IInput.EMouseButton.MIDDLE) brushes.current().changeColour();
    }
    // all clear!
    return EUpdateResult.CONTINUE;
  }
  @Override
  public EUpdateResult processInput(IInput input) {
    // default input processing
    EUpdateResult result = super.processInput(input);
    if (result != EUpdateResult.CONTINUE) return result;

    // reset brush position
    brushes.current().setSize(1 / level.getCamera().getZoom()); // size first!
    brushes.current().setPosition(level.getCamera().getGlobal(input.getMousePosition()));

    // "paint" or erase using the current brush
    if (input.isMouseClicking(IInput.EMouseButton.LEFT)) {
      brushes.current().touch(level.tilegrid, false); // paint
      level.fog.recalculate();
    } else if (input.isMouseClicking(IInput.EMouseButton.RIGHT)) {
      brushes.current().touch(level.tilegrid, true); // erase
      level.fog.recalculate();
    }

    return EUpdateResult.CONTINUE;
  }
  @Override
  public void render(ICanvas canvas) {
    // draw gui
    canvas.setCameraActive(false);
    canvas.setColour(Colour.YELLOW);
    canvas.box(GUI_BOX, true);
    canvas.setColour(Colour.BLACK);
    for (int i = 0; i < gui_txt.length; i++) canvas.text(gui_txt[i], gui_pos[i]);

    // draw brush paint
    canvas.setCameraActive(true);
    brushes.current().render(canvas);
  }
  @Override
  public EUpdateResult processKeyPress(IInput.KeyPress event) {
    // default interactions
    EUpdateResult result = super.processKeyPress(event);
    if (result != EUpdateResult.CONTINUE) return result;

    // change brush
    if (event.pressed) {
      if (event.key != null)
        switch (event.key) {
          case L_SHIFT:
          case R_SHIFT:
            // change brush on SHIFT
            brushes.next();
            break;
        }
    }

    // all clear
    return EUpdateResult.CONTINUE;
  }