
CLASS_TRAINER_SKILLS_DISPLAYED = 11;
CLASS_TRAINER_SKILL_SUBTEXT_WIDTH = 210
CLASS_TRAINER_SKILL_NOSUBTEXT_WIDTH = 270
CLASS_TRAINER_SKILL_HEIGHT = 16;
MAX_LEARNABLE_PROFESSIONS = 2;

-- Trainer Filter Default Values
TRAINER_FILTER_AVAILABLE = 1;
TRAINER_FILTER_UNAVAILABLE = 1;
TRAINER_FILTER_USED = 0;


UIPanelWindows["ClassTrainerFrame"] = { area = "left", pushable = 0 };

StaticPopupDialogs["CONFIRM_PROFESSION"] = {
	text = format(PROFESSION_CONFIRMATION1, "XXX"),
	button1 = ACCEPT,
	button2 = CANCEL,
	OnAccept = function(self)
		BuyTrainerService(ClassTrainerFrame.selectedService);
		ClassTrainerFrame.showSkillDetails = 1;
		ClassTrainerFrame.showDialog = nil;		
		ClassTrainer_SetSelection(GetTrainerSelectionIndex());
		ClassTrainerFrame_Update();
	end,
	OnShow = function(self)
		local cp1, cp2 = UnitCharacterPoints("player");
		if cp2 < MAX_LEARNABLE_PROFESSIONS then
			self.text:SetFormattedText(PROFESSION_CONFIRMATION2, GetTrainerServiceSkillLine(ClassTrainerFrame.selectedService));
		else
			self.text:SetFormattedText(PROFESSION_CONFIRMATION1, GetTrainerServiceSkillLine(ClassTrainerFrame.selectedService));
		end
	end,
	showAlert = 1,
	timeout = 0,
	hideOnEscape = 1
};

function ClassTrainerFrame_Show()
	ShowUIPanel(ClassTrainerFrame);
	if not ClassTrainerFrame:IsShown() then
		CloseTrainer();
		return;
	end

	ClassTrainerTrainButton:Disable();
	--Reset scrollbar
	ClassTrainerListScrollFrameScrollBar:SetMinMaxValues(0, 0); 

	ClassTrainer_SelectFirstLearnableSkill();
	ClassTrainerFrame_Update();
	UpdateMicroButtons();
end

function ClassTrainerFrame_Hide()
	HideUIPanel(ClassTrainerFrame);
end

function ClassTrainerFrame_OnLoad(self)
	self:RegisterEvent("TRAINER_UPDATE");
	self:RegisterEvent("TRAINER_DESCRIPTION_UPDATE");
	ClassTrainerDetailScrollFrame.scrollBarHideable = 1;
end

function ClassTrainerFrame_OnEvent(self, event, ...)
	if not self:IsShown() then
		return;
	end
	if event == "TRAINER_UPDATE" then
		ClassTrainer_SelectFirstLearnableSkill();
		ClassTrainerFrame_Update();
	elseif event == "TRAINER_DESCRIPTION_UPDATE" then
		ClassTrainer_SetSelection(GetTrainerSelectionIndex());
	end
end

