local defaultIcon = "Interface\\Icons\\INV_Misc_QuestionMark";


local function RotationToString(entry)
	local blockType = entry.type or "spell"
	local exportString = "{"
	exportString = exportString .. "\n\ttype=\"".. blockType .. "\","
	exportString = exportString .. "\n\t" .. blockType .. "=\"".. (blockType == "spell" and WhatsNext:GetSpellID(entry[blockType]) or entry[blockType] or "") .. "\","
	if entry.unit then
		exportString = exportString .. "\n\tunit=\"".. entry.unit .. "\","
	end
	if entry.copyUnits then
		exportString = exportString .. "\n\tcopyUnits={\n\t\t"
		for k,v in ipairs(entry.copyUnits) do
			exportString = exportString .. "\"" .. v .. "\","
		end
		exportString = exportString .. "\n\t},"
	end
	exportString = exportString .. "\n\tchecks={"
	for i, check in pairs(entry.checks) do
		exportString = exportString .. "\n\t\t{[\"type\"]=\"" .. tostring(check["type"]) .. "\","
		for var,val in pairs(check) do
			if var ~= "type" then
				exportString = exportString .. "[\"" .. tostring(var) .. "\"]="
				if type(val) == "boolean" or type(val) == "number" then
					exportString = exportString .. tostring(val) .. ","
				else
					exportString = exportString .. "\"" .. tostring(val) .. "\","
				end
			end
		end
		exportString = exportString .. "},"
	end
	return exportString .. "\n\t}\n}"
end

local function updateSelectedBlock(index)
	if WhatsNext.rotationManagerFrame.selectedIndex == index then
		WhatsNext.rotationManagerFrame.selectedIndex = 0;
	else
		WhatsNext.rotationManagerFrame.selectedIndex = index;
	end
	
	if WhatsNext.rotationManagerFrame.entryBlocks then
		for i,entryBlock in ipairs(WhatsNext.rotationManagerFrame.entryBlocks) do
			if i == WhatsNext.rotationManagerFrame.selectedIndex then
				entryBlock.frame.texture:SetColorTexture(.2,.2,.2,1)
			elseif i%2==1 then
				entryBlock.frame.texture:SetColorTexture(.05,.05,.05,1)
			else
				entryBlock.frame.texture:SetColorTexture(.1,.1,.1,1)
			end
		end
	end
end


local function createSpacer(width)
	local label = WhatsNext.AceGUI:Create('Label');
	label:SetText(" ");
	if width <= 0 then
		label:SetFullWidth(true)
	else
		label:SetWidth(width)
	end
	return label
end

