--[[
	BagnonDB
		Functions for storing and accessing player inventory data
		This is intended to be completely seperate from Bagnon_Forever
		
	BagnonData has this format, which was taken from KC_Items
		Realm
			Character
				Bag
					size,count,[link]
					ItemSlot
						link,[count]
				Money
--]]

local VERSION = "1136";

--local globals
local currentPlayer = UnitName("player"); --the current player that's logged on
local realm = GetRealmName(); --what realm we're in


function BagnonDB_OnLoad()
	this:RegisterEvent("ADDON_LOADED");
	this:RegisterEvent("PLAYER_LOGIN");
	this:RegisterEvent("PLAYER_ENTERING_WORLD");
	this:RegisterEvent("PLAYER_LEAVING_WORLD");
	this:RegisterEvent("BANKFRAME_CLOSED");
	this:RegisterEvent("BANKFRAME_OPENED");
	this:RegisterEvent("PLAYERBANKSLOTS_CHANGED");
	this:RegisterEvent("PLAYER_MONEY");
end

function BagnonDB_OnEvent(event)
	if(event == "BAG_UPDATE") then
		BagnonDB_SaveBagData(arg1);
	elseif(event == "PLAYERBANKSLOTS_CHANGED") then
		BagnonDB_SaveBagData(-1);
	elseif(event == "BANKFRAME_CLOSED") then
		atBank = nil;
	elseif(event == "BANKFRAME_OPENED") then
		atBank = 1;
		BagnonDB_SaveBankData();
	elseif(event == "PLAYER_MONEY" or event == "PLAYER_LOGIN") then
		BagnonDB_SavePlayerMoney();
	elseif(event == "PLAYER_LEAVING_WORLD") then
		this:UnregisterEvent("BAG_UPDATE");
	elseif(event == "PLAYER_ENTERING_WORLD") then
		this:RegisterEvent("BAG_UPDATE");
		BagnonDB_SaveAllData();
	elseif(event == "ADDON_LOADED" and arg1 == "Bagnon_DB") then
		this:UnregisterEvent("ADDON_LOADED");
		BagnonDB_LoadVariables();
	end
end

function BagnonDB_LoadVariables()
	local realm = GetRealmName(); --what realm we're in
	
	if(not BagnonItems) then
		BagnonItems = {};
		BagnonItems.version = VERSION;
	end
	
	if(not BagnonItems[realm]) then
		BagnonItems[realm] = {};
	end
	
	if(not BagnonItems[realm][UnitName("player")]) then
		BagnonItems[realm][UnitName("player")] = {};
	end
	
	if(BagnonItems.version ~= VERSION) then
		BagnonDB_UpdateVersion();
	end
end

function BagnonDB_UpdateVersion()
	local realm = GetRealmName();
	
	BagnonItems = {};
	BagnonItems[realm] = {};
	BagnonItems[realm][UnitName("player")] = {};	
	BagnonItems.version = VERSION;
	
	DEFAULT_CHAT_FRAME:AddMessage("Bagnon Database updated to v" .. VERSION, 1, 1, 0);
end



--[[
	Storage Functions
--]]

function BagnonDB_SaveAllData()
	local i;
	for i = -1, 10, 1 do
		BagnonDB_SaveBagData(i);
	end
	BagnonDB_SavePlayerMoney();
end

function BagnonDB_SaveBankData()
	BagnonDB_SaveBagData(-1);
	local bagID;
	for bagID = 5, 10, 1 do
		BagnonDB_SaveBagData(bagID);
	end
end

--called whenever the bag updates, save all the bag's dat and
function BagnonDB_SaveBagData(bagID)
	--don't save bank data unless you're at the bank
	if( Bagnon_IsBankBag(bagID) and not atBank ) then
		return;
	end
	
	local size = GetContainerNumSlots(bagID);
	
	if(size > 0) then
		local link, count;
		
		if(bagID > 0) then
			link = BagnonDB_ToShortLink( GetInventoryItemLink("player", ContainerIDToInventoryID(bagID) ) );
		end
		
		count = GetInventoryItemCount("player", ContainerIDToInventoryID(bagID));
		
		--save bag size
		BagnonItems[realm][currentPlayer][bagID] = {};
		BagnonItems[realm][currentPlayer][bagID].s = size .. "," .. count .. ",";
		
		if(link) then
			BagnonItems[realm][currentPlayer][bagID].s = BagnonItems[realm][currentPlayer][bagID].s .. link;
		end

		--save all item info
		for index = 1, size, 1 do
			BagnonDB_SaveItemData(bagID, index);
		end
	else
		BagnonItems[realm][currentPlayer][bagID] = nil;
	end