function ClassTrainerFrame_Update()
	SetPortraitTexture(ClassTrainerFramePortrait, "npc");
	ClassTrainerNameText:SetText(UnitName("npc"));
	ClassTrainerGreetingText:SetText(GetTrainerGreetingText());
	local numTrainerServices = GetNumTrainerServices();
	local skillOffset = FauxScrollFrame_GetOffset(ClassTrainerListScrollFrame);
	
	-- If no spells then clear everything out
	if numTrainerServices == 0 then
		ClassTrainerCollapseAllButton:Disable();
	else
		ClassTrainerCollapseAllButton:Enable();
	end

	-- If selectedService is nil hide everything
	if not ClassTrainerFrame.selectedService then
		ClassTrainer_HideSkillDetails();
	end

	-- Change the setup depending on if its a class trainer or tradeskill trainer
	if IsTradeskillTrainer() then
		ClassTrainer_SetToTradeSkillTrainer();
	else
		ClassTrainer_SetToClassTrainer();
	end

	-- ScrollFrame update
	FauxScrollFrame_Update(ClassTrainerListScrollFrame, numTrainerServices, CLASS_TRAINER_SKILLS_DISPLAYED, CLASS_TRAINER_SKILL_HEIGHT, nil, nil, nil, ClassTrainerSkillHighlightFrame, 293, 316 )
	
	--ClassTrainerUsedButton:Show();
	ClassTrainerMoneyFrame:Show();

	local selected = GetTrainerSelectionIndex();

	ClassTrainerSkillHighlightFrame:Hide();
	-- Fill in the skill buttons
	for i=1, CLASS_TRAINER_SKILLS_DISPLAYED, 1 do
		local skillIndex = i + skillOffset;
		local skillButton = getglobal("ClassTrainerSkill"..i); 
		local serviceName, serviceSubText, serviceType, isExpanded;
		local moneyCost, cpCost1, cpCost2;
		if skillIndex <= numTrainerServices then	
			serviceName, serviceSubText, serviceType, isExpanded = GetTrainerServiceInfo(skillIndex);
			if not serviceName then
				serviceName = UNKNOWN;
			end
			-- Set button widths if scrollbar is shown or hidden
			if ClassTrainerListScrollFrame:IsShown() then
				skillButton:SetWidth(293);
			else
				skillButton:SetWidth(313);
			end
			local skillSubText = getglobal("ClassTrainerSkill"..i.."SubText");
			local skillText = getglobal("ClassTrainerSkill"..i.."Text");
			-- Type stuff
			if serviceType == "header" then
				skillButton:SetText(serviceName);
				skillButton:SetNormalFontObject(GameFontNormalLeft);
				skillSubText:Hide();
				skillText:SetWidth(CLASS_TRAINER_SKILL_NOSUBTEXT_WIDTH);
				if isExpanded then
					skillButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
				else
					skillButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
				end
				getglobal("ClassTrainerSkill"..i.."Highlight"):SetTexture("Interface\\Buttons\\UI-PlusButton-Hilight");
			else
				skillButton:SetNormalTexture("");
				getglobal("ClassTrainerSkill"..i.."Highlight"):SetTexture("");
				skillButton:SetText("  "..serviceName);
				if serviceSubText and serviceSubText ~= "" then
					skillSubText:SetFormattedText(PARENS_TEMPLATE, serviceSubText);
					skillText:SetWidth(CLASS_TRAINER_SKILL_SUBTEXT_WIDTH);
					skillSubText:ClearAllPoints();
					skillSubText:SetPoint("RIGHT", skillButton, "RIGHT", -2, 0);
					skillSubText:Show();
				else
					skillText:SetWidth(CLASS_TRAINER_SKILL_NOSUBTEXT_WIDTH);
					skillSubText:Hide();
				end
				
				-- Cost Stuff
				moneyCost, cpCost1, cpCost2 = GetTrainerServiceCost(skillIndex);
				if serviceType == "available" then
					skillButton:SetNormalFontObject(GameFontNormalLeftGreen);
					ClassTrainer_SetSubTextColor(skillButton, 0, 0.6, 0);
					skillButton.r = 0;
				elseif serviceType == "used" then
					skillButton:SetNormalFontObject(GameFontNormalLeftGrey);
					ClassTrainer_SetSubTextColor(skillButton, 0.5, 0.5, 0.5);
				else
					skillButton:SetNormalFontObject(GameFontNormalLeftRed);
					ClassTrainer_SetSubTextColor(skillButton, 0.6, 0, 0);
				end		
			end
			skillButton:SetID(skillIndex);
			skillButton:Show();
			-- Place the highlight and lock the highlight state
			if ClassTrainerFrame.selectedService and selected == skillIndex then
				ClassTrainerSkillHighlightFrame:SetPoint("TOPLEFT", "ClassTrainerSkill"..i, "TOPLEFT", 0, 0);
				ClassTrainerSkillHighlightFrame:Show();
				skillButton:LockHighlight();
				ClassTrainer_SetSubTextColor(skillButton, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
				if moneyCost and moneyCost > 0 then
					ClassTrainerCostLabel:Show();
				end
			else
				skillButton:UnlockHighlight();
			end
		else
			skillButton:Hide();
		end
	end
		
	-- Set the expand/collapse all button texture
	local numHeaders = 0;
	local notExpanded = 0;
	local showDetails = nil;
	-- Somewhat redundant loop, but cleaner than the alternatives
	for i=1, numTrainerServices, 1 do
		local serviceName, serviceSubText, serviceType, isExpanded = GetTrainerServiceInfo(i);
		if serviceName and serviceType == "header" then
			numHeaders = numHeaders + 1;
			if not isExpanded then
				notExpanded = notExpanded + 1;
			end
		end
		-- Show details if selected skill is visible
		if ClassTrainerFrame.selectedService and selected == i then
			showDetails = 1;
		end
	end
	-- Show skill details if the skill is visible
	if showDetails then
		ClassTrainer_ShowSkillDetails();
	else	
		ClassTrainer_HideSkillDetails();
	end
	-- If all headers are not expanded then show collapse button, otherwise show the expand button
	if notExpanded ~= numHeaders then
		ClassTrainerCollapseAllButton.collapsed = nil;
		ClassTrainerCollapseAllButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
	else
		ClassTrainerCollapseAllButton.collapsed = 1;
		ClassTrainerCollapseAllButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
	end
end

function ClassTrainer_SelectFirstLearnableSkill()
	if GetNumTrainerServices() > 0 then
		ClassTrainerFrame.showSkillDetails = 1;
		local selectionIndex = GetTrainerSelectionIndex();
		ClassTrainer_SetSelection(selectionIndex);
		if ( selectionIndex and (selectionIndex <= GetNumTrainerServices() and selectionIndex >= 2)) then
			ClassTrainerFrame_Update();
			ClassTrainerListScrollFrameScrollBar:SetValue((selectionIndex-1)*CLASS_TRAINER_SKILL_HEIGHT);
		end
	else
		ClassTrainerFrame.showSkillDetails = nil;
		ClassTrainer_SetSelection(GetTrainerSelectionIndex());
		ClassTrainerListScrollFrameScrollBar:SetValue(0);
	end
end

function ClassTrainer_SetSelection(id)
	-- General Info
	if not id then
		ClassTrainer_HideSkillDetails();
		return;
	end
	local serviceName, serviceSubText, serviceType, isExpanded = GetTrainerServiceInfo(id);

	ClassTrainerSkillHighlightFrame:Show();
	
	if serviceType == "available" then
		ClassTrainerSkillHighlight:SetVertexColor(0, 1.0, 0);
	elseif serviceType == "used" then
		ClassTrainerSkillHighlight:SetVertexColor(0.5, 0.5, 0.5);
	elseif serviceType == "unavailable" then
		ClassTrainerSkillHighlight:SetVertexColor(0.9, 0, 0);
	else
		-- Is header, so collapse or expand header
		ClassTrainerSkillHighlightFrame:Hide();
		if isExpanded then
			CollapseTrainerSkillLine(id);
		else
			ExpandTrainerSkillLine(id);
		end
		return;
	end
	
	ClassTrainerSubSkillName:SetFormattedText(PARENS_TEMPLATE, serviceSubText);
	ClassTrainerFrame.selectedService = id;
	SelectTrainerService(id);
	ClassTrainerSkillIcon:SetNormalTexture(GetTrainerServiceIcon(id));

	if ClassTrainerFrame.showSkillDetails then
		ClassTrainer_ShowSkillDetails();
	else
		ClassTrainer_HideSkillDetails();
		return;
	end

	if not serviceName then
		serviceName = UNKNOWN;
	end
	ClassTrainerSkillName:SetText(serviceName);
	if not serviceSubText then
		serviceSubText = "";
	end
	-- Build up the requirements string
	local requirements = "";
	-- Level Requirements
	local reqLevel = GetTrainerServiceLevelReq(id);
	local separator = "";
	if reqLevel > 1 then
		separator = ", ";
		if UnitLevel("player") >= reqLevel then
			requirements = requirements..format(TRAINER_REQ_LEVEL, reqLevel);
		else
			requirements = requirements..format(TRAINER_REQ_LEVEL_RED, reqLevel);
		end
	end
	-- Skill Requirements
	local skill, rank, hasReq = GetTrainerServiceSkillReq(id);
	if skill then
		if hasReq then
			requirements = requirements..separator..format(TRAINER_REQ_SKILL_RANK, skill, rank );
		else
			requirements = requirements..separator..format(TRAINER_REQ_SKILL_RANK_RED, skill, rank );
		end
		separator = ", ";
	end
	-- Ability Requirements
	local numRequirements = GetTrainerServiceNumAbilityReq(id);
	local ability, abilityName, abilitySubText, abilityType;
	if numRequirements > 0 then
		for i=1, numRequirements, 1 do
			ability, hasReq = GetTrainerServiceAbilityReq(id, i);
			abilityName, abilitySubText, abilityType = GetTrainerServiceInfo(id);
			if hasReq or (abilityType == "used") then
				requirements = requirements..separator..format(TRAINER_REQ_ABILITY, ability );
			else
				requirements = requirements..separator..format(TRAINER_REQ_ABILITY_RED, ability );
			end
			separator = ", ";
		end
	end
	-- Step Requirements
	local step, met = GetTrainerServiceStepReq(id);
	if step then
		if met then
			requirements = requirements..separator..format(TRAINER_REQ_ABILITY, step );
		else 
			requirements = requirements..separator..format(TRAINER_REQ_ABILITY_RED, step );
		end
	end
	if requirements ~= "" then
		ClassTrainerSkillRequirements:SetText(REQUIRES_LABEL.." "..requirements);
	else
		ClassTrainerSkillRequirements:SetText("");
	end
	-- Money Frame and cost
	local moneyCost, cpCost1, cpCost2 = GetTrainerServiceCost(id);
	local cp1, cp2 = UnitCharacterPoints("player");
	local unavailable, skillPointCost;
	if moneyCost == 0 then
		ClassTrainerDetailMoneyFrame:Hide();
		ClassTrainerCostLabel:Hide();
		ClassTrainerSkillDescription:SetPoint("TOPLEFT", "ClassTrainerCostLabel", "TOPLEFT", 0, 0);
	else
		ClassTrainerDetailMoneyFrame:Show();
		ClassTrainerCostLabel:Show();
		ClassTrainerSkillDescription:SetPoint("TOPLEFT", "ClassTrainerCostLabel", "BOTTOMLEFT", 0, -10);
		if GetMoney() >= moneyCost then
			SetMoneyFrameColor("ClassTrainerDetailMoneyFrame", "white");
		else
			SetMoneyFrameColor("ClassTrainerDetailMoneyFrame", "red");
			unavailable = 1;
		end
	end
	
	MoneyFrame_Update("ClassTrainerDetailMoneyFrame", moneyCost);
	if cpCost2 > 0 then
		ClassTrainerFrame.showDialog = 1;
		if cp2 < cpCost2 and serviceType ~= "used" then
			unavailable = 1;
		end
	elseif cpCost1 > 0 then
		ClassTrainerFrame.showDialog = 1;
		if cp1 < cpCost1 and serviceType ~= "used" then
			unavailable = 1;
		end
	else
		ClassTrainerFrame.showDialog = nil;
	end
	ClassTrainerSkillDescription:SetText( GetTrainerServiceDescription(id) );
	if serviceType == "available" and not unavailable then
		ClassTrainerTrainButton:Enable();
	else
		ClassTrainerTrainButton:Disable();
	end

	-- Close the confirmation dialog if you choose a different skill
	if StaticPopup_Visible("CONFIRM_PROFESSION") then
		StaticPopup_Hide("CONFIRM_PROFESSION");
	end
end

function ClassTrainerSkillButton_OnClick(self, button)
	if button == "LeftButton" then
		ClassTrainerFrame.selectedService = self:GetID();
		ClassTrainerFrame.showSkillDetails = 1;
		ClassTrainer_SetSelection(self:GetID());
		ClassTrainerFrame_Update();
	end
end

function ClassTrainerTrainButton_OnClick(self, button)
	if ( IsTradeskillTrainer() and ClassTrainerFrame.showDialog) then
		StaticPopup_Show("CONFIRM_PROFESSION");
	else
		BuyTrainerService(ClassTrainerFrame.selectedService);
		ClassTrainerFrame.showSkillDetails = 1;
		ClassTrainer_SetSelection(ClassTrainerFrame.selectedService);
		ClassTrainerFrame_Update();
	end
end

function ClassTrainer_SetSubTextColor(button, r, g, b)
	button.r = r;
	button.g = g;
	button.b = b;
	getglobal(button:GetName().."SubText"):SetTextColor(r, g, b);
end

function ClassTrainerCollapseAllButton_OnClick(self)
	if self.collapsed then
		self.collapsed = nil;
		ExpandTrainerSkillLine(0);
	else
		self.collapsed = 1;
		ClassTrainerListScrollFrameScrollBar:SetValue(0);
		CollapseTrainerSkillLine(0);
	end
end

function ClassTrainer_HideSkillDetails()
	ClassTrainerFrame.showSkillDetails = nil;
	ClassTrainerSkillName:Hide();
	ClassTrainerSkillIcon:Hide();
	ClassTrainerSkillRequirements:Hide();
	ClassTrainerSkillDescription:Hide();
	ClassTrainerDetailMoneyFrame:Hide();
	ClassTrainerCostLabel:Hide();
	ClassTrainerTrainButton:Disable();
end

function ClassTrainer_ShowSkillDetails()
	ClassTrainerSkillName:Show();
	ClassTrainerSkillIcon:Show();
	ClassTrainerSkillRequirements:Show();
	ClassTrainerSkillDescription:Show();
	ClassTrainerDetailMoneyFrame:Show();
	--ClassTrainerCostLabel:Show();
end

function ClassTrainer_SetToTradeSkillTrainer()
	CLASS_TRAINER_SKILLS_DISPLAYED = 10;
	ClassTrainerSkill11:Hide();
	ClassTrainerListScrollFrame:SetHeight(168);
	ClassTrainerDetailScrollFrame:SetHeight(135);
	local cp1, cp2 = UnitCharacterPoints("player");
	ClassTrainerHorizontalBarLeft:SetPoint("TOPLEFT", "ClassTrainerFrame", "TOPLEFT", 15, -259);
end

function ClassTrainer_SetToClassTrainer()
	CLASS_TRAINER_SKILLS_DISPLAYED = 11;
	ClassTrainerListScrollFrame:SetHeight(184);
	ClassTrainerDetailScrollFrame:SetHeight(119);
	ClassTrainerHorizontalBarLeft:SetPoint("TOPLEFT", "ClassTrainerFrame", "TOPLEFT", 15, -275);
end

-- Dropdown functions
function ClassTrainerFrameFilterDropDown_OnLoad(self)
	UIDropDownMenu_Initialize(self, ClassTrainerFrameFilterDropDown_Initialize);
	UIDropDownMenu_SetText(self, FILTER);
	UIDropDownMenu_SetWidth(self, 130);
end

function ClassTrainerFrameFilterDropDown_Initialize()
	local info = UIDropDownMenu_CreateInfo();

	-- Available button
	info.text = GREEN_FONT_COLOR_CODE..AVAILABLE..FONT_COLOR_CODE_CLOSE;
	info.value = "available";
	info.func = ClassTrainerFrameFilterDropDown_OnClick;
	info.checked = GetTrainerServiceTypeFilter("available");
	info.keepShownOnClick = 1;
	UIDropDownMenu_AddButton(info);

	-- Unavailable button
	info.text = RED_FONT_COLOR_CODE..UNAVAILABLE..FONT_COLOR_CODE_CLOSE;
	info.value = "unavailable";
	info.func = ClassTrainerFrameFilterDropDown_OnClick;
	info.checked = GetTrainerServiceTypeFilter("unavailable");
	info.keepShownOnClick = 1;
	UIDropDownMenu_AddButton(info);

	-- Unavailable button
	info.text = GRAY_FONT_COLOR_CODE..USED..FONT_COLOR_CODE_CLOSE;
	info.value = "used";
	info.func = ClassTrainerFrameFilterDropDown_OnClick;
	info.checked = GetTrainerServiceTypeFilter("used");
	info.keepShownOnClick = 1;
	UIDropDownMenu_AddButton(info);
end

function ClassTrainerFrameFilterDropDown_OnClick(self)	
	ClassTrainerListScrollFrameScrollBar:SetValue(0);
	if UIDropDownMenuButton_GetChecked(self) then
		SetTrainerServiceTypeFilter(self.value, 1);
	else
		SetTrainerServiceTypeFilter(self.value, 0);
	end
end
