--[==[Here are tags you may use to customize the above macros:
	<ff> == Random Flying Mount (fastest speed increase)
	<f310> == Random Flying Mount (310% speed increase)
	<f280> == Random Flying Mount (280% speed increase)
	<f60> == Random Flying Mount (60% speed increase)
	<gf> == Random Ground Mount (fastest speed increase)
	<g100> == Random Ground Mount (100% speed increase)
	<g60> == Random Ground Mount (60% speed increase)
	<g0> == Random Ground Mount (0% speed increase)
	<aq> == Random Ahn'Qiraj Mount
	<ww> == Random Water Mount falls back on <gf> if no watermount is found
	<s#> == will be replaced with the spellname of spellid #
(will not insert rank so will scale)]==]--

local MountTypeLookup = {
	['g'] = 'ground',
	['f'] = 'flying',
	['a'] = 'aq',
	['w'] = 'water',
}

-- /spew MNT2:ParseMacro([[#showtooltip\n/cast <gf>]])
function MNT2:ParseMacro(macrotext)
	macrotext = macrotext or '' -- use a empty string if macrotext is nil
	local mounts = {}
	local mountscache = {}
	local valid = true
	for tag in string.gmatch(macrotext, "<(%w+)>") do
		if not mountscache[tag] then
			mountscache[tag] = self:GetMount(tag) or UNKNOWN
		end
		if mountscache[tag] == UNKNOWN then
			valid = false
		end
		mounts[#mounts+1] = mountscache[tag]
	end
	return valid, string.format(string.gsub(macrotext, '<%w+>', '%%s()'), unpack(mounts))
end

local lastmount = {}
function MNT2:GetMount(text)
	local mountType, mountSpeed = string.match(text, "(.)(.+)")
	mountType = MountTypeLookup[mountType] or mountType
	local mountID, mount
	local maxspeed = self:GetFastest(mountType)
	if mountType == 'ground' and mountSpeed == 'f' then
		mountSpeed = maxspeed and self.MaxGroundSpeed < maxspeed and self.MaxGroundSpeed or maxspeed
	elseif mountType == 'flying' and mountSpeed == 'f' then
		mountSpeed = maxspeed and self.MaxAirSpeed < maxspeed and self.MaxAirSpeed or maxspeed
	elseif mountType == 'aq' then
		mountSpeed = 100
	elseif mountType == 'water' then
		if next(self.db.char.mounts[mountType]) then
			local topspeed = -1
			for speed in pairs(self.db.char.mounts[mountType]) do
				if speed > topspeed then
					topspeed = speed
				end
			end
			mountID, mount = self:GetRandomMountFromTable(mountType, tonumber(topspeed), text)
			lastmount[text] = self.db.profile.alwaysdifferent and mountID or nil
			return mount
		else
			return self:GetMount('gf')
		end
	elseif mountType == 's' then
		return GetSpellInfo(mountSpeed)
	end
	if not mountSpeed then return end
	--print(mountType)
	--print(mountSpeed)
	mountSpeed = tonumber(mountSpeed)
	mountID, mount = self:GetRandomMountFromTable(mountType, mountSpeed, text)
	--print(mountID)
	--print(mount)
	lastmount[text] = self.db.profile.alwaysdifferent and mountID or nil
	return mount
end

function MNT2:GetFastest(mountType)
	if not self.db.char.mounts[mountType] then return end
	local speeds = {}
	for speed in pairs(self.db.char.mounts[mountType]) do
		speeds[#speeds+1] = speed
	end
	table.sort(speeds)
	return speeds[#speeds]
end

function MNT2:GetRandomMountFromTable(mountType, mountSpeed, tag) -- format of t is t[mountid] = weight
	if not mountType then return end -- return nil if input was nil :P
	local SetName
	local mounts = {}
	local size = 0
	local lastmountID
	local mounts_N_sets = {}
	for mount, weight in pairs(self.db.char.mounts[mountType][mountSpeed]) do
		if not self:IsInSet(mount, mountType, mountSpeed) then
			mounts_N_sets[mount] = weight
		end
	end
	if self.db.char.mountSets[mountType][mountSpeed] then
		for set, setTable in pairs(self.db.char.mountSets[mountType][mountSpeed]) do
			mounts_N_sets[setTable] = self.db.char.mountSetsPriority[mountType][mountSpeed][set]
		end
	end
	for mount, weight in pairs(mounts_N_sets) do
		mounts[#mounts+1] = mount
		if mount ~= lastmount[tag] then
			size = size + weight
		elseif weight > 0 then
			lastmountID = mount
		end
	end
	if size == 0 and lastmountID then -- if this is the only valid mount use this one
		return self:GetMountFromIDorTable(lastmountID)
	end
	if size > 0 then
		local rand = 1
		while rand == 1 do -- ensures that size > rand and never size == rand
			rand = math.random()
		end
		rand = rand * size
		local Csize = 0
		for i, mount in ipairs(mounts) do
			SetName = self:IsInSet(mount, mountType, mountSpeed)
			if mount ~= lastmount[tag] and not SetName then
				Csize = Csize + mounts_N_sets[mount]
				if Csize > rand then
					return self:GetMountFromIDorTable(mount)
				end
			end
		end
	elseif next(mounts) then -- if all mounts are at 0 weight than simply return a random one
		local mount = mounts[math.random(1,#mounts)]
		return self:GetMountFromIDorTable(mount)
	else -- if no mounts return nil
		return nil
	end
end

function MNT2:GetMountFromIDorTable(mount)
	if type(mount) == 'number' then
		return mount, GetSpellInfo(mount)
	elseif type(mount) == 'table' then
		local mounts = {}
		for m in pairs(mount) do
			mounts[#mounts+1] = m
		end
		local rand = math.random(#mounts)
		return mounts[rand], GetSpellInfo(mounts[rand])
	end
end
