local STANCESET_MAX_STANCES = 5;
BINDING_HEADER_STANCESETS = "Stance Sets"
BINDING_NAME_TOGGLESTANCESETSDLG = "Toggle Configuration Pane";
BINDING_NAME_STANCESETNEXT = "Equip Next Weapon Set";
STANCESETS_TITLE = "Configure Stance Sets"

UIPanelWindows["StanceSetsFrame"] = { area = "left", pushable = 5 }; 

function StanceSets_OnLoad()
	this:RegisterEvent("UPDATE_BONUS_ACTIONBAR");
	this:RegisterEvent("SPELLS_CHANGED");
	this:RegisterEvent("VARIABLES_LOADED");
	
	SlashCmdList["STANCESETS"] = StanceSets_SlashCmd;
	SLASH_STANCESETS1 = "/stancesets";
	
	StanceSets = { };
end

function StanceSets_OnShow()
	return StanceSets_UpdateAllStances();	
end

function StanceSets_OnEvent(event, arg1)
	if event == "UPDATE_BONUS_ACTIONBAR" then
		return StanceSets_FormChanged();
	elseif event == "SPELLS_CHANGED" then 
		return StanceSets_SpellsChanged();
	end
end

function StanceSets_SlashCmd(cmd)
	if cmd and cmd == "next" then
		return StanceSets_Next();
	end
	
	return StanceSets_Toggle();
end

function StanceSets_Toggle()
	if StanceSetsFrame:IsVisible() then
		HideUIPanel(StanceSetsFrame);
	else
		ShowUIPanel(StanceSetsFrame);
	end
end

function StanceSets_SpellsChanged()
	-- Spells have changed, this may mean that we've got a new shapeshift form
	if StanceSetsFrame:IsVisible() then
		return StanceSets_UpdateAllStances();
	end
end

function StanceSet_SetButtonTextureAndName(suffix,texture,itemName)
	local btn = getglobal("StanceSetsFrameSet"..suffix);
	if btn then
		SetItemButtonTexture(btn, texture);
		btn.itemName = itemName;
	end
end

function StanceSet_FindAndSetButtonTexture(suffix, itemName)
	if itemName and itemName ~= "" then
		local bag, slot = WeaponQuickSwap_FindItem(itemName);
		if bag and slot then
			local texture;
			if bag == -1 then
				texture = GetInventoryItemTexture("player", slot);
			else
				texture = GetContainerItemInfo(bag, slot);
			end
			StanceSet_SetButtonTextureAndName(suffix, texture, itemName);
		else
			-- if not found, just use a generic icon
			StanceSet_SetButtonTextureAndName(suffix, "Interface\\Icons\\INV_Misc_Gift_01", itemName);
		end
	else
		-- no item name, no icon
		StanceSet_SetButtonTextureAndName(suffix, nil, itemName);
	end
end

function StanceSets_UpdateAllStances()
	local allstances = StanceSets_GetAllForms();
	
	for i=1,STANCESET_MAX_STANCES do
		local stanceName = allstances[i];
		local frameStance = getglobal("StanceSetsFrameSet"..i);
		local frameLabel = getglobal("StanceSetsFrameSet"..i.."Title");
		
		if frameStance then
			local chkForceFirst = getglobal(frameStance:GetName().."ForceFirst");

			if stanceName then
				frameStance.StanceName = stanceName;
				
				frameStance:Show();
				if frameLabel then frameLabel:SetText(stanceName); end
				
				local playerName = UnitName("player");
				local setName = playerName.."_"..stanceName;
				local stanceSet = StanceSets[setName];
				
				if StanceSets[setName.."_ForceFirst"] then
					chkForceFirst:SetChecked(1);
				else
					chkForceFirst:SetChecked(nil);
				end
				
				if stanceSet then
				  StanceSet_FindAndSetButtonTexture(i.."MainHand1", stanceSet[1]);
				  StanceSet_FindAndSetButtonTexture(i.."OffHand1", stanceSet[2]);
				  StanceSet_FindAndSetButtonTexture(i.."MainHand2", stanceSet[3]);
				  StanceSet_FindAndSetButtonTexture(i.."OffHand2", stanceSet[4]);
				  StanceSet_FindAndSetButtonTexture(i.."MainHand3", stanceSet[5]);
				  StanceSet_FindAndSetButtonTexture(i.."OffHand3", stanceSet[6]);
				else
					StanceSet_SetButtonTextureAndName(i.."MainHand1", nil, nil);
					StanceSet_SetButtonTextureAndName(i.."OffHand1", nil, nil);
					StanceSet_SetButtonTextureAndName(i.."MainHand2", nil, nil);
					StanceSet_SetButtonTextureAndName(i.."OffHand2", nil, nil);
					StanceSet_SetButtonTextureAndName(i.."MainHand3", nil, nil);
					StanceSet_SetButtonTextureAndName(i.."OffHand3", nil, nil);
				end
			else				
				frameStance:Hide();
			end
		end  -- if frame found
	end  -- for i 1,MAX
end

function StanceSets_GetCurrentStanceSet()
	if not StanceSets then return; end

	local currentForm = StanceSets_GetCurrentForm();
	local playerName = UnitName("player");
	
	if not playerName then return; end  -- player name might not be defined if not logged yet

	local setName = playerName.."_"..currentForm;
	return StanceSets[setName], setName;
