XPCount = {}

XPCount.init = function(_, _)
    EVENT_MANAGER:UnregisterForEvent("XPCount", EVENT_PLAYER_ACTIVATED)

    if XPCount.curZone ~= nil then
        d("Already init XPCount")
    end

    XPCount.resetCounter("zone")
    XPCount.zoneSet("zone")
    EVENT_MANAGER:RegisterForEvent("XPCountPlayerActivate", EVENT_PLAYER_ACTIVATED, XPCount.zoneChange)
    EVENT_MANAGER:RegisterForEvent("XPCountZoneChange", EVENT_ZONE_CHANGED, XPCount.zoneChange)
    EVENT_MANAGER:RegisterForUpdate("XPCountUIUpdate", 15000, XPCount.updateUI)

end

XPCount.zoneSet = function()
    XPCount.curZone = GetUnitZone("player")
    XPCount.zoneStart = GetTimeStamp()
    XPCount.zoneXpStart = GetUnitXP("player")
    XPCount.zoneVpStart = GetUnitVeteranPoints("player")
end

XPCount.resetCounter = function()
    XPCount.curZone = GetUnitZone("player")
    XPCount.clockStart = GetTimeStamp()
    XPCount.clockXpStart = GetUnitXP("player")
    XPCount.clockVpStart = GetUnitVeteranPoints("player")
end



XPCount.zoneChange = function()
    local playerZone = GetUnitZone("player")
    if playerZone ~= XPCount.curZone then
        if XPCount.curZone ~= "" then
            d("Exiting " .. XPCount.curZone .. " into " .. playerZone .. ":")
            XPCount.showStats()
        end

        XPCount.zoneSet()
    end
end

local function nn(val) if val == nil then return 0 end return val end

XPCount.updateUI = function()
    local time = GetTimeStamp()
    local elapsedZone = GetDiffBetweenTimeStamps(time, XPCount.zoneStart)
    local curXP = GetUnitXP("player")
    local curVP = GetUnitVeteranPoints("player")
    local xp = curXP - nn(XPCount.zoneXpStart)
    local vp = curVP - nn(XPCount.zoneVpStart)
    XPCountUIZoneTime:SetText(XPCount.formatTime(elapsedZone))
    if vp > 0 then
        xp = vp
        XPCountUIZoneXP:SetText(vp .. "vp")
    else
        XPCountUIZoneXP:SetText(xp .. "xp")
    end

    local rate = 0
    if elapsedZone > 0 then
        rate = math.floor((xp/elapsedZone)*3600)
    end
    XPCountUIZoneRate:SetText(rate .. "/h")
end

SLASH_COMMANDS["/zzz"] = XPCount.updateUI

XPCount.formatTime = function(delta)
    local sec = delta % 60
    delta = (delta - sec) / 60
    local min = delta % 60
    local hrs = (delta - min) / 60

    local out = ""
    if hrs > 0 then
        out = out .. hrs .. "h "
    end
    out = out .. min .. "m "
    return out
end

XPCount.showStats = function()
    local time = GetTimeStamp()
    local curXP = GetUnitXP("player")
    local curVP = GetUnitVeteranPoints("player")
    local xp = curXP - XPCount.zoneXpStart
    local vp = curVP - XPCount.zoneVpStart
    local elapsed = GetDiffBetweenTimeStamps(time, XPCount.zoneStart)
    d("Time in zone: " .. XPCount.formatTime(elapsed))
    if vp > 0 then
        d("Experience earned: "  .. vp .. "vp")
    elseif xp > 0 then
        d("Experience earned: " .. xp .. "xp")
    end
    if elapsed > 0 then
        if vp > 0 then
            d("Rate: " .. math.floor((vp/elapsed)*3600) .. "vp/h")
        elseif xp > 0 then
            d("Rate: " .. math.floor((xp/elapsed)*3600) .. "xp/h")
        end
    end
end

EVENT_MANAGER:RegisterForEvent("XPCount", EVENT_PLAYER_ACTIVATED, XPCount.init)