local function populateRotationTable()
	local frame = WhatsNext.rotationManagerFrame
	frame:PauseLayout()
	
	if not frame.entryBlocks then
		frame.entryBlocks = {}
	end
	
	
	for i,entry in ipairs(WhatsNext.workRotation) do

		local entryBlock = frame.entryBlocks[i]
		if not entryBlock then
			entryBlock = WhatsNext.AceGUI:Create("SimpleGroup")
			entryBlock.index = i
			entryBlock:SetFullWidth(true)
			entryBlock:SetLayout("Flow")
			frame.entryBlocks[i] = entryBlock
			
			local spacer = WhatsNext.AceGUI:Create('Label');
			spacer:SetText(" ");
			spacer:SetFont("Fonts\\FRIZQT__.TTF", 28, "OUTLINE, MONOCHROME")
			spacer:SetWidth(400)
			entryBlock:AddChild(spacer)
			entryBlock.checkLabel = WhatsNext.AceGUI:Create('Label');
			entryBlock.checkLabel:SetText(" ");
			entryBlock.checkLabel:SetFont("Fonts\\FRIZQT__.TTF", 13, "")
			entryBlock.checkLabel:SetWidth(680)
			entryBlock.checkLabel.label:SetJustifyH("RIGHT")

			entryBlock:AddChild(createSpacer(5))
			entryBlock:AddChild(entryBlock.checkLabel)
			entryBlock:AddChild(createSpacer(600))
			
			frame.scrollFrame:AddChild(entryBlock)
			
			entryBlock.frame.icon = entryBlock.frame:CreateTexture()
			entryBlock.frame.icon:SetPoint("TOPLEFT",entryBlock.frame,"TOPLEFT",2,-2)
			entryBlock.frame.icon:SetWidth(30)
			entryBlock.frame.icon:SetHeight(30)
		
			entryBlock.frame.entryTitle = entryBlock.frame:CreateFontString(nil,"ARTWORK")
			entryBlock.frame.entryTitle:SetFont("Fonts\\FRIZQT__.TTF", 16, "")
			entryBlock.frame.entryTitle:SetPoint("TOPLEFT",entryBlock.frame.icon,"TOPRIGHT",5,0)
			entryBlock.frame.entryTitle:SetPoint("BOTTOMLEFT",entryBlock.frame.icon,"BOTTOMRIGHT",5,0)
			entryBlock.frame.entryTitle:SetTextColor(1,0.8196079,0,1)
			entryBlock.frame.entryTitle:SetJustifyH("LEFT")
			entryBlock.frame.entryTitle:SetJustifyV("CENTER")
			entryBlock.frame.entryTitle:SetWidth(500)
			
			entryBlock.frame.entryIndex = entryBlock.frame:CreateFontString(nil,"ARTWORK")
			entryBlock.frame.entryIndex:SetFont("Fonts\\ARIALN.TTF", 16, "")
			entryBlock.frame.entryIndex:SetPoint("TOPRIGHT",entryBlock.frame,"TOPRIGHT",-4,-4)
			entryBlock.frame.entryIndex:SetTextColor(1,0.8196079,0,1)
			entryBlock.frame.entryIndex:SetJustifyH("RIGHT")
			entryBlock.frame.entryIndex:SetJustifyV("CENTER")
			entryBlock.frame.entryIndex:SetWidth(40)
			
			entryBlock.frame.texture = entryBlock.frame:CreateTexture(nil, "BACKGROUND")
			entryBlock.frame.texture:SetColorTexture(.5,.5,.5,0)
			entryBlock.frame.texture:SetPoint("TOPLEFT",entryBlock.frame,"TOPLEFT",-4,0)
			entryBlock.frame.texture:SetPoint("BOTTOMRIGHT",entryBlock.frame,4,-3)
			
			entryBlock.frame.button = CreateFrame("Button","blockButton"..i,entryBlock.frame)
			entryBlock.frame.button.index = i
			entryBlock.frame.button:SetPoint("TOPLEFT",entryBlock.frame,-4,0)
			entryBlock.frame.button:SetPoint("BOTTOMRIGHT",entryBlock.frame,4,-3)
			entryBlock.frame.button:SetScript("OnClick",function(btn) 
				updateSelectedBlock(btn.index)
			end)
			
			
		end

		
		
		
		local topLine = ""
		local iconPath = "Interface\\Icons\\INV_Misc_QuestionMark"
		
		
		local name = entry[entry.type];
		if entry.type == "spell" then
			iconPath = select(3,GetSpellInfo(name)) or defaultIcon
			topLine = ((select(1,GetSpellInfo(name)) or "") .. (entry.unit and entry.unit ~= "target" and (" @ "..entry.unit) or ""))  or "";
		elseif entry.type == "item" then
			iconPath = select(10,GetItemInfo(name)) or defaultIcon
			topLine = (select(1,GetItemInfo(name)) or "");
		elseif entry.type == "macro" then
			iconPath = select(2,GetMacroInfo(name)) or defaultIcon
			topLine = (select(1,GetMacroInfo(name)) or "");
		elseif entry.type == "note" then
			iconPath = "Interface\\Icons\\INV_MISC_NOTE_05"
			topLine = (name);
		elseif entry.type == "logicset" then
			iconPath = "Interface\\Icons\\MISC_ARROWRIGHT"
			topLine = (name);
		end
		
		
		local checkText = ""
		local checkCount = #(entry.checks)
		if checkCount > 0 then
			checkText = WhatsNext:GetCheckText(entry.checks[1])
			for i = 2, checkCount do
				checkText = checkText .. "\n"..WhatsNext:GetCheckText(entry.checks[i])
			end
		end
		entryBlock.checkLabel:SetText(checkText)
		entryBlock.frame.icon:SetTexture(iconPath)
		entryBlock.frame.entryTitle:SetText(topLine)
		entryBlock.frame.entryIndex:SetText(tostring(i))
		entryBlock.frame:Show()
	end
	updateSelectedBlock(0)
	frame:ResumeLayout()
	frame:DoLayout()
	frame.scrollFrame:SetScroll(0)
	

	for i=#WhatsNext.workRotation +1, #WhatsNext.rotationManagerFrame.entryBlocks do
		WhatsNext.rotationManagerFrame.entryBlocks[i].frame:Hide()
	end
end

local function populateRotationDropdown()
	WhatsNext.rotationManagerFrame.rotationDropdown:SetList({});
	
	local logicSets = WhatsNext.db.profile.castSequences[WhatsNext.rotationManagerFrame.class][WhatsNext.rotationManagerFrame.spec]
	WhatsNext.rotationManagerFrame.selectedRotationIndex = 1;
	for i,logicSet in ipairs(logicSets) do
		WhatsNext.rotationManagerFrame.rotationDropdown:AddItem(i,logicSet.name);
		if logicSet.use then
			WhatsNext.rotationManagerFrame.selectedRotationIndex = i
		end
	end

	WhatsNext.rotationManagerFrame.rotationDropdown:SetValue(WhatsNext.rotationManagerFrame.selectedRotationIndex);
	populateRotationTable()
