--***********************************************************
--**                    THE INDIE STONE                    **
--**                      Author: yuri                     **
--***********************************************************

require "ISUI/ISPanel"

ISGameStatisticPanel = ISPanel:derive("ISGameStatisticPanel");
ISGameStatisticPanel.instance = nil;

local function roundstring(_val)
    return tostring(ISDebugUtils.roundNum(_val,2));
end

function ISGameStatisticPanel.OnOpenPanel()
    if ISGameStatisticPanel.instance==nil then
        ISGameStatisticPanel.instance = ISGameStatisticPanel:new (100, 100, 800, 800, "Statistic");
        ISGameStatisticPanel.instance:initialise();
        ISGameStatisticPanel.instance:instantiate();
    end

    ISGameStatisticPanel.instance:addToUIManager();
    ISGameStatisticPanel.instance:setVisible(true);

    return ISGameStatisticPanel.instance;
end

function ISGameStatisticPanel:initialise()
    ISPanel.initialise(self);

    self.flareCount = false;
    self.colExt = { r=1, g=1, b=1 };
    self.colInt = { r=1, g=1, b=1 };
    self.flareID = -1;
	self.cGreen = { r=0,g=0.3,b=0,a=1};
    self.cRed = { r=0.3,g=0,b=0,a=1};
end

