--[[
	0.6585 0.7525 -0.7525
	0.6585 65.8947 -60.3935
]]
function trim(s)
  return (s:gsub("^%s*(.-)%s*$", "%1"))
end
-- Compatibility: Lua-5.0
function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gfind(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end
function hex_to_tint(color)
  -- Drop the initial '#'
  color = string.sub(color, 2) 
  local tint = {a=255}
  -- Fetch the different components and invert them
  for i,v in ipairs({'r', 'g', 'b'}) do
    -- Fetch the substring
    local component = string.sub(color, 1 + (i-1) * 2, 2 + (i-1) * 2)
    -- Convert to numerical
    component = tonumber('0x' .. component)
    tint[v] = component
  end
  return tint
end
strokeSvg = false
SvgLoader = function(svg_name, scale, absolute, stroke)
	strokeSvg = stroke
	local base = absolute or blud.bundle_root .. "/"
	local svgObject = ObjectGroup()
	svgObject.id = {}
	svgObject:setSheet(sheets['tiles'])
	-- print("loading: " ..base .. svg_name)
	local xml = LuaXML_ParseFile(base .. svg_name)
	local objects = findNode(xml, "svg")
	if not objects then
		print("file not found: " .. svg_name)
	end
	SvgLoaderHandler(svgObject, objects, scale)
	if scale then
		svgObject:scale(0.5*r_scale, 0.5*r_scale)
		svgObject:storeTransform()
		-- convert all of the id data to smallize
		for key,rbd in pairs(svgObject.id) do
			for k,v in pairs(rbd) do
				rbd[k] = v*0.5*r_scale
			end
		end
	end
    return svgObject
end
function svgAddShape(x, y, w, h, sprite, v, svgObject, gid, opacity)
	local zoom = 1
	local c = {x*zoom, y*zoom, w*zoom, h*zoom}
    local tl = {c[1], c[2]}
    local tr = {c[1]+c[3], c[2]}
    local bl = {c[1], c[2]+c[4]}
    local br = {c[1]+c[3], c[2]+c[4]}
    local fill = v.attr.fill or "#000000"
	local tint = hex_to_tint(fill)
	if not tint.r then return end
	if v.attr.id then gid = v.attr.id end
	if v.attr.opacity then tint.a = 255 * v.attr.opacity end
	if opacity then tint.a = 255 * opacity end
	applyMatrix(v, {tl, tr, bl, br})
	local stroke = false
	if sprite == sprites['tiles']['white.png'] and r_scale > 1 and strokeSvg then stroke = true end
	svgObject:addCorners(sprite, tl[1],tl[2], tr[1],tr[2], bl[1],bl[2], br[1],br[2], bludColor(tint.r, tint.g, tint.b, tint.a), stroke)
	if gid then
		if not svgObject.id then svgObject.id = {} end
		if not svgObject.id[gid] then svgObject.id[gid] = {} end
		local current = svgObject.id[gid]
		local minX = math.min(tl[1], math.min(tr[1], math.min(bl[1], br[1])))
		local minY = math.min(tl[2], math.min(tr[2], math.min(bl[2], br[2])))
		local maxX = math.max(tl[1], math.max(tr[1], math.max(bl[1], br[1])))
		local maxY = math.max(tl[2], math.max(tr[2], math.max(bl[2], br[2])))

		if not current.minX then current.minX = minX else current.minX = math.min(current.minX, minX) end
		if not current.minY then current.minY = minY else current.minY = math.min(current.minY, minY) end
		if not current.maxX then current.maxX = maxX else current.maxX = math.max(current.maxX, maxX) end
		if not current.maxY then
			current.maxY = maxY
		else
			current.maxY = math.max(current.maxY, maxY)
		end

	end
end
function SvgLoaderHandler(svgObject, objects, scale, opacity, g_id)
	for i,v in ipairs(objects) do
		if v.name == 'rect' then
			local x, y, w, h = v.attr.x or 0, v.attr.y or 0, v.attr.width or 0, v.attr.height or 0
			svgAddShape(x, y, w, h, sprites['tiles']['white.png'], v, svgObject, g_id, opacity)
		end
		if v.name == 'circle' then
			local x, y, r = v.attr.cx or 0, v.attr.cy or 0, v.attr.r or 0
			x, y = x - r, y - r
			local w, h = r*2, r*2
			svgAddShape(x, y, w, h, sprites['tiles']['circle.png'], v, svgObject, g_id, opacity)
		end
		if v.name == 'ellipse' then
			local x, y, w, h = v.attr.cx or 0, v.attr.cy or 0, v.attr.rx or 0, v.attr.ry or 0
			x, y = x - w, y - h
			local w, h = w*2, h*2
			svgAddShape(x, y, w, h, sprites['tiles']['circle.png'], v, svgObject, g_id, opacity)
		end
		if v.name == 'polygon' then
			-- evaluate if it is a 4 corner polygon (that is all we currently support)
			local points = Split(trim(v.attr.points), " ")
			if #points == 4 then
				for i,point in ipairs(points) do
					local position = Split(point, ",")
					points[i] = Vec2(position[1], position[2])
				end
				local zoom = 1
			    local fill = v.attr.fill or "#000000"
				local tint = hex_to_tint(fill)
				if v.attr.opacity then tint.a = 255 * v.attr.opacity end
				if opacity then tint.a = 255 * opacity end
				local stroke = false
				if r_scale > 1 and strokeSvg then stroke = true end
				svgObject:addCorners(sprites['tiles']['white.png'], points[1].x, points[1].y, points[2].x, points[2].y, points[4].x, points[4].y,points[3].x, points[3].y, bludColor(tint.r, tint.g, tint.b, tint.a), stroke)
				if g_id then
					if not svgObject.id then svgObject.id = {} end
					if not svgObject.id[g_id] then svgObject.id[g_id] = {} end
					local current = svgObject.id[g_id]
					local minX = math.min(points[1].x, math.min(points[2].x, math.min(points[3].x, points[4].x)))
					local minY = math.min(points[1].y, math.min(points[2].y, math.min(points[3].y, points[4].y)))
					local maxX = math.max(points[1].x, math.max(points[2].x, math.max(points[3].x, points[4].x)))
					local maxY = math.max(points[1].y, math.max(points[2].y, math.max(points[3].y, points[4].y)))

					if not current.minX then current.minX = minX else current.minX = math.min(current.minX, minX) end
					if not current.minY then current.minY = minY else current.minY = math.min(current.minY, minY) end
					if not current.maxX then current.maxX = maxX else current.maxX = math.max(current.maxX, maxX) end
					if not current.maxY then current.maxY = maxY else current.maxY = math.max(current.maxY, maxY) end
				end

			end
		end
		if v.name == 'g' then
			local opacity = nil
			local id = g_id
			if v.attr then
				if v.attr.opacity then
					opacity = v.attr.opacity
				end
				if v.attr.id then
					id = v.attr.id
				end
			end
			-- process the group id to deal with illustrator strangeness
			if id and id:sub(#id) == "_" then id = id:sub(1, #id-3) end
			SvgLoaderHandler(svgObject, v, scale, opacity, id)
		end
    end
end

function applyMatrix(v, points)
	if v.attr and v.attr.transform then
		if v.attr.transform:sub(1, 6) == "matrix" then
			-- extract the matrix
			local matrix = Split(v.attr.transform:sub(8, #v.attr.transform-1), " ")
			local a, b, c, d, e, f = matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]
			for i,v in ipairs(points) do
				local tx = v[1]*a + v[2]*c + e;
            	local ty = v[1]*b + v[2]*d + f;
            	v[1] = tx
            	v[2] = ty
			end
		end
	end
end

-- function SvgLoadState:draw()
-- 	self.svgObject:draw(bludG.camera.scroll.x, bludG.camera.scroll.y, bludG.camera.scale)
-- end
-- function SvgLoadState:update()
-- 	bludG.camera.scroll.x = -(math.sin(bludG.last_t*1.5)+1)*150.0
-- 	bludG.camera.scale = math.sin(bludG.last_t*0.1)+1.5
-- end

-- mainState:changeState(SvgLoadState())
