--[[
GuildTools v 2.0

Addon that allows you to store in game info into SV.lua for further parsing.
Contains: 
BankScan     - scans all posessions of the character, including bank, bags amd bags in bank.
IncomingMail - grabs all the nonCOD items and money from mailbox as soon as it's opened. 
               Also keeps track of all the incoming mail including sender, item sent, money sent
			   and date when the message was received.
			   
Author: Roman Tarakanov (RTE/Arthas)
Date: Sep 13 '05

]]--
---------------------------------------------------------------
----------------------Standart mesages-------------------------
---------------------------------------------------------------

local GT_VER    = "2.0";
local GT_BS_VER = "2.0";
local GT_IM_VER = "2.0";

local MSG_GT_GREETING1 = "GuildTools v" .. GT_VER .. " is loaded.";
local MSG_GT_GREETING2 = "For more information type /gt info.";
local MSG_GT_GREETING = "GuildTools v" .. GT_VER .. ".";
local MSG_BS_GREETING = "BankScan v" .. GT_BS_VER .. ".";
local MSG_IM_GREETING = "IncomingMail v" .. GT_IM_VER .. ".";

local MSG_GT_ADDONOFF = "GT> AddOn is turned off, use /gt on to turn it on for this character";
local MSG_GT_ON = "GT> AddOn is now ENABLED for this character";
local MSG_GT_OFF = "GT> AddOn is now DISABLED for this character";
local MSG_GT_CLEARED = "GT> Variables have been cleared.";
local MSG_GT_INVALID = "GT> Not a valid command. See /gt info for list of commands.";
local MSG_DEBUG_ON = "GT> Debug mode is now ENABLED for this character";
local MSG_DEBUG_OFF = "GT> Debug mode is now DISABLED for this character";

local MSG_BS_ON = "GT> BankScan part of this AddOn is now ENABLED for this character";
local MSG_BS_OFF = "GT> BankScan part of this AddOn is now DISABLED for this character";
local MSG_BS_OK = "GT> BankScan | Success : scan was successful, now log out and run BankParser.exe to get html file";
local MSG_BS_BANKCLOSED = "GT> BankScan | Error : bank must be opened for this script to work.";

local MSG_IM_ON = "GT> IncomingMail part of this AddOn is now ENABLED for this character";
local MSG_IM_OFF = "GT> IncomingMail part of this AddOn is now DISABLED for this character";
local MSG_IM_START = "GT> IncomingMail started taking mail. Please do not do anything.";
local MSG_IM_CANCELED = "GT> IncomingMail grabbing procedure was canceled, some of the data might be corupted.";
local MSG_IM_SUCCESS = "GT> IncomingMail successfully grabbed your mail.";
local MSG_IM_SAVED = "GT> Mailed items database have been saved in SV. You can now run MailParser to get html file.";
local MSG_IM_CLEARED = "GT> IncomingMail varibles are cleared.";
local MSG_IM_NOBAG = "GT> There are no empy slots in your bags. Canceling IncomingMail.";

---------------------------------------------------------------
----------------Global GuildTools variables--------------------
---------------------------------------------------------------

--BankOpen indicator
-- 0 - bank closed
-- 1 - bank opened
local BankStatus = 0;
--Position in the array GT_Saved of the current character 
-- -1 - not in array
local Position=-1;
--Debug mode indicator 
-- 1 - debug mode on
-- 0 - debug mode off (default)
local DebugMode = 0;

---------------------------------------------------------------
------------------Global BankScan variables--------------------
---------------------------------------------------------------

--List of the bags to look in
local BanknBags = { -1, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4};

---------------------------------------------------------------
---------------Global IncomingMail variables-------------------
---------------------------------------------------------------

local MailOpened = false;
local State = 0;

local availableSlots = {};
local numSlots = 0;
local currentMessage = 1;
local From = 0;
local To = 0;

---------------------------------------------------------------
----------------Global GuildTools functions--------------------
---------------------------------------------------------------