function ISGameStatisticPanel:createChildren()
    ISPanel.createChildren(self);

    _, obj = ISDebugUtils.addLabel(self, {}, self.width/2, 15, "Server Statistic", UIFont.Medium, true); obj.center = true;

	local margin = 5;
	local xmarg = 20;
	
	local columnWidth = (self.width)/3;

    local boxWidth = 100;
	
	local x = 20;
    local x1 = 20;
	local xw = 120;
	local xw2 = 40;
    local y, obj = 50, false;

    ------- COLUMN 1 ---------
	x = 20
	y = 50
	y, self.buttonToggleMonitor = ISDebugUtils.addButton(self,"toggle_statistic",x ,y ,columnWidth*2-(xmarg*2), 20, "Toggle statistic monitor", ISGameStatisticPanel.onClick);
	self.buttonToggleMonitor.backgroundColor = self.cRed;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "Period:", UIFont.Small, true); x = x + xw2;
	y, self.periodValue = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;

    y = y+margin*2; x = x1;
    _, obj = ISDebugUtils.addLabel(self, {}, x, y, "Last report:", UIFont.Small, true); x = x + xw;
	y, self.lastReport = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true);
	
	y = y+margin*3; x = x1;
    y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "UPDATE PERIOD", UIFont.Small, true); obj.center = true;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "min:", UIFont.Small, true); x = x + xw2;
	_, self.minUpdatePeriod = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "max:", UIFont.Small, true); x = x + xw2;
	_, self.maxUpdatePeriod = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "avg:", UIFont.Small, true); x = x + xw2;
	y, self.avgUpdatePeriod = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	y = y+margin; x = x1;
	y, self.buttonChartUpdatePeriod = ISDebugUtils.addButton(self, "CHART_UPDATE_PERIOD",x, y, columnWidth-2*xmarg, 20, getText("IGUI_Chart"),ISGameStatisticPanel.onClick);
	
	y = y+margin*3; x = x1;
    y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "SERVER CELL DISK OPERATIONS", UIFont.Small, true); obj.center = true;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "load:", UIFont.Small, true); x = x + xw2;
	_, self.loadCellFromDisk = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "save:", UIFont.Small, true); x = x + xw2;
	y, self.saveCellToDisk = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	y = y+margin; x = x1;
	y, self.buttonChartDiskOperations = ISDebugUtils.addButton(self, "CHART_DISK_OPERATIONS",x, y, columnWidth-2*xmarg, 20, getText("IGUI_Chart"),ISGameStatisticPanel.onClick);
	
	y = y+margin*3; x = x1;
    y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "MEMORY", UIFont.Small, true); obj.center = true;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "used:", UIFont.Small, true); x = x + xw2;
	y, self.usedMemory = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "free:", UIFont.Small, true); x = x + xw2;
	y, self.freeMemory = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	y = y+margin; x = x1;
	y, self.buttonChartMemory = ISDebugUtils.addButton(self, "CHART_MEMORY",x, y, columnWidth-2*xmarg, 20, getText("IGUI_Chart"),ISGameStatisticPanel.onClick);
	
	y = y+margin*3; x = x1;
	y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "CONNECTIONS", UIFont.Small); obj.center = true;
    y = y+3;

    y, self.connections = ISDebugUtils.addComboBox(self,"combo_floats", xmarg, y, columnWidth-(xmarg*2), UIFont.Small, ISGameStatisticPanel.onCombo);
    self.connections:addOption("- NONE -");
    self.connections.selected = 1;
    
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "IP:", UIFont.Small, true); x = x + xw2*2;
	y, self.connection_ip = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "access:", UIFont.Small, true); x = x + xw2*2;
	y, self.connection_access = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "Username:", UIFont.Small, true); x = x + xw2*2;
	y, self.connection_username = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "Ping:", UIFont.Small, true); x = x + xw2*2;
	_, self.connection_ping = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "avg:", UIFont.Small, true); x = x + xw2;
	y, self.connection_ping_avg = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "Player count:", UIFont.Small, true); x = x + xw2*2;
	_, self.connection_players_count = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "avg:", UIFont.Small, true); x = x + xw2;
	y, self.connection_players_desync_avg = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "max:", UIFont.Small, true); x = x + xw2*2;
	_, self.connection_players_desync_max = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "tlprt:", UIFont.Small, true); x = x + xw2;
	y, self.connection_players_desync_teleport = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;

	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "Zombie count:", UIFont.Small, true); x = x + xw2*2;
	_, self.connection_zombies_count = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "avg:", UIFont.Small, true); x = x + xw2;
	y, self.connection_zombies_desync_avg = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "max:", UIFont.Small, true); x = x + xw2*2;
	_, self.connection_zombies_desync_max = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "tlprt:", UIFont.Small, true); x = x + xw2;
	y, self.connection_zombies_desync_teleport = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	
	y = y+margin; x = x1;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "FPS:", UIFont.Small, true); x = x + xw2*2;
	_, self.connection_fps = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	_, obj = ISDebugUtils.addLabel(self, {}, x, y, "Avg:", UIFont.Small, true); x = x + xw2;
	y, self.connection_fpsAvg = ISDebugUtils.addLabel(self, {}, x, y, "___", UIFont.Small, true); x = x + xw2;
	
	y = y+margin; x = x1;
	self.histogramm_y = y;
	self.histogramm_w = columnWidth- 2*xmarg;
	self.histogramm_h = 64;
	y = y+self.histogramm_h+margin;
	
	y = y+margin; x = x1;
    y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "PLAYERS", UIFont.Small, true); obj.center = true;
	y = y+margin; x = x1;
	self.connection_players = ISScrollingListBox:new(x, y, columnWidth- 2*xmarg, self.height - y - 20);
    self.connection_players:initialise();
    self.connection_players:instantiate();
    self.connection_players.itemheight = 35;
    self.connection_players.selected = 0;
    self.connection_players.joypadParent = self;
    self.connection_players.font = UIFont.NewSmall;
    self.connection_players.doDrawItem = self.drawUsersList;
    self.connection_players.drawBorder = true;
    self.connection_players.target = self;
    self:addChild(self.connection_players);
	
	------- COLUMN 2 ---------
	x1 = columnWidth+20
	y = 80
	
	y = y+margin; x = x1;
    y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "INCOME PACKETS", UIFont.Small, true); obj.center = true;
	y = y+margin; x = x1;
	self.incomePackets = ISScrollingListBox:new(x, y, columnWidth- 2*xmarg, self.height - y - 60);
    self.incomePackets:initialise();
    self.incomePackets:instantiate();
    self.incomePackets.itemheight = 35;
    self.incomePackets.selected = 0;
    self.incomePackets.joypadParent = self;
    self.incomePackets.font = UIFont.NewSmall;
    self.incomePackets.doDrawItem = self.drawIncomePacketsList;
    self.incomePackets.drawBorder = true;
    self.incomePackets.target = self;
    self:addChild(self.incomePackets);
	
	------- COLUMN 3 ---------
	x1 = 2*columnWidth+20
	y = 80
	
	y = y+margin; x = x1;
    y, obj = ISDebugUtils.addLabel(self, {}, x - xmarg + columnWidth/2, y, "OUTCOME PACKETS", UIFont.Small, true); obj.center = true;
	y = y+margin; x = x1;
	self.outcomePackets = ISScrollingListBox:new(x, y, columnWidth- 2*xmarg, self.height - y - 60);
    self.outcomePackets:initialise();
    self.outcomePackets:instantiate();
    self.outcomePackets.itemheight = 35;
    self.outcomePackets.selected = 0;
    self.outcomePackets.joypadParent = self;
    self.outcomePackets.font = UIFont.NewSmall;
    self.outcomePackets.doDrawItem = self.drawOutcomePacketsList;
    self.outcomePackets.drawBorder = true;
    self.outcomePackets.target = self;
    self:addChild(self.outcomePackets);
	------- BOTTOM ---------

    y = y + 3;

	_, self.buttonChartPackets = ISDebugUtils.addButton(self, "CHART_PACKETS",columnWidth+xmarg, self.height-40, columnWidth-2*xmarg, 20, getText("IGUI_Chart_Packets"),ISGameStatisticPanel.onClick);
    local y, obj = ISDebugUtils.addButton(self,"close",columnWidth*2+xmarg, self.height-40, columnWidth-2*xmarg, 20,getText("IGUI_CraftUI_Close"),ISGameStatisticPanel.onClickClose);

    self:populateConnectionsList();
	
	self.init = true
	
	StatisticChartUpdatePeriod.doInstance();
	StatisticChartDiskOperations.doInstance();
	StatisticChartMemory.doInstance();
	StatisticChartPackets.doInstance();
