

mouse.down    = {}
mouseUpSet 		= false
mouse.down.LSet 	= false
mouse.down.L 		= false

mouseUpRSet 	= false
mouse.down.RSet 	= false
mouse.down.R 		= false

mouseScroll 	= {x=0,y=0}
mouse.locked 	= false
mouse.doubleTime= 16
mouse.tripleTime= 24
mouse.time 		= 0
mouse.double 	= false
mouse.triple 	= false
mouse.L 		= {func=function()end,release=false}
mouse.R 		= {func=function()end,release=false}
mouse.M 		= {func=function()end,release=false}
mouse.clicks 	= {}
mouse.releases 	= {}
mouse.start = {x=0,y=0}
thingsToScroll = {}

local empty = {}
function mouse.set(func,release)
	if not mouse.locked then
		if type(func)=="table"then 
			mouse.L = {func=type(func[1])=="table" and func[1][1] or func[1],arg=lume.slice(func,2) ,release=release or false}
		else
			mouse.L = {func=func,release=release or false}
		end
	end
end
function mouse.setR(func,release)
	if not mouse.locked then 
		if type(func)=="table"then 
			mouse.R = {func=type(func[1])=="table" and func[1][2] or func[1],arg=lume.slice(func,2) ,release=release or false}
		else
			mouse.R = {func=func,release=release or false}
		end
	end
end
function mouse.setM(func,release)
	if not mouse.locked then 
		mouse.M = {func=func,release=release or false}
	end
end

function mouse.push(f)
 	mouse.pushDown(f)
 	mouse.pushUp(f)
end

function mouse.pushDown(f,...)
	mouse.pushClick(f,arg)
	mouse.pushClickR(f,arg)
end
function mouse.pushUp(f,...)
	mouse.pushRelease(f,arg)
	mouse.pushReleaseR(f,arg)
end


function mouse.pushClick(f,...)
	table.insert(mouse.clicks,1,{f=f,args=arg,button=1})
end
function mouse.pushClickR(f,...)
	table.insert(mouse.clicks,1,{f=f,args=arg,button=2})
end
function mouse.pushClickM(f,...)
	table.insert(mouse.clicks,1,{f=f,args=arg,button=3})
end


function mouse.pushRelease(f,...)
	table.insert(mouse.releases,1,{f=f,args=arg,button=1})
end
function mouse.pushReleaseR(f,...)
	table.insert(mouse.releases,1,{f=f,args=arg,button=2})
end
function mouse.pushReleaseM(f,...)
	table.insert(mouse.releases,1,{f=f,args=arg,button=3})
end


function mouse.pressed( x, y, button)
	mouse.line = {}
	mouse.start.x,mouse.start.y=mouse.x,mouse.y
	if mouse.double and mouse.time<mouse.tripleTime then
		mouse.triple=true
	else 
		mouse.triple = false
	end
	if mouse.double then 
		mouse.double=false
	elseif mouse.time<mouse.doubleTime then
		mouse.double=true
	end

	mouse.time = 0
	mouseStored=lume.clone(mouse)
	if not mouse.L.release and button ==1 then
		mouse.L.func(unpack(mouse.L.arg or empty))
	end
	if not mouse.R.release and button==2 then
		mouse.R.func(unpack(mouse.L.arg or empty))
	end
	if not mouse.M.release and button==3 then
		mouse.M.func()
	end
	if button == 1 then 
		mouse.down.LSet = true
	end
	local clicked = false
	for c,click in ipairs(mouse.clicks) do
		if button == click.button and (click.f(unpack(click.args))==true)   then 
			clicked = true
		end
	end
end


function mouse.released(x, y, button)
	if mouse.L.release and button ==1 then
		mouse.L.func(unpack(mouse.L.arg or empty))
	end
	if mouse.R.release and button==2 then
		mouse.R.func(unpack(mouse.L.arg or empty))
	end
	if mouse.M.release and button==3 then
		mouse.M.func()
	end
	if button == 1 then 
		mouseUpSet = true
	end
	local released = false
	for c,release in ipairs(mouse.releases) do
		if button == release.button and  (release.f(unpack(release.args)))  then 
			released = true
		end
	end
end


function mouse.reset()
	
	mouse.down.L 		= lmouse.isDown(1) 
	mouse.down.R 		= lmouse.isDown(2) 
	mouse.down.M 		= lmouse.isDown(3) 
	mouse.down.LSet 	= false
	mouseUpSet 		= false
	mouse.active 	= ( mouse.down.L or mouse.down.R or mouse.x~=mouse.px or mouse.y~=mouse.py  or mouseScroll.x~=0 or mouseScroll.y~=0) 
