--
-- Mouse utilities
--
function InitMouse ( )

	if mouse then
		function mouse.Press ( b )
			--
			-- Press
			--
			if mouse.OnPress then
				mouse.OnPress ( b, mouse.xaxis, mouse.yaxis )
			end

			if mouse.bstates[b] == 'ready' then

				mouse.timer:stop ( )
				mouse.timer:start ( )
				mouse.last_button = b
				mouse.bstates[b] = 'predouble'

			elseif mouse.bstates[b] == 'predouble' then

				if mouse.last_button == b then
					--
					-- DoubleClick
					--
					if mouse.OnDoubleClick then
						mouse.OnDoubleClick ( b, mouse.xaxis, mouse.yaxis )
					end
					mouse.timer:stop ( )
					mouse.bstates[b] = 'postdouble'
				else
					-- Cancel DoubleClick
					mouse.Tick ( mouse.timer )

					mouse.timer:stop ( )
					mouse.timer:start ( )
					mouse.last_button = b
					mouse.bstates[b] = 'predouble'
				end

			else

		--		assert ( false )

			end

		end

		function mouse.Release ( b )

			--
			-- Release
			--
			if mouse.OnRelease then
				mouse.OnRelease ( b, mouse.xaxis, mouse.yaxis )
			end

			if mouse.bstates[b] == 'drag' then

				--
				-- EndDrag
				--
				if mouse.OnEndDrag then
					mouse.OnEndDrag ( b, mouse.xaxis, mouse.yaxis )
				end
				mouse.bstates[b] = 'ready'

			elseif mouse.bstates[b] == 'predrag' then

				--
				-- SingleClick
				--
				if mouse.OnSingleClick then
					mouse.OnSingleClick ( mouse.last_button, mouse.xaxis, mouse.yaxis )
				end
				mouse.bstates[b] = 'ready'

			elseif mouse.bstates[b] == 'postdouble' then

				mouse.bstates[b] = 'ready'

			elseif mouse.bstates[b] == 'predouble' then

			else

		--		assert ( false )

			end

		end

		function mouse.Move ( x, y )

			if mouse.OnMove then
				mouse.OnMove ( mouse.xaxis, mouse.yaxis )
			end

			-- Cancel DoubleClick
			mouse.Tick ( mouse.timer )

			for i, v in pairs ( mouse.bstates ) do
				if v == 'drag' then

					--
					-- Dragging
					--
					if mouse.OnDragging then
						mouse.OnDragging ( i, mouse.xaxis, mouse.yaxis )
					end

				elseif v == 'predrag' then

					--
					-- BeginDrag
					--
					if mouse.OnBeginDrag then
						mouse.OnBeginDrag ( i, mouse.xaxis, mouse.yaxis )
					end
					mouse.bstates[i] = 'drag'

				end
			end

		end

		function mouse.Tick ( timer )

			mouse.timer:stop ( )

			if mouse.bstates[mouse.last_button] == 'predouble' then

				if mouse:is_down ( mouse.last_button ) then
					mouse.bstates[mouse.last_button] = 'predrag'
				else
					--
					-- SingleClick
					--
					if mouse.OnSingleClick then
						mouse.OnSingleClick ( mouse.last_button, mouse.xaxis, mouse.yaxis )
					end
					mouse.bstates[mouse.last_button] = 'ready'
				end

			end

		end

		function mouse.WheelMove ( z )

			if mouse.OnWheelMove then
				mouse.OnWheelMove ( z )
			end

		end

		mouse.timer = Timer ( )
		mouse.timer.interval = 300
		mouse.timer.recur = false
		mouse.timer.on_tick = mouse.Tick

		mouse.on_press = mouse.Press
		mouse.on_release = mouse.Release
		mouse.on_move = mouse.Move
		mouse.on_wheelmove = mouse.WheelMove
		mouse.bstates = {}
		mouse.bstates[MBUTTON_LEFT] = 'ready'
		mouse.bstates[MBUTTON_MIDDLE] = 'ready'
		mouse.bstates[MBUTTON_RIGHT] = 'ready'
		mouse.bstates[MBUTTON_X] = 'ready'
		mouse.last_button = nil
	end

end