end

function ISGameStatisticPanel:onCombo(_combo)
    
end

function ISGameStatisticPanel:onClick(_button)
    if self.buttonToggleMonitor==_button then
		local enable = getServerStatisticEnable();
        if enable then
			setServerStatisticEnable(false);
            self.buttonToggleMonitor.backgroundColor = self.cRed;
        else
			setServerStatisticEnable(true);
            self.buttonToggleMonitor.backgroundColor = self.cGreen;
        end
		return;
	end
	if self.buttonChartUpdatePeriod==_button then
		StatisticChartUpdatePeriod.OnOpenPanel()
		return;
	end
	if self.buttonChartDiskOperations == _button then
		StatisticChartDiskOperations.OnOpenPanel()
		return;
	end
	if self.buttonChartMemory==_button then
		StatisticChartMemory.OnOpenPanel()
		return;
	end
	if self.buttonChartPackets==_button then
		StatisticChartPackets.OnOpenPanel()
		return;
	end
	
end

function ISGameStatisticPanel:onClickClose()
    self:close();
end

function ISGameStatisticPanel:OnFlaresListMouseDown(item)
    --self:populateInfoList(item);
    self.flareID = item:getId();
end

function ISGameStatisticPanel:populateConnectionsList()
	self.data = getServerStatistic();
	if self.data ~= nil then
		local sel = self.connections.options[self.connections.selected];
		self.connections:clear();
		self.connections:addOption("- NONE -");
		local newindex = 1;
		for k, v in pairs(self.data.connections) do
			local name = v.username;
			self.connections:addOption(name);
			if sel and sel==name then
				newindex = k+2;
			end
		end
		self.connections.selected = newindex;
	end
end

