void mouse_position_callback(GLFWwindow* window, double xpos, double ypos)
{
    ServiceManager* sm = SystemManager::instance()->getServiceManager();
    sm->lockEvents();
    Event* evt = sm->writeHead();
    evt->reset(Event::Move, Service::Pointer);
    evt->setPosition((float)xpos, (float)ypos);
    evt->setFlags(sKeyFlags); 
    sm->unlockEvents();
}
void mouse_scroll_callback(GLFWwindow* window, double x, double y)
{
    ServiceManager* sm = SystemManager::instance()->getServiceManager();
    sm->lockEvents();
    Event* evt = sm->writeHead();

    evt->reset(Event::Zoom, Service::Pointer);
    evt->setExtraDataType(Event::ExtraDataIntArray);
    evt->setExtraDataInt(0, (int)y);
    evt->setFlags(sKeyFlags);
    sm->unlockEvents();
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    // Ignore repeat events
    if (action == GLFW_REPEAT) return;

    ServiceManager* sm = SystemManager::instance()->getServiceManager();
    sm->lockEvents();
    Event* evt = sm->writeHead();

    Event::Type et = Event::Down;
    if (action == GLFW_RELEASE) et = Event::Up;
 
 
    evt->reset(et, Service::Keyboard, key);
    evt->setExtraDataType(EventBase::ExtraDataIntArray);
    evt->setExtraDataInt(0, scancode);

    uint keyFlagsToRemove = 0;

    HANDLE_KEY_FLAG(KEY_LEFT_ALT, Alt);
    HANDLE_KEY_FLAG(KEY_LEFT_SHIFT, Shift);
    HANDLE_KEY_FLAG(KEY_LEFT_CONTROL, Ctrl);
    HANDLE_KEY_FLAG(KEY_RIGHT_ALT, Alt);
    HANDLE_KEY_FLAG(KEY_RIGHT_SHIFT, Shift);
    HANDLE_KEY_FLAG(KEY_RIGHT_CONTROL, Ctrl);

    HANDLE_KEY_FLAG(KEY_LEFT, ButtonLeft);
    HANDLE_KEY_FLAG(KEY_RIGHT, ButtonRight);
    HANDLE_KEY_FLAG(KEY_UP, ButtonUp);
    HANDLE_KEY_FLAG(KEY_DOWN, ButtonDown);

    HANDLE_KEY_FLAG(KEY_ENTER, Button4);
    //HANDLE_KEY_FLAG(KEY_BACKSPACE, Button5);
    HANDLE_KEY_FLAG(KEY_TAB, Button6);
    HANDLE_KEY_FLAG(KEY_HOME, Button7);

    evt->setFlags(sKeyFlags);

    // Remove the bit of all buttons that have been unpressed.
    sKeyFlags &= ~keyFlagsToRemove;

    // If ESC is pressed, request exit.
    if (evt->isKeyDown(KEY_ESCAPE)) SystemManager::instance()->postExitRequest();

    sm->unlockEvents();
}
void char_callback(GLFWwindow* window, unsigned int codepoint)
{
    ServiceManager* sm = SystemManager::instance()->getServiceManager();
    sm->lockEvents();
    char aChar = (char)codepoint;
    String evtStr = string(1,aChar);
    //omsg("creating Character Event");
    Event* evt = sm->writeHead();
    Event::Type et = Event::Down;
    evt->reset(et, Service::Keyboard, 0);

    
    evt->setExtraDataType(EventBase::ExtraDataString);
    evt->setExtraDataString(evtStr);
    evt->setFlags(sKeyFlags); 
    // int evtkey = key;
    // evt->reset(et, Service::Keyboard, evtkey);

    sm->unlockEvents();
}
void mouse_button_callback(GLFWwindow* window, int key, int action, int mods)
{
    ServiceManager* sm = SystemManager::instance()->getServiceManager();
    sm->lockEvents();
    Event* evt = sm->writeHead();

    Event::Type et = Event::Down;
    if (action == GLFW_RELEASE) et = Event::Up;

    evt->reset(et, Service::Pointer);

    uint keyFlagsToRemove = 0;

    HANDLE_KEY_FLAG(GLFW_MOUSE_BUTTON_1, Button1);
    HANDLE_KEY_FLAG(GLFW_MOUSE_BUTTON_2, Button2);
    HANDLE_KEY_FLAG(GLFW_MOUSE_BUTTON_3, Button3);

    evt->setFlags(sKeyFlags);
    sKeyFlags &= ~keyFlagsToRemove;
    sm->unlockEvents();
}