-- Cash Control by DeaTHCorE, based on Auditor2 by Alarisha

--CashControl = DongleStub("Dongle-1.2"):New("CashControl")
CashControl = LibStub("AceAddon-3.0"):NewAddon("CashControl")

--local DBG = LibStub("LibMyDebug-1.0", true)
--if not DBG then
--	C_Timer.After(2, function() print("Library |cffff2020LibMyDebug|r nicht gefunden! Nutze Chat-Ausgabe...") end)
--else
	--DBG:Print("CashControl", true, "LibMyDebug registriert, nutze DEBUG-Ausgabe...")
--	C_Timer.After(2, function() print("|cffff2020LibMyDebug|r registriert, nutze DEBUG-Ausgabe...") end)
--end

local debug = nil
local function dbgPrint(...)
	if debug then
    --if DBG then
	--	DBG:Print("CashControl", true, ...)
	--else
		DEFAULT_CHAT_FRAME:AddMessage(format("|cffff2020DEBUG:|r %s", select(1, ...) or "---"))
		PlaySoundFile("Interface\\AddOns\\BugSack\\Media\\error.ogg")
	--end
    end
end

--[[ LOCALE ]]--
local L = CASHCONTROL_LOCALS

--[[ DECLARE LOCALS ]]--
local addon = CashControl
local auditorPlayer = UnitName("player")
local pairs = pairs
local strgsub = string.gsub
local wipe = wipe
local auditorCurrentMoney, auditorLastMoney = nil, nil
local auditorMode = ""
local subHolder
local auditorHDay = { "6days", "5days", "4days", "3days", "2days", "1days", "0days" }
local auditorLogMode = { "loot", "merch", "void", "quest", "trade", "mail", "ah", "train", "taxi", "repairs", "other", "reconciliation", "guildbank", "transmog", "lfg", "garrison" } --Black Market
local auditorTimeframe = { "session", "day", "week", "total" }
local isBankOpen = nil
local isMerchantOpen = nil
--local isMerchant = nil
local isSellgrey = nil
local isAutoRepair = nil
--local isQuest = nil
--local isLoot = nil
--local reagentbankBuyed = nil

local COPPER_ABBR, SILVER_ABBR, GOLD_ABBR
local GOLD, SILVER, COPPER = GOLD, SILVER, COPPER

if not COPPER and COPPER_AMOUNT then
	GOLD = GOLD_AMOUNT:gsub("%s*%%d%s*", "")
	SILVER = SILVER_AMOUNT:gsub("%s*%%d%s*", "")
	COPPER = COPPER_AMOUNT:gsub("%s*%%d%s*", "")
end

if (COPPER:byte(1) or 128) > 127 then
	COPPER_ABBR = COPPER
	SILVER_ABBR = SILVER
	GOLD_ABBR = GOLD
else
	COPPER_ABBR = COPPER:sub(1, 1):lower()
	SILVER_ABBR = SILVER:sub(1, 1):lower()
	GOLD_ABBR = GOLD:sub(1, 1):lower()
end

local COLOR_WHITE, COLOR_GREEN, COLOR_RED = "ffffff", "00ff00", "ff0000"
local COLOR_COPPER, COLOR_SILVER, COLOR_GOLD = "eda55f", "c7c7cf", "ffd700"
local inf = 1/0
local auditorCN_cash, auditorCN_oldCash = 0, 0

local auditorCN = {
	["merch"]    = {mode = L.Vendor, open = false, gain = 0, spend = 0},
	["void"]    = {mode = L.Void, open = false, gain = 0, spend = 0},
	["transmog"]  = {mode = L.Transmog, open = false, gain = 0, spend = 0},
	["mail"]   = {mode = L.Mailbox, open = false, gain = 0, spend = 0},
	["ah"]        = {mode = L.AH, open = false, gain = 0, spend = 0},
	["train"]   = {mode = L.Trainer, open = false, gain = 0, spend = 0},
	["guildbank"] = {mode = L.Guildbank, open = false, gain = 0, spend = 0},
	["garrison"] = {mode = L.Garrison, open = false, gain = 0, spend = 0},
	}

--[[ DB DEFAULTS ]]--
local defaults = {
	profile = {
	},
	realm = {
		timeOffset = 0,
		useOffset = false,
	},
}

function addon:Print(s)
    print(s)
end

function addon:GetClassColor()
	local class, classFileName = UnitClass("player")
	local color = RAID_CLASS_COLORS[classFileName]
	return format("CFF%.2x%.2x%.2x",color.r*255,color.g*255,color.b*255)
end

--[[ LOCAL MAIN FUNCTIONS ]]--
local function AutoRepairPlease()
	local repairCost = GetRepairAllCost()
	if repairCost > 0 then
		if addon.db.realm[auditorPlayer].guildRepair and IsInGuild() then
			local guildMoney = GetGuildBankWithdrawMoney()
			if guildMoney == -1 then
				guildMoney = GetGuildBankMoney()
			end
			if guildMoney > repairCost then
				RepairAllItems(true)
				addon.db.realm[auditorPlayer].guildRepairsTally = addon.db.realm[auditorPlayer].guildRepairsTally + repairCost
				subHolder = strgsub((addon:MoneyStyle((repairCost * -1), true)), "-", "")
				addon:Print(L.GuildRepairSuccessful..subHolder)
				addon:Print(L.GuildTally..addon:MoneyStyle(addon.db.realm[auditorPlayer].guildRepairsTally))
				--auditorMode = "merch"
				return
			else
				addon:Print(L.GuildRepairFailed)
			end
		end
		if (repairCost < GetMoney()) then
			auditorMode = "repairs"
			RepairAllItems()
		else
			auditorMode = "merch"
			addon:Print(L.InsufficientFunds)
		end
	else
		auditorMode = "merch"
	end
end