--OnEvent function
function GT_OnEvent()	 
	GT_Debug("OnEvent is called");

	if (event == "VARIABLES_LOADED") then
		GT_Debug("Variables are loaded.");
		SlashCmdList["GUILDTOOLS"] = GT_SlashCommand;
		SLASH_GUILDTOOLS1 = "/guildtools";
		SLASH_GUILDTOOLS2 = "/gt";
		
		--GT_Saved = {};
		--GT_BS_ScannedItems = {};
		--GT_IM_MailedItems = {};
		--GT_IM_NumMailedItems = {};
		
		--Saved variables of the AddOn
		--Initialize if blank		
		if (not GT_Saved) then
            GT_Saved = {};
		end
		
		--Find varibles in GT_Saved if exist
		local i;
		GT_Debug("GT_Saved size: "..table.getn(GT_Saved));
		if (GT_Saved) then
			for  i = 1, table.getn(GT_Saved), 1 do
				if (string.find(GT_Saved[i].name, UnitName("player")) and string.find(GT_Saved[i].server, GetCVar("realmName"))) then
					if (not GT_Saved[i].addonOn) then GT_Saved[i].addonOn=false; end
					if (not GT_Saved[i].BSOn) then GT_Saved[i].BSOn=false; end
					if (not GT_Saved[i].mailOn) then GT_Saved[i].mailOn=false; end
					Position = i;
				end
			end
		end
		
		--If new character is observed - initialize the data.
		--On new character AddOn and mail grabber part (future functionality) are off by default
		if (Position == -1) then
			if (GT_Saved) then
				i = table.getn(GT_Saved)+1;
			else
				i = 1;
			end		
			GT_Saved[i] = { name=UnitName("player"), server=GetCVar("realmName"), 
				mailOn=false, addonOn=false, BSOn=false};
			Position = i;
		end
		
		GT_Debug("Position: "..Position);
		GT_Echo(MSG_GT_GREETING1);
		GT_Echo(MSG_GT_GREETING2);
		
		if (not GT_IM_Saved) then GT_IM_Saved = {}; end
		if (not GT_IM_NumMailedItems) then GT_IM_NumMailedItems = {}; end
		if (not GT_IM_MailedItems) then GT_IM_MailedItems = {}; end
		if (not GT_IM_NumMailedItems[Position]) then GT_IM_NumMailedItems[Position] = 0; end
		if (not GT_IM_MailedItems[Position]) then GT_IM_MailedItems[Position] = {}; end
		
	elseif (event == "BANKFRAME_OPENED") then
		GT_Debug("Bank was opened.");
		BankStatus = 1;

	elseif (event == "BANKFRAME_CLOSED") then
		GT_Debug("Bank was closed.");		
		BankStatus = 0;
	
	elseif (not GT_Saved[Position].addonOn) then return; 
	
	elseif (event == "MAIL_SHOW") then
		if (GT_Saved[Position].mailOn) then
			MailOpened = true;
			State = 0;
			GT_Echo(MSG_IM_START);
			GT_IM_ScanSlots();
		end
		
	elseif (event == "MAIL_CLOSED") then
		if (GT_Saved[Position].mailOn) then
			GT_Debug("State = "..State);
			if (State < 5 and State ~= -99) then GT_Echo(MSG_IM_CANCELED); end
			MailOpened = false;
			State = -99;
			GT_IM_Message:Hide();
			GT_IM_Update:Hide();
		end
		
	elseif (event == "MAIL_INBOX_UPDATE") then
		if (GT_Saved[Position].mailOn) then
			GT_Debug("grab!!!!!");
			GT_IM_Update:Show();
		end
		
	elseif (event == "BAG_UPDATE") then
		if (GT_Saved[Position].addonOn and GT_Saved[Position].mailOn) then
			GT_IM_ScanItems();
		end		
	end
end

--Slash command handler
function GT_SlashCommand(msg)
	msg = string.lower(msg);
	GT_Debug("/command: "..msg);