end

local function populateSpecDropdown()
	WhatsNext.rotationManagerFrame.specDropdown:SetList({});
	for i=1, WhatsNext.CLASS_SPECIALIZATION_COUNTS[WhatsNext.rotationManagerFrame.class] or 3 do
		WhatsNext.rotationManagerFrame.specDropdown:AddItem(i,WhatsNextLocal:Localize(WhatsNext.rotationManagerFrame.class..i));
	end
	WhatsNext.rotationManagerFrame.spec = WhatsNext.rotationManagerFrame.class == WhatsNext.rotationManagerFrame.playerClass and GetSpecialization() or 1
	WhatsNext.rotationManagerFrame.specDropdown:SetValue(WhatsNext.rotationManagerFrame.spec);
	populateRotationDropdown()
end

local function createSpacer(width)
	local label = WhatsNext.AceGUI:Create('Label');
	label:SetText(" ");
	label:SetWidth(width)
	return label
end

function WhatsNext:SetWorkRotation(index)
	self.class = select(2,UnitClass("player"));
	self.spec =  GetSpecialization() or 1
	self.rotationIndex = index
	self.rotationChanged = false
	
	if index == -1 then
		self.newWorkRotation = true;
		self.workRotation = {
			name = "Unnamed",
			lastModified = time(),
			use = nil,
		}
	elseif index == 0 then
		for i, rotation in ipairs(WhatsNext.db.profile.castSequences[self.class][self.spec]) do
			if rotation.use then
				self.rotationIndex = i;
			end
		end
	
		self.newWorkRotation = false;
		self.workRotation = DeepCopy(WhatsNext.db.profile.castSequences[self.class][self.spec][self.rotationIndex])
	else
		self.newWorkRotation = false;
		self.workRotation = DeepCopy(WhatsNext.db.profile.castSequences[self.class][self.spec][self.rotationIndex])
	end
	populateRotationTable()
end