function ISGameStatisticPanel:populateUsersList(connect)
	if connect ~= nil then
		self.connection_players:clear();
		for k, v in pairs(connect) do
			self.connection_players:addItem(v.username, v);
		end
	end
end

function ISGameStatisticPanel:populatePacketsList()
	self.data = getServerStatistic();
	if self.data ~= nil then
		self.incomePackets:clear();
		for k, v in pairs(self.data.incomePacketsTable) do
			self.incomePackets:addItem(v.name, v);
		end
		self.outcomePackets:clear();
		for k, v in pairs(self.data.outcomePacketsTable) do
			self.outcomePackets:addItem(v.name, v);
		end
	end
end

function ISGameStatisticPanel:drawUsersList(y, item, alt)
    local a = 0.9;

    self:drawRectBorder(0, (y), self:getWidth()-10, self.itemheight - 1, a, self.borderColor.r, self.borderColor.g, self.borderColor.b);

    self:drawText( item.text, 10, y + 2, 1, 1, 1, a, self.font);
	self:drawText( tostring(item.item.x)..", "..tostring(item.item.y)..", "..tostring(item.item.z), 10, y + 17, 1, 1, 1, a, self.font);
    return y + self.itemheight;
end


function ISGameStatisticPanel:drawOutcomePacketsList(y, item, alt)
    local a = 0.9;

    self:drawRectBorder(0, (y), self:getWidth()-14, self.itemheight - 1, a, self.borderColor.r, self.borderColor.g, self.borderColor.b);
	
	self.data = getServerStatistic();
	if self.data ~= nil then
		self:drawRect( 10, (y+19), 90.0 * math.min(1.0, item.item.count / self.data.countOutcomePackets) , 12 , a, 0.6, 0.2, 0.2);
		self:drawRect( 100, (y+19), 90.0 * math.min(1.0, item.item.bytes / self.data.countOutcomeBytes) , 12 , a, 0.2, 0.6, 0.2);
	end

    self:drawText( item.text, 10, y + 2, 1, 1, 1, a, self.font);
	self:drawText( "count: "..tostring(item.item.count), 10, y + 17, 1, 1, 1, a, self.font);
	self:drawText( "bytes: "..tostring(item.item.bytes), 110, y + 17, 1, 1, 1, a, self.font);
    return y + self.itemheight;
end

function ISGameStatisticPanel:drawIncomePacketsList(y, item, alt)
    local a = 0.9;

    self:drawRectBorder(0, (y), self:getWidth()-14, self.itemheight - 1, a, self.borderColor.r, self.borderColor.g, self.borderColor.b);
	
	self.data = getServerStatistic();
	if self.data ~= nil then
		self:drawRect( 10, (y+19), 90.0 * math.min(1.0, item.item.count / self.data.countIncomePackets) , 12 , a, 0.6, 0.2, 0.2);
		self:drawRect( 100, (y+19), 90.0 * math.min(1.0, item.item.bytes / self.data.countIncomeBytes) , 12 , a, 0.2, 0.6, 0.2);
	end

    self:drawText( item.text, 10, y + 2, 1, 1, 1, a, self.font);
	self:drawText( "count: "..tostring(item.item.count), 10, y + 17, 1, 1, 1, a, self.font);
	self:drawText( "bytes: "..tostring(item.item.bytes), 110, y + 17, 1, 1, 1, a, self.font);
    return y + self.itemheight;
end

