void Application::fireEvent(const InputEvent& event) {
    if (event.type == InputType::Cursor
            || event.type == InputType::MouseButton) {
        context->requestUpdateCursor();
    }
    bool consumed = false;
    if (event.type == InputType::Scroll && context->mouseOverRegion != nullptr
            && context->mouseOverRegion->onScroll) {
        consumed = context->mouseOverRegion->onScroll(context.get(), event);
    } else if (event.type == InputType::MouseButton) {
        if (event.isDown()) {
            if (event.button == GLFW_MOUSE_BUTTON_LEFT) {
                context->leftMouseButton = true;
            }
            if (event.button == GLFW_MOUSE_BUTTON_RIGHT) {
                context->rightMouseButton = true;
            }
            context->mouseOverRegion = context->mouseFocusRegion =
                                           context->mouseDownRegion = context->locate(
                                                   context->cursorPosition);

            if (context->mouseDownRegion != nullptr) {
                context->cursorDownPosition = event.cursor
                                              - context->mouseDownRegion->getBoundsPosition();
            }
        } else if (event.isUp()) {

            if (context->mouseDownRegion != nullptr
                    && context->getOnTopRegion() == context->mouseDownRegion
                    && context->mouseDownRegion->isDragEnabled()) {
                context->removeOnTopRegion(context->mouseDownRegion);
            }

            context->leftMouseButton = false;
            context->rightMouseButton = false;
            context->mouseDownRegion = nullptr;
            context->cursorDownPosition = pixel2(0, 0);
        }
    }

    //Fire events
    if (context->mouseDownRegion != nullptr
            && event.type != InputType::MouseButton
            && context->mouseDownRegion->isDragEnabled()) {
        if (context->mouseDownRegion->onMouseDrag) {
            consumed |= context->mouseDownRegion->onMouseDrag(context.get(),
                        event);
        } else {
            if (context->leftMouseButton) {
                //context->setOnTopRegion(context->mouseDownRegion);
                context->mouseDownRegion->setDragOffset(
                    context->cursorPosition,
                    context->cursorDownPosition);
            }
        }
        context->requestPack();
    } else if (context->mouseOverRegion != nullptr) {
        if (event.type == InputType::MouseButton) {
            if (event.isDown()) {
                if (context->mouseOverRegion->onMouseDown) {
                    consumed |= context->mouseOverRegion->onMouseDown(
                                    context.get(), event);
                } else if (context->mouseDownRegion->isDragEnabled()) {
                    //context->setOnTopRegion(context->mouseDownRegion);
                    context->mouseDownRegion->setDragOffset(
                        context->cursorPosition,
                        context->cursorDownPosition);
                }
            }
            if (context->mouseOverRegion!=nullptr&&context->mouseOverRegion->onMouseUp && event.isUp())
                consumed |= context->mouseOverRegion->onMouseUp(context.get(),
                            event);
            context->requestPack();
        }
        if (event.type == InputType::Cursor) {
            if (context->mouseOverRegion != nullptr
                    && context->mouseOverRegion->onMouseOver) {
                consumed |= context->mouseOverRegion->onMouseOver(context.get(),
                            event);
            }
        }
    }
    if (!consumed) {
        consumed = context->fireListeners(event);
    }
    if (consumed)
        context->dirtyUI = true;
}