end

function BagnonDB_SaveItemData(bagID, itemSlot)
	local texture, count = GetContainerItemInfo(bagID, itemSlot);
	local data;
	
	if(texture) then
	
		data = BagnonDB_ToShortLink( GetContainerItemLink(bagID, itemSlot) ) .. ",";
		if(count > 1) then
			data = data .. count;
		end
	end
	
	BagnonItems[realm][currentPlayer][bagID][itemSlot] = data;
end

function BagnonDB_SavePlayerMoney()
	BagnonItems[realm][currentPlayer].g = GetMoney();
end



--[[
	Access  Functions
--]]

--returns <player>'s current money
function BagnonDB_GetMoney(player)
	return BagnonItems[realm][player].g;
end

function BagnonDB_GetBagData(player, bagID)
	local data = BagnonItems[realm][player][bagID];
	if(data) then
		local _, _, size, count, link = string.find(data.s, "([%w_:]+),([%w_:]+),([%w_:]*)");
		
		if(link) then
			return size, "item:" .. link, tonumber(count);
		elseif(size) then
			return size, tonumber(count);
		end
	end
	return 0;
end

--returns the item link, (in the form of item:www:xxx:yyy:zzz),  texture (full path) , and count of <player>'s <item>
function BagnonDB_GetItemData(item)
	local itemData = BagnonItems[realm][item:GetParent().player][item.bag][item:GetID()];
	
	if(itemData) then
		local _, _, shortLink, count = string.find(itemData, "([%w_:]+),([%w_:]*)");
		
		shortLink = "item:" .. shortLink;
		
		if(count == "") then
			count = 1;
		else
			count = tonumber(count);
		end
		
		local _, _, _, _, _, _, _, _, texture = GetItemInfo(shortLink);
		
		return "item:" .. shortLink, texture, count;
	end
	
	return nil;
end

--return the item:x:y:z:a link format for <player>'s <item>
function BagnonDB_GetItemLink(item)
	local itemData = BagnonItems[realm][item:GetParent().player][item.bag][item:GetID()];
	
	if(itemData) then
		local _, _, shortLink = string.find(itemData, "([%w_:]+),([%w_:]*)");
		return "item:" .. shortLink;
	end
	
	return nil;
end

--return <player>'s <item>'s id (  the w part in the link format item:w:x:y:z )
function BagnonDB_GetItemID(item)
	local itemData = BagnonItems[realm][item:GetParent().player][item.bag][item:GetID()];
	
	if(itemData) then
		local _, _, id = string.find(itemData, "(%d+)");
		return tonumber(id);
	end
	
	return nil;
end

--return the full hyperlink of an item
function BagnonDB_GetFullItemLink(item)
	local link = BagnonDB_GetItemLink(item);
	
	if(link) then
		local name, ilink, quality = GetItemInfo( link );
		local r,g,b,hex = GetItemQualityColor( quality );
	
		return hex .. "|H".. link .. "|h[" .. name .. "]|h|r";
	end
end

--returns the texture of <player>'s <item>
function BagnonDB_GetItemTexture(item)
	local itemData = BagnonItems[realm][item:GetParent().player][item.bag][item:GetID()];
	
	if(itemData) then
		local _, _, shortLink  = string.find(itemData, "([%w_:]+),([%w_:]*)");
		local _, _, _, _, _, _, _, _, texture = GetItemInfo("item:" .. shortLink);
		return texture;
	end
	
	return nil;
end

--returns the size of the item's stack
function BagnonDB_GetItemCount(item)
	local itemData = BagnonItems[realm][item:GetParent().player][item.bag][item:GetID()];
	
	if(itemData) then
		local _, _, shortLink, count = string.find(itemData, "([%w_:]+),([%w_:]*)");
		
		if(count == "") then
			count = 1;
		else
			count = tonumber(count);
		end
		
		return count;
	end
	
	return nil;
end

--takes a full item hyperlink and returns the www:xxx:yyy:zzz form
function BagnonDB_ToShortLink(fullLink)
	if(fullLink) then
		local _, _, w, x, y, z = string.find(fullLink, "(%d+):(%d+):(%d+):(%d+)") ;
		return w .. ":" .. x .. ":" .. y .. ":" .. z;
	end
	return nil;
end