function ISGameStatisticPanel:prerender()
    ISPanel.prerender(self);
	
	self.data = getServerStatistic();
	if self.data ~= nil and self.lastReport ~= nil then
		local indicatorWidth = ((self.width)/3) - 40;
		if (self.data.period >= 1) then
			local period = math.min(1.0, (getTimeInMillis() - self.data.lastReportTime) / (self.data.period * 1000.0));
			self:drawRect( 20, self.lastReport.y + 20, indicatorWidth * period, 6, 1.0, 0.2f, 0.6f, 0.2f);
			self:drawRect( 20 + (indicatorWidth * period), self.lastReport.y + 20, indicatorWidth * (1.0f - period), 6, 1.0, 0.6f, 0.2f, 0.2f);
		else 
			self:drawRect( 20, self.lastReport.y + 20, indicatorWidth, 6, 1.0, 0.2f, 0.2f, 0.2f);
		end
		--self.histogramm_y = y;
		--self.histogramm_w = 30;
		--self.histogramm_h = 30;
		self:drawRect( 20, self.histogramm_y, self.histogramm_w, self.histogramm_h, 1.0, 0.2f, 0.2f, 0.2f);
		local sel = self.connections.options[self.connections.selected];
		for k, v in pairs(self.data.connections) do
			if sel and sel==v.username then
				local d = self.histogramm_w/(v.FPSMax - v.FPSMin);
				local d1 = (v.FPSAvg - v.FPSMin) * d / 16;
				local d2 = (v.FPSMax - v.FPSAvg) * d / 16;
				local kh = self.histogramm_h / v.FPSHistogramMax
				local xcl = 20
				local ycl = self.histogramm_y + self.histogramm_h
				
				local mouseSelect = self:getMouseX() - 20
				local mouseSelectId = 0
				local mouseSelectMin = 0
				local mouseSelectMax = 0
				if mouseSelect > d1 * 16 then
					mouseSelectId = math.min(31, math.max(0, math.floor(((mouseSelect - (d1 * 16)) / d2) + 16)))
					mouseSelectMin = math.floor(v.FPSAvg + (mouseSelectId-16)*d2/d)
					mouseSelectMax = math.floor(v.FPSAvg + (mouseSelectId-15)*d2/d)
				else
					mouseSelectId = math.min(31, math.max(0, math.floor(mouseSelect / d1)))
					mouseSelectMin = math.floor(v.FPSMin + mouseSelectId*d1/d)
					mouseSelectMax = math.floor(v.FPSMin + (mouseSelectId+1)*d1/d)
				end
				
				self:drawRect( xcl, ycl - v.FPSHistogram[0] * kh, d1, v.FPSHistogram[0] * kh, 1.0, 1.0f, 0.3f, 0.3f);
				xcl = xcl + d1
				for i=1,15 do 
					if i == mouseSelectId then
						self:drawRect( xcl-1, ycl - v.FPSHistogram[i] * kh, d1+1, v.FPSHistogram[i] * kh, 1.0, 1.0f - (i/32.0f)*0.7f, 0.3f + (i/32.0f)*0.7f, 0.9f);
					else 
						self:drawRect( xcl-1, ycl - v.FPSHistogram[i] * kh, d1+1, v.FPSHistogram[i] * kh, 1.0, 1.0f - (i/32.0f)*0.7f, 0.3f + (i/32.0f)*0.7f, 0.2f);
					end
					xcl = xcl + d1
				end
				for i=16,31 do 
					if i == mouseSelectId then
						self:drawRect( xcl-1, ycl - v.FPSHistogram[i] * kh, d2+1, v.FPSHistogram[i] * kh, 1.0, 1.0f - (i/32.0f)*0.7f, 0.3f + (i/32.0f)*0.7f, 0.9f);
					else
						self:drawRect( xcl-1, ycl - v.FPSHistogram[i] * kh, d2+1, v.FPSHistogram[i] * kh, 1.0, 1.0f - (i/32.0f)*0.7f, 0.3f + (i/32.0f)*0.7f, 0.2f);
					end
					xcl = xcl + d2
				end
				
				self:drawText( "FPS:"..tostring(mouseSelectMin).."-"..tostring(mouseSelectMax).." Reports:"..tostring(v.FPSHistogram[mouseSelectId]), 20 + 1, self.histogramm_y + 1, 1, 1, 1, 1, self.font);
				--self:drawText( "Min:"..tostring(v.FPSMin), 20 + 1, self.histogramm_y + 17, 1, 1, 1, 1, self.font);
				--self:drawText( "Max:"..tostring(v.FPSMax), 20 + self.histogramm_w - 20, self.histogramm_y + 17, 1, 1, 1, 1, self.font);
				break;
			end
		end

	end