---------------------------------------------------------------
------------------GT standart commands-------------------------
---------------------------------------------------------------
	if (msg == "on") then
		GT_Saved[Position].addonOn = true;
		GT_Echo(MSG_GT_ON);
		
	elseif (msg == "off") then
		GT_Saved[Position].addonOn = false;
		GT_Echo(MSG_GT_OFF);
		
	elseif (msg == "debug") then
		
		if (DebugMode == 1) then
			GT_Echo(MSG_DEBUG_OFF);
			DebugMode = 0;
		else
			GT_Echo(MSG_DEBUG_ON);
			DebugMode = 1;
		end
		
	elseif (msg == "status") then
		if (GT_Saved[Position].addonOn) then
			
			local status = "DISABLED";
			if (GT_Saved[Position].addonOn) then 
				status = "ENABLED";
			end
			GT_Echo("GT> AddOn  is "..status..", see /gt info for information on the AddOn.");
			
			status = "DISABLED";
			if (GT_Saved[Position].BSOn) then 
				status = "ENABLED";
			end
			GT_Echo("GT> BankScan is "..status..", see /gt bsinfo for list of commands.");
			
			status = "DISABLED";
			if (GT_Saved[Position].mailOn) then 
				status = "ENABLED";
			end
			GT_Echo("GT> MailGrabber is "..status..", see /gt iminfo for list of commands.");
			
			status = "DISABLED";
			if (DebugMode == 1) then 
				status = "ENABLED";
			end
			GT_Echo("GT> Debug mode is "..status..".");
			
		else
			GT_Echo(MSG_ADDONOFF);
		end
		
	elseif (msg == "info") then
		GT_Echo(MSG_GT_GREETING);
		GT_Echo("GT> Scans possesions of the char, including bank into SV.lua.");
		GT_Echo("GT> List of components:");
		GT_Echo("GT> BankScan - scanns possesions of char. See /gt bsinfo for more info.");
		GT_Echo("GT> IncomingMail - tracks incoming mail. See /gt iminfo for more info.");
		GT_Echo("GT> -------------------------------------------------------------------");
		GT_Echo("GT> Available commands:");
		GT_Echo("GT> /gt status   shows the status of GuildTools and components.");
		GT_Echo("GT> /gt <on/off> turns the GuildTools on/off for this char.");
		GT_Echo("GT> /gt clear    clears all saved variables for this addon. If used all data will be lost.");
		GT_Echo("GT> /gt debug    tuggles Debug Mode on/off.");
		GT_Echo("GT> /gt info     shows this screen.");
		
	elseif (not GT_Saved[Position].addonOn) then
		GT_Echo(MSG_GT_ADDONOFF);
		return;
		
	elseif (msg == "clear") then
		if (GT_Saved[Position].addonOn) then
			--GT_Saved = {};
			GT_BS_ScannedItems = {};
			GT_BS_Money = 0;
			GT_IM_Saved = {};
			GT_IM_MailedItems[Position] = {};
			GT_IM_NumMailedItems[Position] = 0;
			GT_Echo(MSG_GT_CLEARED);
		else
			GT_Echo(MSG_ADDONOFF);
		end
		
	elseif (msg == "vars") then
		if (MailOpened) then 
			GT_Debug("MailOpened: true"); 
		else 
			GT_Debug("MailOpened: false"); 
		end
		GT_Debug("State: "..State);
		GT_Debug("From = "..From..", To = "..To);
		