local function ReconcileData() -- Reconcile data if Auditor and reality don't sync
	auditorCurrentMoney = GetMoney() -- Set current cash
	auditorLastMoney = auditorCurrentMoney
	auditorCN_cash = auditorCurrentMoney
	local data = addon.db.realm[auditorPlayer].data
	local historical = addon.db.realm[auditorPlayer].historical
	addon.db.realm.chars[auditorPlayer] = auditorCurrentMoney
	data.totals.incomings, data.totals.outgoings = 0, 0
	for _, logmode in pairs(auditorLogMode) do -- Add up total incomings and outgoings according to Auditor
		data.totals.incomings = data.totals.incomings + data[logmode]["total"].incomings
		data.totals.outgoings = data.totals.outgoings + data[logmode]["total"].outgoings
	end
	data.totals.actual = data.totals.incomings - data.totals.outgoings
	if data.totals.actual ~= auditorCurrentMoney then -- Does Auditor's data sync with reality? If not, make it so
		local diff = auditorCurrentMoney - data.totals.actual
		if diff > 0 then
			for _,logmode in pairs(auditorTimeframe) do
				data["reconciliation"][logmode].incomings = data["reconciliation"][logmode].incomings + diff
			end
			historical[auditorHDay[7]]["reconciliation"].incomings = data["reconciliation"]["day"].incomings
			data.totals.incomings = data.totals.incomings + diff
		elseif diff < 0 then
			diff = diff * -1;
			for _,logmode in pairs(auditorTimeframe) do
				data["reconciliation"][logmode].outgoings = data["reconciliation"][logmode].outgoings + diff
			end
			historical[auditorHDay[7]]["reconciliation"].outgoings = data["reconciliation"]["day"].outgoings
			data.totals.outgoings = data.totals.outgoings + diff
		end
		data.totals.actual = auditorCurrentMoney
		addon:Print(L.Reconciled..auditorPlayer)
	end
end

local function UpdateTimeFrame() -- Check if Auditor should reset
	local dateTable = date("*t")
	local timeDiff = time{year = dateTable.year, day = dateTable.day, month = dateTable.month, hour = dateTable.hour, min = dateTable.min, sec = dateTable.sec} - addon.db.realm[auditorPlayer].timeDate.timeDate
	local daysPassedSinceLogin = math.floor(timeDiff / 86400)
	addon.db.realm[auditorPlayer].timeDate.niceDate = date("%d %b '%y") -- Keep date current
	if daysPassedSinceLogin ~= 0 then -- If we haven't logged in for a week, then we need to clear the historical days data and the week data
		if daysPassedSinceLogin > 6 then
			addon.db.realm[auditorPlayer].historical = nil
			addon:NewCharDB()
			addon:DataReset("day")
			addon:DataReset("week")
		else -- Begin the Truffle Shuffle!
			addon:DataReset("week")
			while daysPassedSinceLogin > 0 do
				for i = 1, 6 do
					for _,logmode in pairs(auditorLogMode) do
						addon.db.realm[auditorPlayer].historical[auditorHDay[i]][logmode].incomings = addon.db.realm[auditorPlayer].historical[auditorHDay[i+1]][logmode].incomings
						addon.db.realm[auditorPlayer].historical[auditorHDay[i]][logmode].outgoings = addon.db.realm[auditorPlayer].historical[auditorHDay[i+1]][logmode].outgoings
					end
				end
				for _,logmode in pairs(auditorLogMode) do
					addon.db.realm[auditorPlayer].historical[auditorHDay[7]][logmode] = {incomings = 0, outgoings = 0}
				end
				daysPassedSinceLogin = daysPassedSinceLogin - 1
			end
			for _,hday in pairs(auditorHDay) do
				for _,logmode in pairs(auditorLogMode) do
					addon.db.realm[auditorPlayer].data[logmode]["week"].incomings = addon.db.realm[auditorPlayer].data[logmode]["week"].incomings + addon.db.realm[auditorPlayer].historical[hday][logmode].incomings
					addon.db.realm[auditorPlayer].data[logmode]["week"].outgoings = addon.db.realm[auditorPlayer].data[logmode]["week"].outgoings + addon.db.realm[auditorPlayer].historical[hday][logmode].outgoings
				end
			end
		end
		addon:DataReset("day") -- Lastly, if the date has changed, obviously we need to clear out the day's data.
		addon.db.realm[auditorPlayer].timeDate.timeDate = time{year = dateTable.year, day = dateTable.day, month = dateTable.month, hour = 0} + (addon.db.realm.timeOffset * 3600) -- Time offset crap. Amfg, I hate this stuff. It's retarded.
	end
end


