
function editor.shapeEditor(target,scale,previewArea,activeArea,size)
	local scale 		= scale or 1
	local activeArea 	= activeArea or previewArea
	local size  		= size or previewArea
	local res 			= previewArea.res or 1
	local dotSize 		= (previewArea.dotSize or 8)*res
	local changeState 	= editState=="Viewport" and "Normal" or editState

	if not stageHovered then return end

	previewArea.limit 	= previewArea.limit or function() return true end
	target.draggingPoint=target.draggingPoint or {i=0,j=0}
	
	shapeEditMouse =  ((mouseIn(previewArea) or previewArea.out)) and { x=(mouse.x - activeArea.x)/(size.w*scale), y=(mouse.y - activeArea.y)/(size.h*scale)} 
							or 	{x=shapeEditMouse.x, 	y=shapeEditMouse.y}

	for i,s in lume.ripairs (target.shapes) do 
		
		local 	tempPoly 		= {}
		local 	shapeHovered 	= target.polys and point_in_poly(target.polys[i],shapeEditMouse) or false

		target.polys = target.polys or {}
		target.polys[i]={}

		for j,p in lume.ripairs(s) do
			p.sx = p.x
			p.sy = p.y
			-- CURRENT POINT
			local point = { 	x 	= activeArea.x + size.w * scale * p.x,
								y 	= activeArea.y + size.h * scale * p.y 	}
			-- LAST POINT (FOR LINES)
			local prevpoint = { x 	= activeArea.x + size.w *scale*s[(j>1) and j-1 or #s].x,
								y 	= activeArea.y + size.h *scale*s[(j>1) and j-1 or #s].y 	}
			-- LINE
			local lineHovered 		= false

			-- MOVE POINT TO MOUSE
			local dragging = target.draggingPoint.i==i and  target.draggingPoint.j==j

			if  mouseIn(previewArea) and previewArea.limit() and target.draggingPoint.i==0 and  target.draggingPoint.j==0 then
				point.hovered 			= (math.dist(point.x,point.y, mouse.x,mouse.y)<dotSize)
				point.near 				= (math.dist(point.x,point.y, mouse.x,mouse.y)<dotSize*2)
				prevpoint.hovered 		= (math.dist(prevpoint.x,prevpoint.y, mouse.x,mouse.y)<dotSize)
				prevpoint.near 			= (math.dist(prevpoint.x,prevpoint.y, mouse.x,mouse.y)<dotSize*2)	
				lineHovered 		 	= distPointToLineSegment({mouse.x,mouse.y},{point.x,point.y},{prevpoint.x,prevpoint.y})<dotSize/4
			end

			-- START DRAGGING POINT
			mouse.pushClick(function()
				p.dx = shapeEditMouse.x-p.x
				p.dy = shapeEditMouse.y-p.y

				if point.hovered then
					target.draggingPoint = {i=i ,  j=j}  
				elseif keyDown("v") and shapeHovered then 
					changeState="Viewport"
					target.draggingPoint ={i=i ,  j=0}  
				end
	 		end)

			if p.dx and ((target.draggingPoint.i==i and target.draggingPoint.j==j) or (keyDown("v") and target.draggingPoint.j==0 and target.draggingPoint.i==i)) then
				local offset 	= (activeArea.x-previewArea.x)/previewArea.w
				p.x 			= mc(-offset,  shapeEditMouse.x-p.dx, 1-offset)
				p.y 			= mc(-offset,  shapeEditMouse.y-p.dy, 1-offset)
			end

			-- RENOVE POINT
			if  point.hovered then 
				mouse.setR(function()
					if #s>3 then 
						table.remove(s,j)
					elseif #target.shapes>1 then  
						table.remove(target.shapes,i)
					end 
				end,true)
			end

			-- HOVER LINE
			if mouseIn(previewArea) and lineHovered and not point.near and not prevpoint.near then 
				mouse.set(function ()
					target.draggingPoint={i=i,j=j}
					table.insert(s,j,{x=shapeEditMouse.x,y=shapeEditMouse.y, dx = 0, dy = 0})
				end)
				
				gfx.setLineWidth(mc(1,dotSize/2,16))
				gfx.line(point.x*res,point.y*res,prevpoint.x*res,prevpoint.y*res) 
				
			end
			
			gfx.setLineWidth(8)
			gfx.line(point.x*res,point.y*res,prevpoint.x*res,prevpoint.y*res) 

			-- PUSH POINTS TO POLYS
			table.insert(tempPoly,point.x*res)
			table.insert(tempPoly,point.y*res)
			table.insert(target.polys[i],p.x)
			table.insert(target.polys[i],p.y)

			-- DRAW POINTS
			gfx.circle( "fill", point.x*res, point.y*res, res*((point.hovered or dragging)  and dotSize or dotSize/4), 16 ) 

			if (point.near  or lineHovered) and not levelClicked then 
				changeState="Viewport"
				lmouse.setCursor(defaultCursor) 
			end

			if dragging then 
				for l,p2 in lume.ripairs(s) do
					local dist = math.dist(p.x,p.y,p2.x,p2.y)
					if l~=j and dist<0.025 then 
						local ang = math.angle(p.x,p.y,p2.x,p2.y)
						--p2.x=p2.x+(0.026-dist)*math.sin(ang)
						--p2.y=p2.y+(0.026-dist)*math.cos(ang)
						
					end
				end
			end
		end
		
		if not previewArea.skipOutline then 
			-- DRAW SHAPE LINE
			gfx.setLineWidth(3)
			gfx.polygon( "line", tempPoly) 
		end
		
	end

	editState = changeState

	if mouseIn(previewArea) then
	--	target.draggingPoint={i=0,j=0}
	end
	mouse.pushRelease(function()
		target.draggingPoint={i=0,j=0}
	end)
end

function editor.parseShapes(source, dest)
	dest = lume.clear(dest or {}) 
	for i,s in ipairs (source) do 
		table.insert(dest,{})
		for j,p in ipairs(s) do
			if j % 2 == 0 then 
				dest[i][#dest[i]].y=p
			else 
				table.insert( dest[i], {x=1,y=1} )
				dest[i][#dest[i]].x=p
			end
		end
	end
end