---------------------------------------------------------------
-------------------------BS commands---------------------------
---------------------------------------------------------------
	elseif (msg == "bs") then
		local status = "DISABLED";
		if (GT_Saved[Position].BSOn) then 
			status = "ENABLED";
		end
		GT_Echo(MSG_BS_GREETING1);
		GT_Echo("GT> BankScan BankScan is "..status..", see /gt bsinfo for list of commands.");
		
	elseif (msg == "bson") then
		GT_Saved[Position].BSOn = true;		
		GT_Echo(MSG_BS_ON);
		
	elseif (msg == "bsoff") then
		GT_Saved[Position].BSOn = false;
		GT_Echo(MSG_BS_OFF);
		
	elseif (msg == "bscan") then
		if (GT_Saved[Position].BSOn) then
			NumItems = 1;
			if (BankStatus == 1) then
				BankScanItems = {};
				GT_Debug("GT_BS_DoScan is called.");
				GT_BS_DoScan();
				GT_Debug("GT_BS_DoScan exited.");
				GT_BS_Money = " "..GetMoney().." ";
				GT_Echo(MSG_BS_OK);
			else
				GT_Echo(MSG_BS_BANKCLOSED);
			end
		else
			GT_Echo(MSG_ADDONOFF);
		end
		
	elseif (msg == "bsinfo") then
		GT_Echo(MSG_BS_GREETING);
		GT_Echo("GT> Scans possesions of the char, including bank into SV.lua.");
		GT_Echo("GT> Available commands:");
		GT_Echo("GT> /gt bs         shows the status of BankScan.");
		GT_Echo("GT> /gt bs<on/off> turns the BankScan on/off for this char.");
		GT_Echo("GT> /gt bscan      performs the scan of possesions of this char for parsing into SV.lua.");
		GT_Echo("GT> /gt bsinfo     shows this screen.");
		
---------------------------------------------------------------
-------------------------IM commands---------------------------
---------------------------------------------------------------
	elseif (msg == "im") then
		local status = "DISABLED";
		if (GT_Saved[Position].addonOn) then 
			status = "ENABLED";
		end
		GT_Echo("GT> IncomingMail is "..status..", see /gt iminfo for list of commands.");
		
	elseif (msg == "imon") then
		GT_Saved[Position].mailOn = true;	
		GT_Echo(MSG_IM_ON);
		
	elseif (msg == "imoff") then
		GT_Saved[Position].mailOn = false;
		GT_Echo(MSG_IM_OFF);
		
	elseif (msg == "imsave") then
		GT_IM_Save();
		GT_Echo(MSG_IM_SAVED);
		
	elseif (msg == "imclear") then
		if (GT_Saved[Position].mailOn) then
			GT_IM_MailedItems[Position] = {};
			GT_IM_NumMailedItems[Position] = 0;		
			GT_Echo(MSG_IM_CLEARED);
		else
			GT_Echo(MSG_IMOFF);
		end
		
	elseif (msg == "iminfo") then
		GT_Echo(MSG_IM_GREETING1);
		GT_Echo("GT> Grabs all the nonCoD mail from your mailbox.");
		GT_Echo("GT> Also stores info about all the incoming mail in database.");
		GT_Echo("GT> Available commands:");
		GT_Echo("GT> /gt im         shows the status of IncomingMail.");
		GT_Echo("GT> /gt im<on/off> turns the IncomingMail on/off for this char.");
		GT_Echo("GT> /gt imsave     saves database of this char for parsing in SV.lua.");
		GT_Echo("GT> /gt imclear    clears database for this character (Saved with /gm imsave stays intact).");
		GT_Echo("GT> /gt iminfo     shows this screen.");
		
---------------------------------------------------------------
----------------------End of  commands-------------------------
---------------------------------------------------------------
	else
		GT_Echo(MSG_GT_INVALID);
		
	end
end