end


function mouse.wheelmoved( x, y )
	for i,v in ipairs(thingsToScroll) do 
		local dir = v.h and x or y 
		v.v[v.k] = v.v[v.k] + dir*v.s
	end
	thingsToScroll = {}
	mouseScroll = {x=easeTo(mouseScroll.x,x,2,1),y=easeTo(mouseScroll.y,y,loSpec and 8 or 2,1)}
end

function mouse.mousemoved(x, y, dx, dy)

	local Dx,Dy = dx or 0,dy or 0

	mouse.dx = dx
	mouse.dy = dy
	local mode = (cam and not editor.orbiting and (cam.locked or mouse.down.M) and editState == "Panning") and 1 or (lmouse.getRelativeMode() and 2 or 0)
	local speed = mode== 1 and -0.2/cam.zoom or 1
	if mode==1 or mode==2  then
		cam.angle.tx = cam.angle.tx + math.rad(Dx * speed * 0.2)
		cam.angle.ty = mc(-pi/2,cam.angle.ty - math.rad(Dy * speed * (mode==1 and 0.2 or 0.1)),pi/2)
	end
	
end

function mouse.penmoved(x,y,z,pressure,pitch,yaw,roll)
	-- print("pressure",pressure)
	mouse.pressure = pressure
end

-----------------------------------------------------------
-- LEFT MOUSE
-----------------------------------------------------------
function mouse.clickIn(bounds)
	local rval = false
	if mouse.x>bounds.x and 
		mouse.x<bounds.x+bounds.w and 
		mouse.y>bounds.y and 
		mouse.y<bounds.y+bounds.h then

		rval= mouse.click()
	end
	return rval
end

function mouse.click(func)
	if mouse.down.LSet then 
		local func = func or function() end
		func()
		return true
	else 
		return false
	end
end

function mouse.release(func)
	if mouseUpSet then 
		local func = func or function() end
		func()
		return true
	else 
		return false
	end
end

-----------------------------------------------------------
-- RIGHT MOUSE
-----------------------------------------------------------
function mouse.clickR(func)
	local func = func or function() end
	local rval = false
	if(not mouse.down.R and lmouse.isDown(2)) then
		func()
		mouse.down.LSet=false
		mouse.down.RSet=true
		rval=true
	end
	return rval
end

function mouse.releaseR(func)
	local func = func or function() end
	local rval = false
	if(mouse.down.R and not lmouse.isDown(2) ) then
		func()
		mouse.down.RSet=false
		rval=true
	end
	return rval
end

-----------------------------------------------------------
-- CHECK MOUSE COORDS (GLOBAL) AGAINST BOX, USEFUL FOR BUTTONS
-----------------------------------------------------------
local tempRect,tempMoose={},{}
function mouseIn(rect,moose, w,h, mx,my)
	if w and h then 
		tempRect.x=rect
		tempRect.y=moose
		tempRect.w=w
		tempRect.h=h
		rect = tempRect
		moose = nil
	end
	tempMoose.x,tempMoose.y=mx or mouse.x,my or mouse.y
	if (not mouse.locked) and rect and rect.x and rect.y and (rect.w or rect.width) and (rect.h or rect.height)  then  	

		return simplePointInRect(moose or tempMoose,rect)
	else 
		return  false
	end
end

function mouseInRes(rect)
	return (not mouse.locked and simplePointInRect({x=mouse.x*game.resolution,y=mouse.y*game.resolution},rect))
end

function mouseInBounds(rect, coords)
	return (coords.x>rect[1] and coords.x<rect[3] and coords.y>rect[2] and coords.y<rect[4])
end

function mouseInC(circ)
	return math.dist(mouse.x or 0,mouse.y or 0,circ.x,circ.y)<circ.r
end

-----------------------------------------------------------
-- LOCK MOUSE
-----------------------------------------------------------
function lockMouse()
	--mouse.setR(function ()end)
	mouse.locked 	= true
	--mouse.x 		= -100
	--mouse.y 		= -100
end
function unlockMouse() 	
	mouse.locked 	= false
	mouse.x 		= lmouse.getX()
	mouse.y 		= lmouse.getY()
end

function getMouse()
	log("getmouse",lmouse.getX(),lmouse.getY())
 	return {x=lmouse.getX(),y=lmouse.getY()}
end