end

function StanceSets_Next()
	local playerFormSet = StanceSets_GetCurrentStanceSet();
	if playerFormSet then
		return WeaponSwap(unpack(playerFormSet));
	end
end

function StanceSets_FormChanged()
	local playerFormSet, setName = StanceSets_GetCurrentStanceSet();
	if playerFormSet then
		if StanceSets[setName.."_ForceFirst"] then
			-- must have at least one thing to do a swap
			if playerFormSet[1] or playerFormSet[2] then
				return WeaponSwap(playerFormSet[1], playerFormSet[2]);
			end
		elseif table.getn(playerFormSet) > 0 then
			-- If not forcing a set, only swap if we don't already a known set currently engaged
			local matchingsetidx = WeaponQuickSwap_FindCurrentSetIndex(16, 17, 1, playerFormSet);
			if not matchingsetidx then
				return WeaponSwap(unpack(playerFormSet));
			end
		end
	end
end

function StanceSets_GetCurrentForm()
	for i=1,GetNumShapeshiftForms(),1 do
		local _, name, isActive = GetShapeshiftFormInfo(i);
		if isActive then
			return name;
		end
	end
	
	return "Default";
end

function StanceSets_GetAllForms()
	local retVal = { };
	table.insert(retVal, "Default");
	for i=1,GetNumShapeshiftForms() do
		local _, name = GetShapeshiftFormInfo(i);
		table.insert(retVal, name);
	end
	
	return retVal;
end

function StanceSetSlot_OnEnter()
	if this.itemName and this.itemName ~= "" then
		GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
		
		local bag,slot = WeaponQuickSwap_FindItem(this.itemName);
		if bag and slot then
			if bag == -1 then
				GameTooltip:SetInventoryItem("player", slot);
			else
				GameTooltip:SetBagItem(bag,slot);
			end
		else
			GameTooltip:SetText(this.itemName, 1.0, 1.0, 1.0);
		end
		
		GameTooltip:Show();
	end
end

function StanceSetSlot_IDToSlotID(id)
	if id == 1 or id == 3 or id == 5 then
		return 16;
	else
		return 17;
	end
end

function StanceSetSlot_OnDragStart()
	local frmParent = this:GetParent();
	local playerName = UnitName("player");
	local setName = playerName.."_"..frmParent.StanceName;
	
	local stanceSet = StanceSets[setName];
	if stanceSet then
		stanceSet[this:GetID()] = nil;
		ResetCursor();
		StanceSets_UpdateAllStances();
	end
end

function StanceSetSlot_TakeItemOffCursor(srcBag, srcSlot)
	if srcBag == -1 then
		PickupInventoryItem(srcSlot);
	else
		PickupContainerItem(srcBag, srcSlot);
	end
end

function StanceSetSlot_OnClick(arg1)
	local slotID = StanceSetSlot_IDToSlotID(this:GetID());
	
	arg1 = arg1 or "";
	if arg1 == "LeftButton" then
		if CursorHasItem() and StanceSets_PickedupItem then
			local itemName = WeaponQuickSwap_GetItemName(StanceSets_PickedupItem.bag,
				StanceSets_PickedupItem.slot);
				
			if CursorCanGoInSlot(slotID) then
				local frmParent = this:GetParent();
				local playerName = UnitName("player");
				local setName = playerName.."_"..frmParent.StanceName;
		
				local stanceSet = StanceSets[setName];
				if not stanceSet then stanceSet = {}; end
				stanceSet[this:GetID()] = itemName;
				StanceSets[setName] = stanceSet;
					
				StanceSets_UpdateAllStances();
			else
				Print(itemName.." can not go in that slot!");
			end
	
			ResetCursor();
			StanceSetSlot_TakeItemOffCursor(StanceSets_PickedupItem.bag,StanceSets_PickedupItem.slot);
		end  -- if has item and we know where it came from

		StanceSets_PickedupItem = nil;	
	end  -- if left button
end

local StanceSets_Save_PickupContainerItem = PickupContainerItem;
PickupContainerItem = function (bag,slot)
	StanceSets_PickedupItem = { };
	StanceSets_PickedupItem.bag = bag;
	StanceSets_PickedupItem.slot = slot;
	return StanceSets_Save_PickupContainerItem(bag,slot);
end

local StanceSets_Save_PickupInventoryItem = PickupInventoryItem;
PickupInventoryItem = function (slot)
	StanceSets_PickedupItem = { };
	StanceSets_PickedupItem.bag = -1;
	StanceSets_PickedupItem.slot = slot;
	return StanceSets_Save_PickupInventoryItem(slot);
end

function StanceSetsForceCheck_OnClick()
	local frmParent = this:GetParent();
	local playerName = UnitName("player");
	local setName = playerName.."_"..frmParent.StanceName.."_ForceFirst";
	
	if not StanceSets then StanceSets = { }; end
	
	if (this:GetChecked()) then
		StanceSets[setName] = true;
		PlaySound("igMainMenuOptionCheckBoxOff");
	else
		StanceSets[setName] = nil;
		PlaySound("igMainMenuOptionCheckBoxOn");
	end
end
						