--Returns full info of the item on bag_id, slot_id, nil if item is not there
function GT_GetItemInfo(bag_id, slot_id)
	local count, texture, itemLink, itemName, i, command, itemQuality, itemDesc;
	
	if (not GetContainerItemInfo(bag_id, slot_id)) then 
		GT_Debug("No item in the slot "..bag_id..", "..slot_id);
		return nil;
	end
	
	--Get texture and count of the item in the current slot
	texture, count = GetContainerItemInfo(bag_id, slot_id);
	_,_,texture = string.find(texture, "%a+\\%a+\\([%w_]+)");
	
	--Get link and the name of the item in the current slot
	itemLink = GetContainerItemLink(bag_id, slot_id);
	_, _, itemLink, itemName = string.find(itemLink,
	"|H(item:%d+:%d+:%d+:%d+)|h%[([^]]+)%]|h|r$");
	_, _, itemQuality = GetItemInfo(itemLink);
	
	GT_Debug("Link: "..itemLink);
	--Set tooltip to the current item
	GT_ItemTooltip:ClearLines();
	GT_ItemTooltip:SetHyperlink(itemLink);
	
	--Copy the description test from the tooltip to the variable
	--<n> - new line symbol
	--<t> - tab symbol
	for i=1, GT_ItemTooltip:NumLines(),1 do
	
		command = getglobal("GT_ItemTooltipTextLeft" .. i);
		if (command:IsVisible()) then
			text_left = command:GetText();
		else
			text_left = "sssssss";
		end
		
		command = getglobal("GT_ItemTooltipTextRight" .. i);
		if (command:IsVisible()) then
			text_right = command:GetText();
		else
			text_right = "asdasds";
		end
		
		if (text_left and string.find(text_left, "\n")) then
			text_left = " ";
		end
		
		if (text_right and string.find(text_right, "\n")) then
			text_right = " ";
		end
		
		if (i == 1) then 
			itemDesc = text_left;
		else
			if (text_left) then 
				itemDesc = itemDesc.." <n> "..text_left;
			end
		end
		if (text_right) then
                  itemDesc = itemDesc.." <t> "..text_right;
		end
	end
	return itemName, itemQuality, itemDesc, count, texture;
end

--Prints message into the text chat window
function GT_Echo(message)
	if ( DEFAULT_CHAT_FRAME ) then 
		DEFAULT_CHAT_FRAME:AddMessage(message, 0.5, 0.5, 1.0);
	end
end

--Prints debug message into the chat window iff local variable DebugMode is set to 1
--otherwise does nothing
function GT_Debug(message)
	if (DebugMode == 1) then
		message = "GT><**Debug**> " .. message;
		if ( DEFAULT_CHAT_FRAME ) then 
			DEFAULT_CHAT_FRAME:AddMessage(message, 1.0, 0.0, 0.0);
		end
	end
end

---------------------------------------------------------------
---------------------BankScan functions------------------------
---------------------------------------------------------------

--This function actually scans all bags for items
function GT_BS_DoScan()
	--Array of items that will be saved in SavedVariables.lua
	--Initiated as empty, if BankScan is not called during the session all data will be wiped upon logout
	GT_BS_ScannedItems = {};
		
	local numItems = 1;
	local index, bag_id, slot_id, count, texture, itemLink, itemName, i, command, itemQuality, itemDesc;

	--Go through every slot in the bags (and bank)
	for index, bag_id in BanknBags do
		if (GetContainerNumSlots(bag_id)) then
			for slot_id = 1, GetContainerNumSlots(bag_id), 1 do
				if (GetContainerItemLink(bag_id, slot_id)) then
					
					itemName, itemQuality, itemDesc, count, texture = GT_GetItemInfo(bag_id, slot_id);
					
					--Save info on current item in the array
					itemDesc = "asdasd";
					GT_BS_ScannedItems[numItems] = {description="  "..itemDesc.." ",
													name=" "..itemName.." ", 
													number=" "..count.." ",
													pic=" "..texture.." ", 
													quality=" "..itemQuality.." "};
					numItems = numItems + 1;
				end
			end
		end
	end
end

---------------------------------------------------------------
------------------Incoming Mail functions----------------------
---------------------------------------------------------------