--local events = {"QUEST_COMPLETE" = "quest", "LOOT_CLOSED" = "loot", "GARRISON_MISSION_NPC_CLOSED" = "garrison"}
local lastEvent = "-"
local lastEvent2 = "-"
local lastEvent3 = "-"
local lastEvent4 = "-"
local prntDebug = nil
local function UpdateFigures() -- Main money data allocation function
	auditorCurrentMoney = GetMoney()
	local dbTemp = auditorLastMoney
	local diff = auditorCurrentMoney - auditorLastMoney
	addon.db.realm[auditorPlayer].data.totals.actual = auditorCurrentMoney
	addon.db.realm.chars[auditorPlayer] = auditorCurrentMoney
	auditorLastMoney = auditorCurrentMoney
	if (diff == 0) or (diff == nil) then
		dbgPrint("UpdateFigures->no money diff!!! <-> auditorMode is: "..auditorMode)
		return
	end
	local data = addon.db.realm[auditorPlayer].data
	local historical = addon.db.realm[auditorPlayer].historical
	if auditorMode == "" then -- Deals with random cash from an obfuscated source
		prntDebug = true
        --debug
        if auditorMode == "" then
            dbgPrint(format("NO AUDITORMODE. LastEvent1: %s LastEvent2: %s LastEvent3: %s LastEvent4: %s", lastEvent, lastEvent2, lastEvent3, lastEvent4))
        end --debug
		if lastEvent == "QUEST_COMPLETE" then
			auditorMode = "quest"
			dbgPrint("UpdateFigures-> no auditorMode avail, lastEvent: QUEST_COMPLETE! it's was set to QUEST!!!")
		elseif lastEvent == "LOOT_CLOSED" then
			auditorMode = "loot"
			dbgPrint("UpdateFigures-> no auditorMode avail, lastEvent: LOOT_CLOSED! it's was set to LOOT!!!")
		elseif lastEvent == "GARRISON_MISSION_NPC_CLOSED" then
			auditorMode = "garrison"
			dbgPrint("UpdateFigures-> no auditorMode avail, lastEvent: GARRISON_MISSION_NPC_CLOSED! it's was set to GARRISON!!!")
		elseif lastEvent == "GARRISON_SHIPYARD_NPC_CLOSED" then
			auditorMode = "quest"
			dbgPrint("UpdateFigures-> no auditorMode avail, lastEvent: GARRISON_SHIPYARD_NPC_CLOSED! it's was set to QUEST!!!")
		elseif lastEvent == "GARRISON_ARCHITECT_CLOSED" then
			auditorMode = "garrison"
			dbgPrint("UpdateFigures-> no auditorMode avail, lastEvent: GARRISON_ARCHITECT_CLOSED! it's was set to GARRISON!!!")

		elseif lastEvent == "BANKFRAME_CLOSED" then
			auditorMode = "merch"
			dbgPrint("UpdateFigures-> no auditorMode avail, lastEvent: BANKFRAME_CLOSED! it's was set to MEACH!!!")
        --elseif reagentbankBuyed then
		--	auditorMode = "merch"
		--	dbgPrint("UpdateFigures-> no auditorMode avail and Reagentbank was buyed!!! it's was set to MERCH!!!")
		else
			auditorMode = "other"
			dbgPrint(format("UpdateFigures-> no auditorMode, set to OTHER! Last event=%s", lastEvent))
		end
	end
	if diff > 0 then
		if ((auditorMode=="taxi") or (auditorMode=="train") or (auditorMode=="repairs") or (auditorMode=="transmog") or (auditorMode=="void")) then -- Prevention of incomings to categories that can't have incomings
			dbgPrint("UpdateFigures->INcomings-> auditorMode was not correct!!!!! is: "..auditorMode.." and can't have incomings! now it's set to OTHER! Last Mode was: "..lastEvent)
			auditorMode = "other"
		end
		for _,logmode in pairs(auditorTimeframe) do
			data[auditorMode][logmode].incomings = data[auditorMode][logmode].incomings + diff
		end
		data.totals.incomings = data.totals.incomings + diff
		historical[auditorHDay[7]][auditorMode].incomings = data[auditorMode]["day"].incomings
	elseif diff < 0 then
		if (auditorMode == "loot" or auditorMode == "lfg") then -- Prevention of outgoings to categories that can't have outgoings
			dbgPrint("UpdateFigures->OUTgoing-> auditorMode was not correct!!!!!! is: "..auditorMode.." and can't have a outgoing! it's now set to OTHER!!!")
			auditorMode = "other"
		end
		diff = diff * -1
		for _,logmode in pairs(auditorTimeframe) do
			data[auditorMode][logmode].outgoings = data[auditorMode][logmode].outgoings + diff
		end
		data.totals.outgoings = data.totals.outgoings + diff
		historical[auditorHDay[7]][auditorMode].outgoings = data[auditorMode]["day"].outgoings
	end
	if auditorMode == "repairs" then -- Reset in case we just repaired and are still at a merchant
		if addon.db.realm[auditorPlayer].autoRepair == true then
			subHolder = strgsub((addon:MoneyStyle((diff * -1), true)), "-", "")
			addon:Print(L.RepairSuccessful..subHolder)
		end
		auditorMode = "merch"
	end
end

local function CashNotify()
	for i, v in pairs(auditorCN) do
		if v.open then
			v.open = false
			-- TODO: DeaTHCorE - v.mode unbekannt??? prüfen warum!!!!
			--if not v.mode then
			--	v.mode = "UNBEKANNT!"
			--end
			--**--
			if v.gain > 0 then
				addon:Print(L.Gained..addon:MoneyStyle(v.gain, true)..v.mode)
			end
			if v.spend > 0 then
				subHolder = strgsub((addon:MoneyStyle((v.spend * -1), true)), "-", "")
				addon:Print(L.Spent..subHolder..v.mode)
			end
			local diff = v.gain - v.spend
			if diff ~= 0 and v.gain > 0 and v.spend > 0 then
				if diff > 0 then
					addon:Print(L.ChangeProfit..addon:MoneyStyle(diff, true)..v.mode)
				else
					subHolder = strgsub((addon:MoneyStyle(diff, true)), "-", "")
					addon:Print(L.ChangeLoss..subHolder..v.mode)
				end
			end
			-- Spank variables
			v.gain = 0
			v.spend = 0
		end
	end
end

local function CashNotifyUpdate()
	auditorCN_oldCash, auditorCN_cash = auditorCN_cash, GetMoney()
	local aCN = auditorCN[auditorMode]
	if aCN and (aCN.open == true) then
		local diff = auditorCN_cash - auditorCN_oldCash
		if diff > 0 then
			aCN.gain = aCN.gain + diff
		elseif diff < 0 then
			aCN.spend = aCN.spend - diff
		end
	end
end