function WhatsNext:ShowRotationManagerFrame()
	if not self.rotationManagerFrame then
		local frame = self.AceGUI:Create("Window")
		_G["WhatsNext_RotationManagerFrame"] = frame
		
		
		frame:PauseLayout()
		frame.class = select(2,UnitClass("player"));
		frame.spec =  GetSpecialization() or 1
		
		WhatsNext_AddOptionsScreen(frame.frame)
		tinsert(UISpecialFrames, "WhatsNext_RotationManagerFrame") 
		self.rotationManagerFrame = frame
		frame:SetWidth(750)
		frame:SetHeight(700)
		frame:SetTitle("What's Next? - Rotation Management")
		frame:SetStatusText("")
		frame:EnableResize(false);
		frame:SetCallback("OnClose", function(widget) 
			WhatsNext:ApplyMainSettings()
			WhatsNext:UpdateActiveLogicSet()
			--InterfaceOptionsFrame_OpenToCategory(WhatsNext.mainOptions) 
		end)
		frame:SetLayout("Flow")
		frame:SetAutoAdjustHeight(false)
		
	
		
		frame.scrollContainer = self.AceGUI:Create("InlineGroup") -- "InlineGroup" is also good
		frame.scrollContainer:SetFullWidth(true)
		frame.scrollContainer:SetHeight(590)
		
		frame.frame.texture = frame.frame:CreateTexture(nil, "BACKGROUND")
		frame.frame.texture:SetColorTexture(0,0,0,1)
		frame.frame.texture:SetPoint("TOPLEFT",frame.frame,"TOPLEFT",8,-10)
		frame.frame.texture:SetPoint("BOTTOMRIGHT",frame.frame,"BOTTOMRIGHT",-6,8)
		frame.scrollContainer:SetLayout("Fill") -- important!

		frame:AddChild(frame.scrollContainer)

		frame.scrollFrame = self.AceGUI:Create("ScrollFrame")
		frame.scrollFrame:SetLayout("Flow") -- probably?
		frame.scrollContainer:AddChild(frame.scrollFrame)
				
		
		
		frame.copyEntryButton = self.AceGUI:Create('Button');
		frame.copyEntryButton:SetWidth(80);
		frame.copyEntryButton:SetText('Copy');
		frame.copyEntryButton:SetCallback('OnClick', function()	
			print("Open Entry Edit window, copy of selected blank entry as base");
		end);
		frame.addEntryButton = self.AceGUI:Create('Button');
		frame.addEntryButton:SetWidth(80);
		frame.addEntryButton:SetText('Add');
		frame.addEntryButton:SetCallback('OnClick', function()	
			print("Open Entry Edit window, blank entry base");
		end);
		frame.editEntryButton = self.AceGUI:Create('Button');
		frame.editEntryButton:SetWidth(80);
		frame.editEntryButton:SetText('Edit');
		frame.editEntryButton:SetCallback('OnClick', function()	
			print("Open Entry Edit window, with selected entry");
		end);
		frame.removeEntryButton = self.AceGUI:Create('Button');
		frame.removeEntryButton:SetWidth(80);
		frame.removeEntryButton:SetText('Remove');
		frame.removeEntryButton:SetCallback('OnClick', function()
			local index = WhatsNext.rotationManagerFrame.selectedIndex;
			if index and index > 0 then
				tremove(WhatsNext.workRotation, index)
			end
			populateRotationTable()
			if index > #WhatsNext.workRotation then
				updateSelectedBlock(#WhatsNext.workRotation)
			else
				updateSelectedBlock(index)
			end
		end);
		
		frame.importEntryButton = self.AceGUI:Create('Button');
		frame.importEntryButton:SetWidth(80);
		frame.importEntryButton:SetText('Import');
		frame.importEntryButton:SetCallback('OnClick', function()	
			WhatsNext.rotationManagerFrame.frame:Hide()
			WhatsNext:ShowImportFrame(function(importText)
				local importBody
				if type(importText) == "string" then
					local func, errors = loadstring("return "..importText)
					if not func then
						return false, errors
					end
					importBody = func()
				end
			
				for i,entry in pairs(importBody) do
					if not entry["type"] or not entry[entry["type"]] then
						return false, "Unrecognisable rotation entry (#"..i..")."
					end
				end
			
				local startIndex = WhatsNext.rotationManagerFrame.selectedIndex > 0 and WhatsNext.rotationManagerFrame.selectedIndex or #WhatsNext.workRotation
				for i,entry in pairs(importBody) do
					tinsert(WhatsNext.workRotation, startIndex+i-1, entry);
				end
				
				populateRotationTable()
				
				return true
			end,function()
				WhatsNext:ShowRotationManagerFrame()
			end)
		end);
		
		frame.exportEntryButton = self.AceGUI:Create('Button');
		frame.exportEntryButton:SetWidth(80);
		frame.exportEntryButton:SetText('Export');
		frame.exportEntryButton:SetCallback('OnClick', function()
			local index = WhatsNext.rotationManagerFrame.selectedIndex;
			local count
			local exportString = "{"
			
			if index > 0 then
				exportString = exportString .. RotationToString(WhatsNext.workRotation[index]) .. ","
				count = 1
			else
				for i, entry in ipairs(WhatsNext.workRotation) do
					exportString = exportString .. RotationToString(entry) .. ","
				end
				count = #WhatsNext.workRotation
			end
			exportString = exportString .. "}"
		
			WhatsNext:ShowExportFrame(exportString,count, function() 
				WhatsNext:ShowRotationManagerFrame()
			end)
			WhatsNext.rotationManagerFrame.frame:Hide()
		end);
		
		frame.saveButton = self.AceGUI:Create('Button');
		frame.saveButton:SetWidth(80);
		frame.saveButton:SetText('Save');
		frame.saveButton:SetCallback('OnClick', function()	
			for i, rotation in ipairs(WhatsNext.db.profile.castSequences[WhatsNext.class][WhatsNext.spec]) do
				rotation.use = nil;
			end
			
			WhatsNext.workRotation.lastModified = time()
			WhatsNext.workRotation.use = "General"
			
			if WhatsNext.newWorkRotation then
				tinsert(WhatsNext.db.profile.castSequences[WhatsNext.class][WhatsNext.spec], WhatsNext.workRotation);
			else
				WhatsNext.db.profile.castSequences[WhatsNext.class][WhatsNext.spec][WhatsNext.rotationIndex] = WhatsNext.workRotation			
			end
			
			WhatsNext.rotationManagerFrame.frame:Hide()
		end);
		
		frame.cancelButton = self.AceGUI:Create('Button');
		frame.cancelButton:SetWidth(80);
		frame.cancelButton:SetText('Cancel');
		frame.cancelButton:SetCallback('OnClick', function()
			WhatsNext.rotationManagerFrame.frame:Hide()
		end);
		
		frame:AddChild(createSpacer(0))
		
		frame:AddChild(frame.copyEntryButton)
		frame:AddChild(frame.addEntryButton)
		frame:AddChild(frame.editEntryButton)
		frame:AddChild(frame.removeEntryButton)
		frame:AddChild(createSpacer(43))
		frame:AddChild(frame.importEntryButton)
		frame:AddChild(frame.exportEntryButton)
		frame:AddChild(createSpacer(43))
		frame:AddChild(frame.saveButton)
		frame:AddChild(frame.cancelButton)
		frame:ResumeLayout()
		frame:DoLayout()
	else
		self.rotationManagerFrame:Show()
	end

	if not self.workRotation then
		self:SetWorkRotation(0)
	end
end