void BoardMenuRangeValueCompactGeometry::processEvent(InteractionEvent * event)
{
    if(event->asMouseEvent())
    {
        MouseInteractionEvent * mie = event->asMouseEvent();
        if(event->getInteraction() == BUTTON_DOWN
                || event->getInteraction() == BUTTON_DOUBLE_CLICK)
        {
            int x, y;

            x = mie->getX();
            y = mie->getY();

            _lastMouseX = x;
            _lastMouseY = y;
            return;
        }
        if(event->getInteraction() == BUTTON_DRAG
                || event->getInteraction() == BUTTON_UP)
        {
            int x, y;
            x = mie->getX();
            y = mie->getY();

            MenuRangeValueCompact * mrv = (MenuRangeValueCompact*)_item;

	    float min,max,current;

	    if(mrv->getIsLog())
	    {
		min = log(mrv->getMin()) / log(mrv->getLogBase());
		max = log(mrv->getMax()) / log(mrv->getLogBase());
		current = log(mrv->getValue()) / log(mrv->getLogBase());
	    }
	    else
	    {
		min = mrv->getMin();
		max = mrv->getMax();
		current = mrv->getValue();
	    }

            float pixelRange = 800;

            bool valueUpdated = false;
            if(x > _lastMouseX)
            {
                if(mrv->getValue() != mrv->getMax())
                {
                    float change = (x - _lastMouseX)
                            * (max - min) / pixelRange;
			    
		    float newValue;

		    if(mrv->getIsLog())
		    {
			newValue = pow(mrv->getLogBase(),current + change);
			newValue = std::max(newValue, mrv->getMin());
		    }
		    else
		    {
			newValue = std::max(mrv->getValue() + change,
                            mrv->getMin());
		    }
                    mrv->setValue(newValue);
                    valueUpdated = true;
                }
            }
            else if(x < _lastMouseX)
            {
                if(mrv->getValue() != mrv->getMin())
                {
                    float change = (x - _lastMouseX)
                            * (max - min) / pixelRange;
                    float newValue;
		    
		    if(mrv->getIsLog())
		    {
			newValue = pow(mrv->getLogBase(),current + change);
			newValue = std::min(newValue, mrv->getMax());
		    }
		    else
		    {
			newValue = std::min(mrv->getValue() + change,
                            mrv->getMax());
		    }
                    mrv->setValue(newValue);
                    valueUpdated = true;
                }
            }

            if(valueUpdated)
            {
                if(mrv->getCallback())
                {
                    mrv->getCallback()->menuCallback(_item, event->asHandEvent() ? event->asHandEvent()->getHand() : 0);
                }
            }

            _lastMouseY = y;
            _lastMouseX = x;
            return;
        }
    }
    else if(event->asTrackedButtonEvent())
    {
        TrackedButtonInteractionEvent * tie = event->asTrackedButtonEvent();
        if(event->getInteraction() == BUTTON_DOWN
                || event->getInteraction() == BUTTON_DOUBLE_CLICK)
        {
	    if(event->asPointerEvent())
	    {
		SceneManager::instance()->getPointOnTiledWall(tie->getTransform(),_point);
	    }
	    else
	    {
		_point = tie->getTransform().getTrans();
		osg::Vec3 forward = osg::Vec3(0,1.0,0) * tie->getTransform();
		forward = forward - _point;
		_normal = forward ^ osg::Vec3(0,0,1.0);
		_normal.normalize();
	    }
            _lastDistance = 0.0;
            return;
        }
        if(event->getInteraction() == BUTTON_DRAG
                || event->getInteraction() == BUTTON_UP)
        {
            MenuRangeValueCompact * mrv = (MenuRangeValueCompact*)_item;

	    float min,max,current;

	    if(mrv->getIsLog())
	    {
		min = log(mrv->getMin()) / log(mrv->getLogBase());
		max = log(mrv->getMax()) / log(mrv->getLogBase());
		current = log(mrv->getValue()) / log(mrv->getLogBase());
	    }
	    else
	    {
		min = mrv->getMin();
		max = mrv->getMax();
		current = mrv->getValue();
	    }

	    float newDistance;
	    float range;

	    if(tie->asPointerEvent())
	    {
		osg::Vec3 newPoint;
		SceneManager::instance()->getPointOnTiledWall(tie->getTransform(),newPoint);
		newDistance = newPoint.z() - _point.z();
		range = SceneManager::instance()->getTiledWallHeight() * 0.6;
	    }
	    else
	    {
		osg::Vec3 vec = tie->getTransform().getTrans();
		vec = vec - _point;
		newDistance = vec * _normal;
		range = 1000;
	    }

            bool valueUpdated = false;
            if(newDistance < _lastDistance)
            {
                if(mrv->getValue() != mrv->getMin())
                {
                    float change = (newDistance - _lastDistance)
                            * (max - min) / range;
                    float newValue;
		    
		    if(mrv->getIsLog())
		    {
			newValue = pow(mrv->getLogBase(),current + change);
			newValue = std::max(newValue, mrv->getMin());
		    }
		    else
		    {
			newValue = std::max(mrv->getValue() + change,
                            mrv->getMin());
		    }
                    mrv->setValue(newValue);
                    valueUpdated = true;
                }
            }
            else if(newDistance > _lastDistance)
            {
                if(mrv->getValue() != mrv->getMax())
                {
                    float change = (newDistance - _lastDistance)
                            * (max - min) / range;
                    float newValue;
		    
		    if(mrv->getIsLog())
		    {
			newValue = pow(mrv->getLogBase(),current + change);
			newValue = std::min(newValue, mrv->getMax());
		    }
		    else
		    {
			newValue = std::min(mrv->getValue() + change,
                            mrv->getMax());
		    }
                    mrv->setValue(newValue);
                    valueUpdated = true;
                }
            }

            if(valueUpdated)
            {
                if(mrv->getCallback())
                {
                    mrv->getCallback()->menuCallback(_item, event->asHandEvent() ? event->asHandEvent()->getHand() : 0);
                }
            }

            _lastDistance = newDistance;

            return;
        }
    }
}
bool BoardPopupMenu::processEvent(InteractionEvent * event)
{
    if(!_menuActive || !_myMenu || !event->asTrackedButtonEvent())
    {
        return false;
    }

    TrackedButtonInteractionEvent * tie = event->asTrackedButtonEvent();

    if(_clickActive)
    {
        if(tie->getHand() == _activeHand)
        {
            if(tie->getInteraction() == BUTTON_DRAG
                    || tie->getInteraction() == BUTTON_UP)
            {
                if(tie->getButton() == _primaryButton)
                {
                    BoardMenuSubMenuGeometry * smg =
                            dynamic_cast<BoardMenuSubMenuGeometry *>(_activeItem);
                    if(smg && smg->isMenuHead())
                    {
                        updateMovement(tie);
                    }

                    _activeItem->processEvent(event);
                    if(tie->getInteraction() == BUTTON_UP)
                    {
                        _clickActive = false;
                    }
                    return true;
                }
            }
        }
        return false;
    }
    else if(tie->getHand() == _activeHand && tie->getButton() == _primaryButton)
    {
        if(tie->getInteraction() == BUTTON_DOWN
                || tie->getInteraction() == BUTTON_DOUBLE_CLICK)
        {
            if(_activeItem)
            {
                BoardMenuSubMenuGeometry * smg =
                        dynamic_cast<BoardMenuSubMenuGeometry *>(_activeItem);
                if(smg && smg->isMenuHead())
                {
                    osg::Vec3 ray;
                    ray = _currentPoint[tie->getHand()]
                            - tie->getTransform().getTrans();

		    if(!tie->asPointerEvent())
		    {
			_moveDistance = ray.length();
		    }
		    else
		    {
			_moveDistance = ray.y();
		    }
                    _menuPoint = _currentPoint[tie->getHand()]
                            * osg::Matrix::inverse(_menuRoot->getMatrix());
                    updateMovement(tie);
                }
                else if(smg && !smg->isMenuHead())
                {
                    if(smg->isMenuOpen())
                    {
                        closeMenu((SubMenu*)smg->getMenuItem());
                    }
                    else
                    {
                        openMenu(smg);
                    }
                }
		_clickActive = true;
                _activeItem->processEvent(event);
                return true;
            }

            return false;
        }
    }

    return false;
}