local function SellGreys()
	for bag=0, 4 do
		for slot=1, GetContainerNumSlots(bag) do
			if not isMerchantOpen then
				--auditorCN["merch"].open = addon.db.realm[auditorPlayer].notifyVendor
				CashNotify()
				isSellgrey = nil
				return
			end
			local link = GetContainerItemLink(bag, slot)
			--if link and select(3, GetItemInfo(link)) == 0 then
			if link then
				--name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(link)
				_, _, quality, _, _, _, _, _, _, _, vendorPrice = GetItemInfo(link)
				if (quality == 0) and (vendorPrice ~= 0) then
					--DeaTHCorE - changed for timing and is UseContainerItem protected? so use securecall("UseContainerItem", bag, slot)...
					--ShowMerchantSellCursor(1)
					--UseContainerItem(bag, slot)
					PickupContainerItem(bag, slot)
					if CursorHasItem() then
						PickupMerchantItem()
					--else
						--dbgPrint(format("SellGreys-> Cursor has no Item!!! Item = %s", link))
					end
					--ClearCursor()
				elseif addon.db.realm[auditorPlayer].WarningPrice and (quality == 0) and (vendorPrice == 0) then
					--dbgPrint(format("SellGreys-> Item: %s has no price (price=%s)...", link, vendorPrice or "nil"))
					DEFAULT_CHAT_FRAME:AddMessage(format("|cffff2020CashControl:|r %s", format(L.WarningPrice, link)))
				end
			end
		end
	end
	if not isMerchantOpen then
		CashNotify()
	end
	isSellgrey = nil
end

--local function SellGreysEnd()
--	auditorMode = ""
--end

--[[ LOCAL EVENT FUNCTIONS ]]--
local f = CreateFrame("Frame")
f:RegisterEvent("MERCHANT_SHOW")
f:RegisterEvent("MERCHANT_CLOSED")
--f:RegisterEvent("VOID_STORAGE_OPEN")
--f:RegisterEvent("VOID_STORAGE_CLOSE")
f:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
f:RegisterEvent("BANKFRAME_OPENED")
f:RegisterEvent("BANKFRAME_CLOSED")

--f:RegisterEvent("REAGENTBANK_PURCHASED");

--f:RegisterEvent("GUILDBANKFRAME_OPENED")
--f:RegisterEvent("GUILDBANKFRAME_CLOSED")
f:RegisterEvent("QUEST_COMPLETE")
--f:RegisterEvent("SCENARIO_COMPLETED")
f:RegisterEvent("LOOT_OPENED")

f:RegisterEvent("LOOT_CLOSED")--required???

f:RegisterEvent("TAXIMAP_OPENED")
f:RegisterEvent("TRADE_SHOW")
f:RegisterEvent("TRADE_CLOSED")
f:RegisterEvent("MAIL_SHOW")
--f:RegisterEvent("MAIL_INBOX_UPDATE")--
f:RegisterEvent("MAIL_CLOSED")
f:RegisterEvent("TRAINER_SHOW")
f:RegisterEvent("TRAINER_CLOSED")
f:RegisterEvent("AUCTION_HOUSE_SHOW")
f:RegisterEvent("AUCTION_HOUSE_CLOSED")
--f:RegisterEvent("CHAT_MSG_MONEY")
f:RegisterEvent("PLAYER_MONEY")
f:RegisterEvent("CONFIRM_TALENT_WIPE")
--f:RegisterEvent("TRANSMOGRIFY_OPEN")
--f:RegisterEvent("TRANSMOGRIFY_CLOSE")
--f:RegisterEvent("LFG_COMPLETION_REWARD")

f:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED") --Fires when the number of bank bag slots purchased by the player changes

--for loot from garrison missions...
--f:RegisterEvent("GARRISON_MISSION_NPC_OPENED")
--f:RegisterEvent("GARRISON_MISSION_NPC_CLOSED")--required???

--for loot from chests from garrison missions by the wiederverwertung...
f:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")

--for garrison building upgrades...
--f:RegisterEvent("GARRISON_ARCHITECT_OPENED")
--f:RegisterEvent("GARRISON_ARCHITECT_CLOSED")
--f:RegisterEvent("GARRISON_BUILDING_PLACED")

--for garrison shipyard quests...
--f:RegisterEvent("GARRISON_SHIPYARD_NPC_OPENED")
--f:RegisterEvent("GARRISON_SHIPYARD_NPC_CLOSED") --required???

--for garrison quests...
--f:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE")
--"GARRISON_MISSION_BONUS_ROLL_COMPLETE" --testen für ganisionsquests!!!

--PLAYER_TRADE_MONEY
--SEND_MAIL_MONEY_CHANGED
--SEND_MAIL_COD_CHANGED
--TRADE_CURRENCY_CHANGED
--TRADE_MONEY_CHANGED
--CURRENCY_DISPLAY_UPDATE
--INELIGIBLE_FOR_LOOT
--SHIPMENT_CRAFTER_OPENED
--SHOW_LOOT_TOAST