--Scans inventory for empty slots and stores the list of them
--in global variable availableSlots
function GT_IM_ScanSlots()
local index, bag_id, slot_id, i;
	GT_Debug("ScanSlots.");
	if (MailOpened and State == 0) then
		
		GT_IM_Message:Show();
		
		numSlots = 0;
		--availableSlots = nil;
		availableSlots = {};
		
		for index, bag_id in {4,3,2,1,0} do
			if (GetContainerNumSlots(bag_id)) then
				for slot_id = GetContainerNumSlots(bag_id), 1, -1 do
					if (not GetContainerItemLink(bag_id, slot_id)) then
						availableSlots[numSlots+1] = {bag_id = bag_id, slot_id = slot_id};
						numSlots = numSlots+1;
					end
				end
			end
		end
		
		GT_Debug("Empty space is scanned. There are "..numSlots.." empty slots.");
		
		if (numSlots < 1) then 
			GT_Echo(MSG_IM_NOBAG);
			State = -1;
			return;
		end
		
		State = 1;
		From = GT_IM_NumMailedItems[Position] + 1;
		currentMessage = 1;
		--GT_IM_Update:Show();
	end
end

--Takes mail from the mailbox
function GT_IM_GrabMail()
	GT_IM_Update:Hide();
	local index, bag_id, slot_id, i;
	GT_Debug("GrabMail is called.");
	if (MailOpened and State == 1) then
		
		GT_Debug("------>Next item. "..currentMessage.." out of "..GetInboxNumItems());
		if (GetInboxNumItems() < currentMessage) then 
			GT_Debug("End of messages."); 
			State = 4; 
			GT_IM_ScanItems(); 
			return; 
		end
		
		local sender, money, CODAmount, hasItem;
		_, _, sender, _, money, CODAmount, _, hasItem = GetInboxHeaderInfo(currentMessage);
		
		while ((not hasItem and money==0) or CODAmount>0) do
			GT_Debug("Message has no item nor cash or is COD - skipping.");
			currentMessage = currentMessage + 1;
			if (currentMessage > GetInboxNumItems()) then
				GT_Debug("End of messages.");
				State = 4;
				GT_IM_ScanItems();
				return; 
			end
			_, _, sender, _, money, CODAmount, _, hasItem = GetInboxHeaderInfo(currentMessage);
		end
		
		local _item = "None";
		local _pic = "INV_Misc_QuestionMark";
		GT_Debug("Grabbing stuff from message. From: "..sender);
		
		if (hasItem) then 
			GT_Debug("Taking item ...");
			TakeInboxItem(currentMessage);
			_item = "Unknown";
		end
		
		if (money>0) then 
			if (_item == "None") then 
				GT_Debug("No item, but there's money, taking ...");
				TakeInboxMoney(currentMessage); 
				_pic = "INV_Misc_Coin_01";
				
			elseif (_item == "Unknown") then
				GT_Debug("There's money AND item ...");
				State = 2;
				
			else 
				GT_Debug("WTF?????");
				State = -1;
				
			end
		end
		
		GT_Debug("Grabbing complete.");
		
		--Save info on current item in the array
		GT_IM_NumMailedItems[Position] = GT_IM_NumMailedItems[Position] + 1;
		GT_IM_MailedItems[Position][GT_IM_NumMailedItems[Position]] = {description="  ".._item.." ",
																		name=" ".._item.." ", 
																		number=" ".._item.." ",
																		pic=" ".._pic.." ", 
																		quality=" ".._item.." ",
																		from=" "..sender.." ",
																		coin=" "..money.." ",
																		when=" "..date("%m/%d/%y").." "};
		
		To = GT_IM_NumMailedItems[Position];
        GT_Debug("From = "..From.." To = "..To);
		
		if (State == 1) then 
			if (string.find(sender, "Auction") and string.find(sender, "House")) then 
				State = 3; 
			else 
				State = 1; 
			end
		end
		
		return;
		
	elseif (MailOpened and State == 2) then
        TakeInboxMoney(currentMessage);
		State = 1;
		return;
		
	elseif (MailOpened and State == 3) then
		GT_Debug("AH - waiting ...");
		State = 1;
		return;
		
	else
		GT_Debug("Just doing nothing.");
	end
end

