//[-------------------------------------------------------]
//[ Public virtual UpdateDevice functions                 ]
//[-------------------------------------------------------]
void AndroidKeyboardDevice::Update()
{
	// Check if input device is valid
	if (m_pDevice) {
		// Get keyboard device
		Keyboard *pKeyboard = static_cast<Keyboard*>(m_pDevice);

		// Process delayed keys
		for (uint32 i=0; i<m_lstDelayedKeys.GetNumOfElements(); i++) {
			const KeyInfo &sKeyInfo = m_lstDelayedKeys[i];

			// Get button
			Button *pButton = GetKeyboardKey(*pKeyboard, sKeyInfo.nKeyCode);
			if (pButton) {
				// Get button state
				const bool bPressed = sKeyInfo.bPressed;

				// Propagate changes
				if (pButton->IsPressed() != bPressed)
					pButton->SetPressed(bPressed);
			}
		}
		m_lstDelayedKeys.Clear();
		m_lstProcessedKeys.Clear();
	}
}
/**
*  @brief
*    Call this to process the next key input event
*/
void AndroidKeyboardDevice::OnKeyInputEvent(const struct AInputEvent &cAKeyInputEvent)
{
	// Check if input device is valid
	if (m_pDevice) {
		// Get Android key code
		const int32_t nKeyCode = AKeyEvent_getKeyCode(&cAKeyInputEvent);

		// Lookout! The virtual keyboard of Android sends "down" and "up" directly one after another
		// -> This is really a problem and we have to delay further keys...
		if (m_lstProcessedKeys.IsElement(nKeyCode)) {
			// Add key for later processing
			KeyInfo sKeyInfo;
			sKeyInfo.nKeyCode = nKeyCode;
			sKeyInfo.bPressed = (AKeyEvent_getAction(&cAKeyInputEvent) == AKEY_EVENT_ACTION_DOWN);
			m_lstDelayedKeys.Add(sKeyInfo);
		} else {
			// Get keyboard device
			Keyboard *pKeyboard = static_cast<Keyboard*>(m_pDevice);

			// Get button
			Button *pButton = GetKeyboardKey(*pKeyboard, nKeyCode);
			if (pButton) {
				// Get button state
				const bool bPressed = (AKeyEvent_getAction(&cAKeyInputEvent) == AKEY_EVENT_ACTION_DOWN);

				// Propagate changes
				if (pButton->IsPressed() != bPressed)
					pButton->SetPressed(bPressed);
			}

			// Add this key to the processed keys
			m_lstProcessedKeys.Add(nKeyCode);
		}
	}
}
/**
*  @brief
*    Performs the picking
*/
void MyPicking::PerformPicking()
{
	// Get the default input controller of the application
	Controller *pController = reinterpret_cast<Controller*>(m_pApplication->GetInputController());
	if (pController && pController->GetActive()) {
		// Get the "MouseLeft" control
		Control *pControl = pController->GetControl("MouseLeft");
		if (pControl && pControl->GetType() == ControlButton) {
			Button *pButton = reinterpret_cast<Button*>(pControl);
			SceneNode *pPickedSceneNode = nullptr;

			// If the left mouse button is currently down, do NOT perform new picking
			if (!pButton->IsPressed()) {
				// Get the current time data
				const uint64 nPastTime = Timing::GetInstance()->GetPastTime();

				// Perform mouse picking - do not make this test each frame because it may cost some performance
				if ((nPastTime-m_nLastPickingTime) > 100) {
					m_nLastPickingTime = nPastTime;

					// Perform picking - "PerformMousePicking()" is using the current mouse position inside the main window
					// and the currently used camera in order to find the scene node under the mouse cursor
					PickingResult cPickingResult;
					if (PerformMousePicking(cPickingResult))
						pPickedSceneNode = cPickingResult.GetSceneNode();
				} else {
					// Use the previous result
					pPickedSceneNode = m_cCurrentPickedSceneNodeHandler.GetElement();
				}

				// Picked changed?
				if (pPickedSceneNode != m_cCurrentPickedSceneNodeHandler.GetElement()) {
					// Backup the currently picked scene node
					m_cCurrentPickedSceneNodeHandler.SetElement(pPickedSceneNode);
				}
			}

			// Is currently anything picked?
			if (pButton->IsHit() && pPickedSceneNode) {
				// Toggle the debug mode of the picked scene node
				if (pPickedSceneNode->GetDebugFlags() & SceneNode::DebugEnabled) {
					// Disable debug mode
					pPickedSceneNode->SetDebugFlags(pPickedSceneNode->GetDebugFlags() & ~SceneNode::DebugEnabled);
				} else {
					// Enable debug mode
					pPickedSceneNode->SetDebugFlags(pPickedSceneNode->GetDebugFlags() |SceneNode::DebugEnabled);
				}
			}
		}
	}
}