--	self:RegisterEvent("BLACK_MARKET_OPEN");
--	self:RegisterEvent("BLACK_MARKET_CLOSE");
--	self:RegisterEvent("UPDATE_INVENTORY_ALERTS");
--	self:RegisterEvent("MERCHANT_UPDATE");
f:SetScript("OnEvent", function(self, event, ...)
	--dbgPrint(format("event %s was called... auditorMode START %s", event, auditorMode))
	if event == "PLAYER_MONEY" then
		local oldMode = auditorMode
		UpdateTimeFrame()
		UpdateFigures()
		CashNotifyUpdate()
		if (CashControl_Broker) then CashControl_Broker:UpdateBrokerText() end
		if (not InRepairMode() and auditorMode == "repairs") or (auditorMode == "other") or (auditorMode == "") then
			dbgPrint("DEBUG 1: CashControl-> PLAYER_MONEY, change auditorMode from ", auditorMode, " to merch...")
            auditorMode = "merch"
		end
		--if isQuest then
		--	if auditorMode == "quest" then
		--		auditorMode = ""
		--	end
		--	isQuest = nil
		--end
		--if isLoot then
		--	if auditorMode == "loot" then
		--		auditorMode = ""
		--	end
		--	isLoot = nil
		--end
		--if reagentbankBuyed then
		--	auditorMode = ""
		--	reagentbankBuyed = nil
		--end
		--if isMerchant and not isMerchantOpen and not isSellgrey then
		--	auditorMode = ""
		--	isMerchant = nil
		--end
		if prntDebug then
			prntDebug = nil
			dbgPrint(format("event %s called. auditorMode start/end: %s / %s, lastEvent %s", event, oldMode, auditorMode, lastEvent))
		end
	elseif event == "LOOT_OPENED" then
		auditorMode = "loot"
	elseif event == "MERCHANT_SHOW" then
		--isMerchant = true
		isMerchantOpen = true
		if (addon.db.realm[auditorPlayer].autoRepair == true) and CanMerchantRepair() then
			dbgPrint("DEBUG 1: CashControl-> autoRepair...")
            isAutoRepair = true
			AutoRepairPlease()
			isAutoRepair = nil
		else
			local cost, canRepair = GetRepairAllCost()
            dbgPrint("DEBUG 1: CashControl-> cost: ", cost, " - canRepair: ", canRepair)
            if canRepair then -- is item destruct?
                dbgPrint("DEBUG 1: CashControl: SET REPAIR MODE!!!!!")
				auditorMode = "repairs"
            else
                dbgPrint("DEBUG 1: CashControl: SET VENDOR MODE!!!!!")
                auditorMode = "merch"
			end
		end
		auditorCN["merch"].open = addon.db.realm[auditorPlayer].notifyVendor
		if addon.db.realm[auditorPlayer].sellGreys == true then
			isSellgrey = true
			C_Timer.After(1, SellGreys)
            --addon:ScheduleTimer("AUDITOR_SELLGREYS_DELAY", SellGreys, 1)
		end
	elseif event == "UPDATE_INVENTORY_DURABILITY" then --DeaTHCorE - single item repair or repair from other addon...i hope it ;)
        if not isAutoRepair and CanMerchantRepair() and auditorMode ~= "repairs" then -- can merchant repair?
            --dbgPrint("DEBUG 2: CashControl: UPDATE_INVENTORY_DURABILITY - mode: ", auditorMode, " - LastEvent: ", lastEvent, " - LastEvent2: ", lastEvent2)
			local cost, canRepair = GetRepairAllCost()
            --dbgPrint("DEBUG 2: CashControl-> cost: ", cost, " - canRepair: ", canRepair, " - mode: ", auditorMode)
            if canRepair then -- is item destruct?
                dbgPrint("DEBUG 2: CashControl: SET REPAIR MODE!!!!!")
				auditorMode = "repairs"
			end
        --elseif isMerchantOpen and auditorMode ~= "merch" then
            --dbgPrint("DEBUG 2: CashControl: SET VENDOR MODE!!!!!")
            --auditorMode = "merch"
		end
	elseif event == "VOID_STORAGE_OPEN" then
		auditorMode = "void"
	elseif event == "MERCHANT_CLOSED" then
		isMerchantOpen = nil
		if not isSellgrey then
			CashNotify()
			--auditorMode = ""
			--isMerchant = nil
		--elseif addon.db.realm[auditorPlayer].sellGreys == true then
		--	addon:ScheduleTimer("AUDITOR_SELLGREYS_END_DELAY", SellGreysEnd, 4)
			--dbgPrint(format("event %s called. sellGray is nil", event))
		--else
		--	dbgPrint(format("event %s called. sellGray is true", event))
		end
    elseif --[[event == "LOOT_CLOSED" or]] event == "TRADE_CLOSED" --[[or event == "GARRISON_MISSION_NPC_CLOSED"]] then
		auditorMode = ""
	elseif event == "TRANSMOGRIFY_CLOSE" or event == "GUILDBANKFRAME_CLOSED" or event == "MAIL_CLOSED" or event == "TRAINER_CLOSED" or event == "AUCTION_HOUSE_CLOSED" or event == "VOID_STORAGE_CLOSE" or event == "GARRISON_ARCHITECT_CLOSED" then
		CashNotify()
		if event ~= "GARRISON_ARCHITECT_CLOSED" then
			auditorMode = ""
		end
	elseif event == "BANKFRAME_CLOSED" then
		if isBankOpen then
			isBankOpen = nil
			CashNotify()
			auditorMode = ""
		end
	elseif event == "QUEST_COMPLETE" or event == "SCENARIO_COMPLETED" or event == "GARRISON_MISSION_NPC_OPENED" or event == "GARRISON_SHIPYARD_NPC_OPENED" then
		--isQuest = true
		auditorMode = "quest"
		--if event == "SCENARIO_COMPLETED" then--debug
		--	dbgPrint(format("event %s called. auditorMode is quest", event))
		--end
	--elseif event == "GARRISON_SHIPYARD_NPC_OPENED" then --garrison shipyard quests
		--auditorMode = "quest"
        --debug test here...
    --elseif event == "GARRISON_MISSION_NPC_OPENED" then
    	--auditorMode = "quest"
    --elseif event == "GARRISON_MISSION_BONUS_ROLL_COMPLETE" then --garrison quests
        --dbgPrint(format("garrison quests: event %s was called, auditorMode %s, lastEvent2 %s,lastEvent3 %s,lastEvent4 %s, ", event, auditorMode, lastEvent2, lastEvent3, lastEvent4))
	elseif event == "TAXIMAP_OPENED" then
		auditorMode = "taxi"
	elseif event == "TRADE_SHOW" then
		auditorMode = "trade"
	elseif event == "BANKFRAME_OPENED" then --needed if a bankslot is purchased...
		isBankOpen = true
		auditorMode = "merch"
		auditorCN["merch"].open = addon.db.realm[auditorPlayer].notifyVendor
	elseif event == "TRANSMOGRIFY_OPEN" then
		auditorMode = "transmog"
		auditorCN[auditorMode].open = addon.db.realm[auditorPlayer].notifyTransmog
	elseif event == "MAIL_SHOW" then
		auditorMode = "mail"
		auditorCN[auditorMode].open = addon.db.realm[auditorPlayer].notifyMailbox