--Scans global variable availableSlots for items, if found - updates MailedItems.
function GT_IM_ScanItems()
	GT_Debug("ScanItem is called.");
	if (MailOpened and State == 4) then
		
		if (To < From) then 
			State = 5; 
			GT_IM_Update:Hide();
			GT_IM_Message:Hide();
			GT_Echo(MSG_IM_SUCCESS);
			return; 
		end
		
		local bag_id, slot_id, count, texture, itemName, i, itemQuality, itemDesc;
		
		bag_id = availableSlots[numSlots].bag_id;
		slot_id = availableSlots[numSlots].slot_id;
		GT_Debug("Checking: "..bag_id..", "..slot_id);
		if (not GT_GetItemInfo(bag_id, slot_id)) then return; end
		
		for i = From, To, 1 do 
			GT_Debug("Checking: "..bag_id..", "..slot_id);
			if (bag_id > -1 and slot_id > -1) then
				itemName, itemQuality, itemDesc, count, texture = GT_GetItemInfo(bag_id, slot_id);
			else
				itemName = "Error";
				itemQuality = "1";
				itemDesc = "Error has occured.";
				count = "1";
				texture = "INV_Misc_QuestionMark";
			end
			
			--if (not itemName) then return; end
			
			if (GT_IM_MailedItems[Position][i].name == " None ") then
				GT_Debug("Skipping...");
				GT_IM_MailedItems[Position][i].description = " No item ";
				GT_IM_MailedItems[Position][i].name = " None ";
				GT_IM_MailedItems[Position][i].pic = " INV_Misc_Coin_01 ";
				GT_IM_MailedItems[Position][i].number = " 0 ";
				GT_IM_MailedItems[Position][i].quality = " 1 ";
			else
				if (not itemName) then From = i; GT_Debug("Ejecting..."); return; end
				if (numSlots > 0) then
					availableSlots[numSlots] = nil;
					numSlots = numSlots - 1;
				end
				
				GT_Debug("itemName='"..GT_IM_MailedItems[Position][i].name.."', replacing with '"..itemName.."'");
				GT_Debug("Changing...");
				GT_IM_MailedItems[Position][i].number = " "..count.." ";
				GT_IM_MailedItems[Position][i].quality = " "..itemQuality.." ";
				GT_IM_MailedItems[Position][i].description = " "..itemDesc.." ";
				GT_IM_MailedItems[Position][i].name = " "..itemName.." ";
				GT_IM_MailedItems[Position][i].pic = " "..texture.." ";
				
				if (numSlots > 0) then 
					bag_id = availableSlots[numSlots].bag_id;
					slot_id = availableSlots[numSlots].slot_id;
				else
					bag_id = -1;
					slot_id = -1;
				end
			end
		end
		
	State = 5;
	GT_IM_Update:Hide();
	GT_IM_Message:Hide();
	GT_Echo(MSG_IM_SUCCESS);
	end
end

--Deletes all messages from mailbox that do not contain item/money.
--Future functionality
function GT_IM_Delete()
	if (MailOpened and State == 10) then
		local i, money, CODAmount, hasItem;
		local numMessages = GetInboxNumItems();
		for i = 1, numMessages, 1 do
			_, _, _, _, money, CODAmount, _, hasItem = GetInboxHeaderInfo(i);
			if (not hasItem and money == 0  and CODAmount == 0) then
				GT_Debug("Message "..i.." will be deleted.");
			end
		end
	end
end

--Transfers data from GT_IM_NumMailedItems to BS_GT_Saved in reverse order
function GT_IM_Save()
	local i, j;
	j = 0;
	BS_GT_Saved = {};
	for i = GT_IM_NumMailedItems[Position], 1, -1 do
		if (GT_IM_MailedItems[Position][i]) then
			GT_IM_Saved[GT_IM_NumMailedItems[Position]+1-i-j] = GT_IM_MailedItems[Position][i];
		else
			j = j + 1;
		end
	end
end