end

function ISGameStatisticPanel:updateValues()
	if not self.init then
		return
	end
	local enable = getServerStatisticEnable();
	if enable then
		self.data = getServerStatistic();
		if self.data ~= nil then
			self.periodValue:setName(tostring(self.data.period));
			self.lastReport:setName(tostring(self.data.lastReport));
			self.minUpdatePeriod:setName(tostring(self.data.minUpdatePeriod));
			self.maxUpdatePeriod:setName(tostring(self.data.maxUpdatePeriod));
			self.avgUpdatePeriod:setName(tostring(self.data.avgUpdatePeriod));
			self.loadCellFromDisk:setName(tostring(self.data.loadCellFromDisk));
			self.saveCellToDisk:setName(tostring(self.data.saveCellToDisk));
			self.usedMemory:setName(tostring(self.data.usedMemory));
			self.freeMemory:setName(tostring(self.data.freeMemory));
			self:populateConnectionsList();
			local sel = self.connections.options[self.connections.selected];
			for k, v in pairs(self.data.connections) do
				if sel and sel==v.username then
					self.connection_ip:setName(tostring(v.ip));
					self.connection_access:setName(tostring(v.accessLevel));
					self.connection_username:setName(tostring(v.username));
					self.connection_ping:setName(string.format("%.2f", v.diff * 0.5f));
					self.connection_ping_avg:setName(string.format("%.2f", v.pingAVG));
					self.connection_players_count:setName(string.format("%.2f", v.remotePlayersCount));
					self.connection_players_desync_avg:setName(string.format("%.2f", v.remotePlayersDesyncAVG));
					self.connection_players_desync_max:setName(string.format("%.2f", v.remotePlayersDesyncMax));
					self.connection_players_desync_teleport:setName(string.format("%.2f", v.remotePlayersTeleports));
					self.connection_zombies_count:setName(string.format("%.2f", v.zombiesCount));
					self.connection_zombies_desync_avg:setName(string.format("%.2f", v.zombiesDesyncAVG));
					self.connection_zombies_desync_max:setName(string.format("%.2f", v.zombiesDesyncMax));
					self.connection_zombies_desync_teleport:setName(string.format("%.2f", v.zombiesTeleports));
					self.connection_fps:setName(string.format("%.2f", v.FPS));
					self.connection_fpsAvg:setName(string.format("%.2f", v.FPSAvg));
					self:populateUsersList(v.users)
					break;
				end
			end
			self:populatePacketsList();
		end
	end
	
end

ISGameStatisticPanel.OnServerStatisticReceived = function()
	if ISGameStatisticPanel.instance==nil then
        ISGameStatisticPanel.instance = ISGameStatisticPanel:new (100, 100, 800, 800, "Statistic");
        ISGameStatisticPanel.instance:initialise();
        ISGameStatisticPanel.instance:instantiate();
    end
	ISGameStatisticPanel.instance:updateValues()
end

Events.OnServerStatisticReceived.Add(ISGameStatisticPanel.OnServerStatisticReceived);

function ISGameStatisticPanel:close()
    self:setVisible(false);
    self:removeFromUIManager();
    ISGameStatisticPanel.instance = nil
end

function ISGameStatisticPanel:new(x, y, width, height, title)
    local o = {};
    o = ISPanel:new(x, y, width, height);
    setmetatable(o, self);
    self.__index = self;
    o.variableColor={r=0.9, g=0.55, b=0.1, a=1};
    o.borderColor = {r=0.4, g=0.4, b=0.4, a=1};
    o.backgroundColor = {r=0, g=0, b=0, a=0.8};
    o.buttonBorderColor = {r=0.7, g=0.7, b=0.7, a=0.5};
    o.zOffsetSmallFont = 25;
    o.moveWithMouse = true;
    o.panelTitle = title;
    ISDebugMenu.RegisterClass(self);
    return o;
end