--[[	elseif event == "MAIL_INBOX_UPDATE" then
		-- Quel's fix: when we open a mail message, see if this is a successfull Auction.
		if (InboxFrame.openMailID ~= nil) then
			a, b, sender, subject, money = GetInboxHeaderInfo(InboxFrame.openMailID)
			if (sender ~= nil) then
				if (string.find(subject, L.AH_Succ) ~= nil) or (string.find (subject, L.AH_Outbid) ~= nil) then
					auditorMode = "ah"
					if addon.db.realm[auditorPlayer].notifyAH == true then
						auditorCN[auditorMode].open = true
					end
				else
					auditorMode = "mail"
					if addon.db.realm[auditorPlayer].notifyMailbox == true then
						auditorCN[auditorMode].open = true
					end
				end
			end
		end ]]--
	elseif event == "TRAINER_SHOW" then
		auditorMode = "train"
		auditorCN["train"].open = addon.db.realm[auditorPlayer].notifyTrainer
	elseif event == "AUCTION_HOUSE_SHOW" then
		auditorMode = "ah"
		auditorCN["ah"].open = addon.db.realm[auditorPlayer].notifyAH
	elseif event == "GUILDBANKFRAME_OPENED" then
		auditorMode = "guildbank"
		auditorCN["guildbank"].open = addon.db.realm[auditorPlayer].notifyGuildbank
	elseif event == "CONFIRM_TALENT_WIPE" then
		auditorMode = "train"
	elseif event == "LFG_COMPLETION_REWARD" then
		auditorMode = "lfg"
	elseif event == "PLAYERBANKBAGSLOTS_CHANGED" then
		if isBankOpen then
			auditorMode = "merch"
			auditorCN["merch"].open = addon.db.realm[auditorPlayer].notifyVendor
			CashNotify()
		end
		--dbgPrint(format("event %s was called... auditorMode is %s", event, auditorMode))
	--elseif event == "REAGENTBANK_PURCHASED" then
	--		reagentbankBuyed = true
	--		auditorMode = "merch"
	--		auditorCN["merch"].open = addon.db.realm[auditorPlayer].notifyVendor
	--		CashNotify()
	--		dbgPrint(format("event %s was called... auditorMode is %s", event, auditorMode))
	elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
		local spell = select(5, ...)
		if spell == 168179 then -- spell Wiederverwertung... in den kisten is auch gold als loot
			--dbgPrint(format("event %s was called... old auditorMode = '%s'", event, auditorMode))
			--isLoot = true
			auditorMode = "loot"
		elseif spell == 125801 then --spell kampfhaustier heilen bei einem stallmeister...
			auditorMode = "merch"
		end
	elseif event == "GARRISON_ARCHITECT_OPENED" or event == "GARRISON_BUILDING_PLACED" then --garrison
		auditorMode = "garrison"
		auditorCN["garrison"].open = addon.db.realm[auditorPlayer].notifyGarrison
	end
	--debug here...
	if event ~= "PLAYER_MONEY" then
        lastEvent4 = lastEvent3
        lastEvent3 = lastEvent2
        lastEvent2 = lastEvent
		lastEvent = event
	end
end)

--[[ STARTUP ]]--
--function addon:Initialize()
function addon:OnInitialize()
	addon.db = LibStub("AceDB-3.0"):New("CashControlDB", defaults)
--	addon.db = addon:InitializeDB("CashControlDB", defaults)
	auditorSessionTime = time()
	auditorFocus = auditorPlayer
	if not addon.db.realm[auditorPlayer] then addon:NewCharDB() end -- Create DB for char if it doesn't exist
	if not addon.db.realm[auditorPlayer].playerClassColor then
		addon.db.realm[auditorPlayer].playerClassColor = addon:GetClassColor()
	end
	addon:UpgradeCategories() -- Add any new categories
    --dbgPrint("initialize 1")
--    C_Timer.After(2, function() dbgPrint("initialize 2") end)
end


--function addon:Enable()
function addon:OnEnable()
	--deathcore - function wird nicht gehooked, sehen warum!!!
    --dbgPrint("hooking...")
    hooksecurefunc("RepairAllItems", function(...) addon:RepairAllItems(...) end)
	--**--
    hooksecurefunc("CursorHasItem", function() addon:CursorHasItem() end)
	hooksecurefunc("TakeInboxMoney", function(...) addon:TakeInboxMoney(...) end)
	UpdateTimeFrame() -- Data housekeeping
	addon:DataReset("session") -- Clear out last session's data
	ReconcileData()
	if (CashControl_Broker) then CashControl_Broker:UpdateBrokerText() end
end

--[[ DB MANIPULATION ]]--
function addon:DataReset(timeFrame, char)
	local charToReset = ""
	if char ~= nil then
		charToReset = char
	else
		charToReset = auditorPlayer
	end
	for _,logmode in pairs(auditorLogMode) do
		addon.db.realm[charToReset].data[logmode][timeFrame] = {incomings = 0, outgoings = 0}
	end
	if timeFrame == "session" then -- Reset time for gold per hour
		auditorSessionTime = time()
	end
end

function addon:PurgeData(name)
	auditorFocus = auditorPlayer
	addon.db.realm[name] = nil
	addon.db.realm.chars[name] = nil
	if auditorPlayer == name then
		addon:NewCharDB() -- Create DB for Char
		ReconcileData() -- Reconcile DB with reality
	end
	ReloadUI()
end

function addon:NewCharDB(arg)
	if arg == nil then arg = auditorPlayer end
	if not addon.db.realm[arg] then -- Normal
		addon.db.realm[arg] = { data = { totals = {incomings = 0, outgoings = 0, actual = 0}}, timeDate = {niceDate = date("%d %b '%y"), timeDate = (math.floor((time() + (addon.db.realm.timeOffset * 3600)) / 86400)) * 86400}}
		for _,logmode in pairs(auditorLogMode) do
			addon.db.realm[arg].data[logmode] = {}
			for _,timeframe in pairs(auditorTimeframe) do
				addon.db.realm[arg].data[logmode][timeframe] = {incomings = 0, outgoings = 0}
			end
		end
		addon.db.realm[arg].playerClassColor = addon:GetClassColor()
		addon.db.realm[arg].notifyVendor = true
		addon.db.realm[arg].notifyVoid = true
		addon.db.realm[arg].notifyMailbox = true
		addon.db.realm[arg].notifyAH = true
		addon.db.realm[arg].notifyGuildbank = true
		addon.db.realm[arg].notifyTrainer = true
		addon.db.realm[arg].notifyGarrison = true
		addon.db.realm[arg].notifyTransmog = true
		addon.db.realm[arg].autoRepair = false
		addon.db.realm[arg].guildRepair = false
		addon.db.realm[arg].sellGreys = false
		addon.db.realm[arg].WarningPrice = false
	end
	if not addon.db.realm[arg].historical then -- Historical
		addon.db.realm[arg].historical = {}
		for _,hday in pairs(auditorHDay) do
			addon.db.realm[arg].historical[hday] = {}
			for _,logmode in pairs(auditorLogMode) do
				addon.db.realm[arg].historical[hday][logmode] = {incomings = 0, outgoings = 0}
			end
		end
	end
	if not addon.db.realm.chars then -- Character totals
		addon.db.realm.chars = {}
	end
	if not addon.db.realm.chars[arg] then
		addon.db.realm.chars[arg] = 0
	end
	if not addon.db.realm[arg].guildRepairsTally then -- Guild repairs tally
		addon.db.realm[arg].guildRepairsTally = 0
	end
end

function addon:UpgradeCategories()
	for charParse,_ in pairs (addon.db.realm.chars) do
		for _,logmode in pairs(auditorLogMode) do -- If I've added a new category
			if not addon.db.realm[charParse].data[logmode] then
				addon.db.realm[charParse].data[logmode] = {}
				for _,timeframe in pairs(auditorTimeframe) do
					addon.db.realm[charParse].data[logmode][timeframe] = {incomings = 0, outgoings = 0}
				end
			end
		end
		if not addon.db.realm[charParse].historical then -- Historical
			addon.db.realm[charParse].historical = {}
			for _,hday in pairs(auditorHDay) do
				addon.db.realm[charParse].historical[hday] = {}
				for _,logmode in pairs(auditorLogMode) do
					addon.db.realm[charParse].historical[hday][logmode] = {incomings = 0, outgoings = 0}
				end
			end
		else
			for _,hday in pairs(auditorHDay) do
				for _,logmode in pairs(auditorLogMode) do
					if not addon.db.realm[charParse].historical[hday][logmode] then
						addon.db.realm[charParse].historical[hday][logmode] = {incomings = 0, outgoings = 0}
					end
				end
			end
		end
	end
end

--[[ HOOK FUNCTIONS ]]--
function addon:RepairAllItems(useGuildMoney)
	dbgPrint("DEBUG: CashControl: Hooked Func RepairAllItems called, auditorMode: ", auditorMode)
    auditorMode = "repairs"
	if not addon.db.realm[auditorPlayer].autoRepair then
        if useGuildMoney and IsInGuild() then
			local guildMoney = GetGuildBankWithdrawMoney()
			if guildMoney == -1 then
				guildMoney = GetGuildBankMoney()
			end
			if guildMoney > repairCost then
                auditorMode = "guildbank"
            end
        end
	elseif useGuildMoney then
        auditorMode = "guildbank"
    end
	dbgPrint("DEBUG: CashControl: Hooked Func RepairAllItems finished, auditorMode: ", auditorMode)
end

function addon:CursorHasItem()
	if InRepairMode() then
		auditorMode = "repairs"
        dbgPrint("DEBUG: CashControl: In Repair Mode, auditorMode: ", auditorMode)
	end
end

function addon:TakeInboxMoney(mailIndex)
	local _, _, sender, subject, _, _, _, _, _, _, _, _= GetInboxHeaderInfo(mailIndex)
	if sender ~= nil then
		if strfind(sender, L.AuctionHouse) or strfind(subject, L.AH_Succ) or strfind (subject, L.AH_Outbid) then
			auditorMode = "ah"
			auditorCN[auditorMode].open = addon.db.realm[auditorPlayer].notifyAH
		else
			auditorMode = "mail"
			auditorCN[auditorMode].open = addon.db.realm[auditorPlayer].notifyMailbox
		end
	else
		auditorMode = "mail"
		auditorCN[auditorMode].open = addon.db.realm[auditorPlayer].notifyMailbox
	end
end

--[[ UTILITY FUNCTIONS ]]--
function addon:PrintResetTime()
    --deathcore - TODO: wochentag übersetzen...
    --local d = date("*t", addon.db.realm[auditorPlayer].timeDate.timeDate + 86400)
    --for k,v in pairs(d) do dbgPrint("k: ", k, " - v: ",v) end
    local d = date(L.ResetTime, addon.db.realm[auditorPlayer].timeDate.timeDate + 86400)
	--if GetLocale() ~= "enUS" then
	if GetLocale() == "deDE" then
        local wDays = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
        for _, v in pairs(wDays) do
            if string.match(d, v) then
                --dbgPrint(L[v])
                d = string.gsub(d, v, L[v])
                break
            end
        end
    end
    --addon:Print(date(L.ResetTime, addon.db.realm[auditorPlayer].timeDate.timeDate + 86400))
    addon:Print(d)
end


--DeaTHCorE - format money with seperators....eg here: comma and decimals
function comma_value(n) -- credit http://richard.warburton.it
	local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
	return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end

local function AddMoneyGoldSeperators(moneyValue, caller)
--print("DEBUG Cash Control: func AddMoneyGoldSeperators, caller: ", caller)
    if moneyValue then
        local val = math.floor(moneyValue)
        if val then
            local left, num, right = string.match(val, '^([^%d]*%d)(%d*)(.-)$') -- credit http://richard.warburton.it
            return left..(num:reverse():gsub('(%d%d%d)', '%1,'):reverse())..right
        else
            return moneyValue
        end
    else
        return nil
    end
end

local function FormatMoneyFull(value, colored)
	local gold = abs(value / 10000)
	local silver = abs(mod(value / 100, 100))
	local copper = abs(mod(value, 100))
	local negl = ""
    
local newGold = AddMoneyGoldSeperators(gold, "full")
if newGold then
    gold = newGold
end

	local color = COLOR_WHITE
	if value > 0 then
		if colored then
			color = COLOR_GREEN
		end
	elseif value < 0 then
		negl = "-"
		if colored then
			color = COLOR_RED
		end
	end
	if value == inf or value == -inf then
		return format("|cff%s%s|r", color, value)
	elseif value ~= value then
		return format("|cff%s0|r|cff%s%s|r", COLOR_WHITE, COLOR_COPPER, COPPER_ABBR)
	elseif value >= 10000 or value <= -10000 then
		if newGold then--deathcore - ändere hier zu immer string für gold
            return format("|cff%s%s%s|r|cff%s%s|r |cff%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r", color, negl, gold, COLOR_GOLD, GOLD_ABBR, color, silver, COLOR_SILVER, SILVER_ABBR, color, copper, COLOR_COPPER, COPPER_ABBR)
        else
            return format("|cff%s%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r", color, negl, gold, COLOR_GOLD, GOLD_ABBR, color, silver, COLOR_SILVER, SILVER_ABBR, color, copper, COLOR_COPPER, COPPER_ABBR)
        end
	elseif value >= 100 or value <= -100 then
		return format("|cff%s%s%d|r|cff%s%s|r |cff%s%d|r|cff%s%s|r", color, negl, silver, COLOR_SILVER, SILVER_ABBR, color, copper, COLOR_COPPER, COPPER_ABBR)
	else
		return format("|cff%s%s%d|r|cff%s%s|r", color, negl, copper, COLOR_COPPER, COPPER_ABBR)
	end
end

local function FormatMoneyShort(value, colored)
	local color = COLOR_WHITE
	if colored then
		if value > 0 then
			color = COLOR_GREEN
		elseif value < 0 then
			color = COLOR_RED
		end
	end
	if value == inf or value == -inf then
		return format("|cff%s%s|r", color, value)
	elseif value ~= value then
		return format("|cff%s0|r|cff%s%s|r", COLOR_WHITE, COLOR_COPPER, COPPER_ABBR)
	elseif value >= 10000 or value <= -10000 then

local gold = abs(value / 10000)
local newGold = AddMoneyGoldSeperators(gold, "short")
if newGold then
    gold = newGold
end

        --return format("|cff%s%.1f|r|cff%s%s|r", color, value / 10000, COLOR_GOLD, GOLD_ABBR)
        return format("|cff%s%d|r|cff%s%s|r", color, gold, COLOR_GOLD, GOLD_ABBR)
	elseif value >= 100 or value <= -100 then
		return format("|cff%s%.1f|r|cff%s%s|r", color, value / 100, COLOR_SILVER, SILVER_ABBR)
	else
		return format("|cff%s%d|r|cff%s%s|r", color, value, COLOR_COPPER, COPPER_ABBR)
	end
end

local function FormatMoneyCondensed(value, colored)
	local negl = ""
	local negr = ""
	if value < 0 then
		if colored then
			negl = "|cffff0000-(|r"
			negr = "|cffff0000)|r"
		else
			negl = "-("
			negr = ")"
		end
	end
	local gold = floor(math.abs(value) / 10000)
	local silver = mod(floor(math.abs(value) / 100), 100)
	local copper = mod(floor(math.abs(value)), 100)

    
local newGold = AddMoneyGoldSeperators(gold, "condensed")
if newGold then
    gold = newGold
end

	if value == inf or value == -inf then
		return format("%s|cff%s%s|r%s", negl, COLOR_COPPER, math.abs(value), negr)
	elseif value ~= value then
		return format("|cff%s0|r", COLOR_COPPER)
--	elseif gold ~= 0 then
	elseif newGold then
		return format("%s|cff%s%s|r.|cff%s%02d|r.|cff%s%02d|r%s", negl, COLOR_GOLD, gold, COLOR_SILVER, silver, COLOR_COPPER, copper, negr)
    elseif not newGold and gold ~= 0 then
		return format("%s|cff%s%d|r.|cff%s%02d|r.|cff%s%02d|r%s", negl, COLOR_GOLD, gold, COLOR_SILVER, silver, COLOR_COPPER, copper, negr)
	elseif silver ~= 0 then
		return format("%s|cff%s%d|r.|cff%s%02d|r%s", negl, COLOR_SILVER, silver, COLOR_COPPER, copper, negr)
	else
		return format("%s|cff%s%d|r%s", negl, COLOR_COPPER, copper, negr)
	end
end

function addon:MoneyStyle(value, colored, bar)
	local cashFormat = CashControl_Broker.db.profile.cashFormat
	if bar == true then
		if cashFormat.Bar == "Full" then
			return FormatMoneyFull(value, colored)
		elseif cashFormat.Bar == "Short" then
			return FormatMoneyShort(value, colored)
		else
			return FormatMoneyCondensed(value, colored)
		end
	else
		if cashFormat.toolTip == "Full" then
			return FormatMoneyFull(value, colored)
		elseif cashFormat.toolTip == "Short" then
			return FormatMoneyShort(value, colored)
		else
			return FormatMoneyCondensed(value, colored)
		end
	end
end
