--
-- Created by IntelliJ IDEA.
-- User: RJ
-- Date: 21/09/16
-- Time: 10:19
-- To change this template use File | Settings | File Templates.
--

--***********************************************************
--**                    ROBERT JOHNSON                     **
--***********************************************************

require "ISUI/ISPanel"

ISPlayerStatsUI = ISPanel:derive("ISPlayerStatsUI");


--************************************************************************--
--** ISPanel:initialise
--**
--************************************************************************--

function ISPlayerStatsUI:initialise()
    ISPanel.initialise(self);
    self:create();
end


function ISPlayerStatsUI:setVisible(visible)
    --    self.parent:setVisible(visible);
    self.javaObject:setVisible(visible);
    for _,v in ipairs(self.windows) do
       v:removeFromUIManager();
    end
end

function ISPlayerStatsUI:subPanelPreRender()
    self:setStencilRect(0,5,self:getWidth(),self:getHeight()-5);
    ISPanel.prerender(self);
end

function ISPlayerStatsUI:subPanelRender()
    ISPanel.render(self);
    self:clearStencilRect();
end

function ISPlayerStatsUI:render()
    ISPlayerStatsUI.instance = self -- to support reloading in lua debugger

    local z = 20 + self:getYScroll();

    self:updateButtons();

    self:drawText(getText("IGUI_PlayerStats_PlayerStats"), self.width/2 - (getTextManager():MeasureStringX(UIFont.Cred1, getText("IGUI_PlayerStats_PlayerStats")) / 2), 10, 1,1,1,1, UIFont.Cred1);
    self:setStencilRect(0,60,self:getWidth(),self:getHeight()-60);
    z = z + 25;
    self.mainPanel:drawText(getText("IGUI_PlayerStats_Username"), 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getUsername(), 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);
    z = z + self.buttonHeight
    self.mainPanel:drawText(getText("IGUI_PlayerStats_DisplayName"), 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getDisplayName(), 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);
    self.changeUsernameBtn:setY(z);
    z = z + self.buttonHeight;
    self.mainPanel:drawText(getText("UI_characreation_forename") .. ":", 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getDescriptor():getForename(), 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);
    self.changeForename:setY(z);
    z = z + self.buttonHeight;
    self.mainPanel:drawText(getText("UI_characreation_surname") .. ":", 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getDescriptor():getSurname(), 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);
    self.changeSurname:setY(z);
    z = z + self.buttonHeight;
    self.mainPanel:drawText(getText("IGUI_PlayerStats_Profession"), 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.profession, 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);
    self.changeProfession:setY(z);
    z = z + self.buttonHeight;
    self.mainPanel:drawText(getText("IGUI_char_Survived_For") .. ":", 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getTimeSurvived(), 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);
    z = z + self.buttonHeight;
    self.mainPanel:drawText(getText("IGUI_char_Zombies_Killed") .. ":", 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getZombieKills() .. "", 10 + self.xoffset, z, 1,1,1,1, UIFont.Small);

    local nextColumnX = 400;
    local nextColumnZ = 45 + self:getYScroll();
    self.mainPanel:drawText(getText("IGUI_PlayerStats_AccessLevel"), nextColumnX, nextColumnZ, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.mainPanel:drawText(self.char:getAccessLevel(), nextColumnX + self.xoffset, nextColumnZ, 1,1,1,1, UIFont.Small);
    self.changeAccessLvlBtn:setX(nextColumnX + self.buttonOffset);
    self.changeAccessLvlBtn:setY(nextColumnZ);
    if self.char:getUsername() == "admin" then
        self.changeAccessLvlBtn.enable = false;
    end
    nextColumnZ = nextColumnZ + self.buttonHeight;

    self.mainPanel:drawText(getText("IGUI_PlayerStats_ChatMuted"), nextColumnX, nextColumnZ, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    local chatMuted = getText("Sandbox_ThumpNoChasing_option1");
    if not self.char:isAllChatMuted() then chatMuted = getText("Sandbox_ThumpNoChasing_option2"); end
    self.mainPanel:drawText(chatMuted, nextColumnX + self.xoffset, nextColumnZ, 1,1,1,1, UIFont.Small);
    if self.char:isAllChatMuted() then
        self.muteAllBtn:setTitle(getText("UI_Scoreboard_Unmute"));
    else
        self.muteAllBtn:setTitle(getText("UI_Scoreboard_Mute"));
    end
    self.muteAllBtn:setX(nextColumnX + self.buttonOffset);
    self.muteAllBtn:setY(nextColumnZ);
    nextColumnZ = nextColumnZ + self.buttonHeight;

    self.mainPanel:drawText(getText("IGUI_PlayerStats_UserLogs") .. " (" .. #self.userlogs .. ")", nextColumnX, nextColumnZ, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.userlogBtn:setX(nextColumnX + self.buttonOffset);
    self.userlogBtn:setY(nextColumnZ);
    nextColumnZ = nextColumnZ + self.buttonHeight;

    self.mainPanel:drawText(getText("IGUI_PlayerStats_WarningPts") .. self.warningPoint, nextColumnX, nextColumnZ, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    self.warningPointsBtn:setX(nextColumnX + self.buttonOffset);
    self.warningPointsBtn:setY(nextColumnZ);
    nextColumnZ = nextColumnZ + self.buttonHeight;
    
    self.manageInvBtn:setX(nextColumnX);
    self.manageInvBtn:setY(nextColumnZ);
    nextColumnZ = nextColumnZ + self.buttonHeight;

    z = z + self.zOffsetSmallFont;
    self.mainPanel:drawText(getText("IGUI_char_Traits") .. ":", 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    z = z + self.zOffsetSmallFont;
    local count = 0;
    if #self.traits > 0 then
        local x = 25;
        local y = z + 10;
        for i,v in ipairs(self.traits) do
            v:setY(y);
            v:setX(x);
            v:setVisible(true);
            self.mainPanel:drawText(v.label, 25 + x, y, 1,1,1,1, UIFont.Small)
            self.traitsRemoveButtons[v.label]:setY(y)
            self.traitsRemoveButtons[v.label]:setX(x + 140)
            count = count + 1;
            if count < 3 then
                x = x + 210;
            else
                count = 0;
                x = 25;
                y = y + v:getTexture():getHeight() + 2
            end
        end
        if count == 0 then y = y - 20; end
        if count < 3 then y = y + 20; end
        x = 25;
        y = y + 10;
        self.mainPanel:drawRectBorder(10, z, self.width - 30, y-z + 30, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b);
        z = y;
        self.addTraitBtn:setY(z);
        self.addTraitBtn:setX(x);
    else
        self.mainPanel:drawRectBorder(10, z, self.width - 30, 40, self.borderColor.a, self.borderColor.r, self.borderColor.g, self.borderColor.b);
        z = z + 10;
        self.addTraitBtn:setY(z);
        self.addTraitBtn:setX(25);
    end
--    print(self:getYScroll());
    z = z + self.buttonHeight;
    z = z + self.zOffsetSmallFont;

    self.mainPanel:drawText(getText("IGUI_PlayerStats_Exp"), 10, z, self.variableColor.r,self.variableColor.g,self.variableColor.b,self.variableColor.a, UIFont.Small);
    z = z + self.buttonHeight;
    local previousXp = 0;
    if self.char:getXp():getLevel() > 0 then
        previousXp = self.char:getXpForLevel(self.char:getXp():getLevel() - 1)
    end
    local xp = self.char:getXp():getTotalXp() - previousXp
    self.mainPanel:drawText(getText("IGUI_PlayerStats_GlobalExp") .. xp .. "/" .. self.char:getXpForLevel(self.char:getXp():getLevel()) - previousXp, 10, z, 1,1,1,1, UIFont.Small);
    self.addGlobalXP:setY(z);
    self.addGlobalXP:setX(200);
    z = z + self.buttonHeight;
    self.mainPanel:drawText(getText("IGUI_PlayerStats_AvailableSkillPt") .. self.char:getNumberOfPerksToPick(), 10, z, 1,1,1,1, UIFont.Small);
    self.addLevelUpPoint:setY(z);
    self.addLevelUpPoint:setX(200);
    z = z + self.zOffsetSmallFont;
    z = z + self.zOffsetSmallFont;

--    self.mainPanel:drawText("Perk", 10, z, 1,1,1,1, UIFont.Small);
--    self.mainPanel:drawTextRight("Level", 188, z, 1,1,1,1, UIFont.Small);
--    self.mainPanel:drawTextRight("XP", 225, z, 1,1,1,1, UIFont.Small);
--    self.mainPanel:drawTextRight("Boost", 310, z, 1,1,1,1, UIFont.Small);
--    self.mainPanel:drawTextRight("Multiplier", 412, z, 1,1,1,1, UIFont.Small);
    self.xpListBox:setY(z);
    self.addXpBtn:setY(self.xpListBox:getY() + self.xpListBox.height + 3);
    self.addXpBtn:setX(self.xpListBox:getX());
    self.addLvlBtn:setY(self.addXpBtn:getY());
    self.addLvlBtn:setX(self.addXpBtn:getX() + self.addXpBtn:getWidth() + 5);

    local yoff = 13;
    local columnLeft = self.xpListBox.columnLeft
    local columnWidth = self.xpListBox.columnWidth
    self:drawRectBorder(self.xpListBox.x, self.xpListBox.y - self.xpListBox.itemheight + yoff, self.xpListBox:getWidth(), self.xpListBox.itemheight + 1, 1, self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.xpListBox.x, 1 + self.xpListBox.y - self.xpListBox.itemheight + yoff, self.xpListBox.width, self.xpListBox.itemheight,self.listHeaderColor.a,self.listHeaderColor.r, self.listHeaderColor.g, self.listHeaderColor.b);
    self:drawRect(self.xpListBox.x + columnLeft[2], 1 + self.xpListBox.y - self.xpListBox.itemheight + yoff, 1, self.xpListBox.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.xpListBox.x + columnLeft[3], 1 + self.xpListBox.y - self.xpListBox.itemheight + yoff, 1, self.xpListBox.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.xpListBox.x + columnLeft[4], 1 + self.xpListBox.y - self.xpListBox.itemheight + yoff, 1, self.xpListBox.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.xpListBox.x + columnLeft[5], 1 + self.xpListBox.y - self.xpListBox.itemheight + yoff, 1, self.xpListBox.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.xpListBox.x + columnLeft[5] + columnWidth[5], 1 + self.xpListBox.y - self.xpListBox.itemheight + yoff, 1, self.xpListBox.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);

    self:drawText(self.xpListBox.columnLabel[1], self.xpListBox.x + 5, self.xpListBox.y - 20 + yoff, 1,1,1,1,UIFont.Small);
    self:drawText(self.xpListBox.columnLabel[2], self.xpListBox.x + columnLeft[2] + 10, self.xpListBox.y - 20 + yoff, 1,1,1,1,UIFont.Small);
    self:drawText(self.xpListBox.columnLabel[3], self.xpListBox.x + columnLeft[3] + 10, self.xpListBox.y - 20 + yoff, 1,1,1,1,UIFont.Small);
    self:drawText(self.xpListBox.columnLabel[4], self.xpListBox.x + columnLeft[4] + 10, self.xpListBox.y - 20 + yoff, 1,1,1,1,UIFont.Small);
    self:drawText(self.xpListBox.columnLabel[5], self.xpListBox.x + columnLeft[5] + 10, self.xpListBox.y - 20 + yoff, 1,1,1,1,UIFont.Small);


    z = z + self.zOffsetSmallFont - 5;
    --    self:setScrollHeight(z + 250);
--    self:setScrollHeight(2000);

    self:clearStencilRect();
end

function ISPlayerStatsUI:canModifyThis()
   return (self.admin:getAccessLevel() == "Admin") or (self.admin:getAccessLevel() == "Moderator" and (self.char:getAccessLevel() == "None" or self.char:getAccessLevel() == "GM" or self.char:getAccessLevel() == "Overseer" or self.char:getAccessLevel() == "Observer"))
end

function ISPlayerStatsUI:updateButtons()
    self.addTraitBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.changeProfession.enable = canModifyPlayerStats() and self:canModifyThis();
    self.changeForename.enable = canModifyPlayerStats() and self:canModifyThis();
    self.changeSurname.enable = canModifyPlayerStats() and self:canModifyThis();
    self.addGlobalXP.enable = canModifyPlayerStats() and self:canModifyThis();
    self.addLevelUpPoint.enable = canModifyPlayerStats() and self:canModifyThis();
    self.muteAllBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.addXpBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.addLvlBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.userlogBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.manageInvBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.warningPointsBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    self.changeAccessLvlBtn.enable = (self.admin:getAccessLevel() == "Admin" or self.admin:getAccessLevel() == "Moderator") and self:canModifyThis();
    self.changeUsernameBtn.enable = canModifyPlayerStats() and self:canModifyThis();
    for _,image in ipairs(self.traits) do
        self.traitsRemoveButtons[image.label].enable = canModifyPlayerStats() and self:canModifyThis();
    end
end

function ISPlayerStatsUI:onMouseWheel(del)
    if not self.xpListBox:isMouseOver() then
        self:setYScroll(self:getYScroll() - (del*50));
        return true;
    else
        return false;
    end
end


function ISPlayerStatsUI:create()

    self.mainPanel = ISPanel:new(0, 13, self:getWidth(), self:getHeight() - 13)
    self.mainPanel:initialise()
    self.mainPanel:instantiate()
    self.mainPanel:setAnchorRight(true)
    self.mainPanel:setAnchorLeft(true)
    self.mainPanel:setAnchorTop(true)
    self.mainPanel:setAnchorBottom(true)
    self.mainPanel:noBackground()
    self.mainPanel.borderColor = {r=0, g=0, b=0, a=0};
    self.mainPanel.moveWithMouse = true;

    self.mainPanel.render = ISPlayerStatsUI.subPanelRender
    self.mainPanel.prerender = ISPlayerStatsUI.subPanelPreRender

    self.mainPanel:addScrollBars();
    self:addChild(self.mainPanel)

    self.closeBtn = ISButton:new(self.width - 100, 5, 80, 25, getText("UI_btn_close"), self, self.onOptionMouseDown);
    self.closeBtn.internal = "CLOSE";
    self.closeBtn:initialise();
    self.closeBtn:instantiate();
    self.closeBtn:setAnchorLeft(true);
    self.closeBtn:setAnchorTop(false);
    self.closeBtn:setAnchorBottom(true);
    self.closeBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.closeBtn);

    self.addTraitBtn = ISButton:new(16, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_AddTrait"), self, self.onOptionMouseDown);
    self.addTraitBtn.internal = "ADDTRAIT";
    self.addTraitBtn:initialise();
    self.addTraitBtn:instantiate();
    self.addTraitBtn:setAnchorLeft(true);
    self.addTraitBtn:setAnchorTop(false);
    self.addTraitBtn:setAnchorBottom(true);
    self.addTraitBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.addTraitBtn);

    self.changeProfession = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_Change"), self, self.onOptionMouseDown);
    self.changeProfession.internal = "CHANGEPROFESSION";
    self.changeProfession:initialise();
    self.changeProfession:instantiate();
    self.changeProfession:setAnchorLeft(true);
    self.changeProfession:setAnchorTop(false);
    self.changeProfession:setAnchorBottom(true);
    self.changeProfession.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.changeProfession);

    self.changeUsernameBtn = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_Change"), self, self.onOptionMouseDown);
    self.changeUsernameBtn.internal = "CHANGENAME";
    self.changeUsernameBtn.changedName = "Displayname";
    self.changeUsernameBtn:initialise();
    self.changeUsernameBtn:instantiate();
    self.changeUsernameBtn:setAnchorLeft(true);
    self.changeUsernameBtn:setAnchorTop(false);
    self.changeUsernameBtn:setAnchorBottom(true);
    self.changeUsernameBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.changeUsernameBtn);

    self.changeForename = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_Change"), self, self.onOptionMouseDown);
    self.changeForename.internal = "CHANGENAME";
    self.changeForename.changedName = "Forename";
    self.changeForename:initialise();
    self.changeForename:instantiate();
    self.changeForename:setAnchorLeft(true);
    self.changeForename:setAnchorTop(false);
    self.changeForename:setAnchorBottom(true);
    self.changeForename.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.changeForename);

    self.changeSurname = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_Change"), self, self.onOptionMouseDown);
    self.changeSurname.internal = "CHANGENAME";
    self.changeSurname.changedName = "Surname";
    self.changeSurname:initialise();
    self.changeSurname:instantiate();
    self.changeSurname:setAnchorLeft(true);
    self.changeSurname:setAnchorTop(false);
    self.changeSurname:setAnchorBottom(true);
    self.changeSurname.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.changeSurname);

    self.addGlobalXP = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_AddGlobalXP"), self, self.onOptionMouseDown);
    self.addGlobalXP.internal = "ADDGLOBALXP";
    self.addGlobalXP:initialise();
    self.addGlobalXP:instantiate();
    self.addGlobalXP:setAnchorLeft(true);
    self.addGlobalXP:setAnchorTop(false);
    self.addGlobalXP:setAnchorBottom(true);
    self.addGlobalXP.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.addGlobalXP);

    self.addLevelUpPoint = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_AddPoint"), self, self.onOptionMouseDown);
    self.addLevelUpPoint.internal = "ADDLEVELUPPOINT";
    self.addLevelUpPoint:initialise();
    self.addLevelUpPoint:instantiate();
    self.addLevelUpPoint:setAnchorLeft(true);
    self.addLevelUpPoint:setAnchorTop(false);
    self.addLevelUpPoint:setAnchorBottom(true);
    self.addLevelUpPoint.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.addLevelUpPoint);

    self.muteAllBtn = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("UI_Scoreboard_Mute"), self, self.onOptionMouseDown);
    self.muteAllBtn.internal = "MUTEALL";
    self.muteAllBtn:initialise();
    self.muteAllBtn:instantiate();
    self.muteAllBtn:setAnchorLeft(true);
    self.muteAllBtn:setAnchorTop(false);
    self.muteAllBtn:setAnchorBottom(true);
    self.muteAllBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.muteAllBtn);

    self.changeAccessLvlBtn = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_Change"), self, self.onOptionMouseDown);
    self.changeAccessLvlBtn.internal = "CHANGEACCESSLEVEL";
    self.changeAccessLvlBtn:initialise();
    self.changeAccessLvlBtn:instantiate();
    self.changeAccessLvlBtn:setAnchorLeft(true);
    self.changeAccessLvlBtn:setAnchorTop(false);
    self.changeAccessLvlBtn:setAnchorBottom(true);
    self.changeAccessLvlBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.changeAccessLvlBtn);

    self.userlogBtn = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_See"), self, self.onOptionMouseDown);
    self.userlogBtn.internal = "SEEUSERLOG";
    self.userlogBtn:initialise();
    self.userlogBtn:instantiate();
    self.userlogBtn:setAnchorLeft(true);
    self.userlogBtn:setAnchorTop(false);
    self.userlogBtn:setAnchorBottom(true);
--    self.userlogBtn.enable = false;
    self.userlogBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.userlogBtn);

    self.warningPointsBtn = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_Add"), self, self.onOptionMouseDown);
    self.warningPointsBtn.internal = "ADDWARNINGPOINT";
    self.warningPointsBtn:initialise();
    self.warningPointsBtn:instantiate();
    self.warningPointsBtn:setAnchorLeft(true);
    self.warningPointsBtn:setAnchorTop(false);
    self.warningPointsBtn:setAnchorBottom(true);
    self.warningPointsBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.warningPointsBtn);
    
    self.manageInvBtn = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_ManageInventory", self.char:getUsername()), self, self.onOptionMouseDown);
    self.manageInvBtn.internal = "MANAGEINV";
    self.manageInvBtn:initialise();
    self.manageInvBtn:instantiate();
    self.manageInvBtn:setAnchorLeft(true);
    self.manageInvBtn:setAnchorTop(false);
    self.manageInvBtn:setAnchorBottom(true);
    self.manageInvBtn.borderColor = self.buttonBorderColor;
    self.mainPanel:addChild(self.manageInvBtn);
    if self.char == self.admin then
        self.manageInvBtn:setVisible(false);
    end

    self.xpListBox = ISScrollingListBox:new(10, 30, self.width - 30, 200);
    self.xpListBox:initialise();
    self.xpListBox:instantiate();
    self.xpListBox.itemheight = 22;
    self.xpListBox.selected = 0;
    self.xpListBox.joypadParent = self;
    self.xpListBox.font = UIFont.NewSmall;
    self.xpListBox.doDrawItem = self.drawPerk;
    self.xpListBox.drawBorder = true;
    self.xpListBox.mainUI = self;
    self.mainPanel:addChild(self.xpListBox);

    self.xpListBox.columnLabel = {
        getText("IGUI_PlayerStats_Perk"),
        getText("IGUI_PlayerStats_Level"),
        getText("IGUI_PlayerStats_XP"),
        getText("IGUI_PlayerStats_Boost"),
        getText("IGUI_PlayerStats_Multiplier")
    }
    self.xpListBox.columnWidth = { 140, 50, 70, 80, 120 }
    self:updateColumns()

    self.addXpBtn = ISButton:new(16, self.xpListBox.y + 200, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_AddXP"), self, self.onOptionMouseDown);
    self.addXpBtn.internal = "ADDXP";
    self.addXpBtn:initialise();
    self.mainPanel:addChild(self.addXpBtn);
    self.addGlobalXP.borderColor = self.buttonBorderColor;
    
    self.addLvlBtn = ISButton:new(self.addXpBtn.x + self.buttonWidth + 5, self.addXpBtn.y, self.buttonWidth, self.buttonHeight, getText("IGUI_PlayerStats_LevelUp"), self, self.onOptionMouseDown);
    self.addLvlBtn.internal = "LEVELPERK";
    self.addLvlBtn:initialise();
    self.mainPanel:addChild(self.addLvlBtn);

    self:addScrollBars();

    self:loadTraits();
    self:loadProfession();
    self:loadPerks();
    self:loadUserlog();
end

function ISPlayerStatsUI:onOptionMouseDown(button, x, y)
    if button.internal == "CLOSE" then
        self:setVisible(false);
        self:removeFromUIManager();
    end

    if button.internal == "ADDTRAIT" then
        local modal = ISPlayerStatsChooseTraitUI:new(self.x + 200, self.y + 200, 350, 250, nil, ISPlayerStatsUI.onAddTrait, self.char)
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "CHANGENAME" then
        local defaultTxt = "";
        if button.changedName == "Forename" then
            defaultTxt = ISPlayerStatsUI.instance.char:getDescriptor():getForename();
        elseif button.changedName == "Surname" then
            defaultTxt = ISPlayerStatsUI.instance.char:getDescriptor():getSurname();
        elseif button.changedName == "Displayname" then
            defaultTxt = ISPlayerStatsUI.instance.char:getDisplayName();
        end

        local modal = ISTextBox:new(self.x + 200, 200, 280, 180, "Change " .. button.changedName, defaultTxt, nil, ISPlayerStatsUI.onChangeName, self.char:getPlayerNum(), self.char, button.changedName);
        modal.changedName = button.changedName;
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "CHANGEPROFESSION" then
        local modal = ISPlayerStatsChooseProfessionUI:new(self.x + 200, self.y + 200, 350, 250, nil, ISPlayerStatsUI.onChangeProfession, self.char)
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "CHANGEACCESSLEVEL" then
        local modal = ISPlayerStatsChooseAccessLevelUI:new(self.x + 200, self.y + 200, 350, 250, nil, ISPlayerStatsUI.onChangeAccessLevel, self.char, self.admin)
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "ADDGLOBALXP" then
        local modal = ISTextBox:new(self.x + 200, 200, 280, 180, getText("IGUI_PlayerStats_AddGlobalXP") .. " ", "1", nil, ISPlayerStatsUI.onAddGlobalXP, self.char:getPlayerNum(), self.char);
        modal:initialise();
        modal:addToUIManager();
        modal:setOnlyNumbers(true);
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "ADDXP" then
        local modal = ISPlayerStatsAddXPUI:new(self.x + 200, self.y + 200, 300, 250, nil, ISPlayerStatsUI.onAddXP)
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end
    
    if button.internal == "LEVELPERK" then
        self.char:LevelPerk(self.selectedPerk.perk, false);
        self.char:getXp():setXPToLevel(self.selectedPerk.perk, self.char:getPerkLevel(self.selectedPerk.perk));
        self:loadPerks();
    end

    if button.internal == "ADDLEVELUPPOINT" then
        self.char:setNumberOfPerksToPick(self.char:getNumberOfPerksToPick() + 1);
        addLevelUpPoint(self.char);
    end

    if button.internal == "SEEUSERLOG" then
        requestUserlog(self.char:getUsername());
        local modal = ISPlayerStatsUserlogUI:new(self.x + 200, self.y + 200, 600, 550, nil, ISPlayerStatsUI.onUserlogOption, self.char, self.userlogs);
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "ADDWARNINGPOINT" then
        local modal = ISPlayerStatsWarningPointUI:new(self.x + 200, self.y + 200, 300, 250, nil, ISPlayerStatsUI.onAddWarningPoint, self.char);
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end

    if button.internal == "MUTEALL" then
        self.char:setAllChatMuted(not self.char:isAllChatMuted());
        sendPlayerStatsChange(self.char);
    end
    
    if button.internal == "MANAGEINV" then
        local modal = ISPlayerStatsManageInvUI:new(self.x + 100, self.y + 100, 600, 650, self.char);
        modal:initialise();
        modal:addToUIManager();
        table.insert(ISPlayerStatsUI.instance.windows, modal);
    end
end

function ISPlayerStatsUI:onAddWarningPoint(button, reason, amount)
    addWarningPoint(ISPlayerStatsUI.instance.char:getUsername(), reason, tonumber(amount));
    ISPlayerStatsUI.instance.warningPoint = ISPlayerStatsUI.instance.warningPoint + 1;
    requestUserlog(ISPlayerStatsUI.instance.char:getUsername());
end

function ISPlayerStatsUI:onAddTrait(button, trait)
    if button.internal == "OK" then
        ISPlayerStatsUI.instance.char:getTraits():add(trait:getType());
        SyncXp(ISPlayerStatsUI.instance.char);
        ISPlayerStatsUI.instance:loadTraits();
    end
end

function ISPlayerStatsUI:onChangeProfession(button, prof)
    if button.internal == "OK" then
        ISPlayerStatsUI.instance.char:getDescriptor():setProfession(prof:getType());
        sendPlayerStatsChange(ISPlayerStatsUI.instance.char);
    end
end

function ISPlayerStatsUI:onChangeAccessLevel(button, accessLevel)
    if button.internal == "OK" then
        ISPlayerStatsUI.instance.char:setAccessLevel(accessLevel);
        sendPlayerStatsChange(ISPlayerStatsUI.instance.char);
    end
end

function ISPlayerStatsUI:onAddGlobalXP(button, player)
    if button.internal == "OK" then
        if button.parent.entry:getText() and button.parent.entry:getText() ~= "" then
            ISPlayerStatsUI.instance.char:getXp():addGlobalXP(tonumber(button.parent.entry:getText()));
            sendAddXp(ISPlayerStatsUI.instance.char, nil, tonumber(button.parent.entry:getText()), false, true);
--            ISPlayerStatsUI.instance.loadPerks();
        end
    end
end

function ISPlayerStatsUI:onChangeName(button, player, changedName)
    if button.internal == "OK" then
        local doneIt = true;
        if (changedName ~= "Tag" and button.parent.entry:getText() and button.parent.entry:getText() ~= "") or changedName == "Tag" then
            if changedName == "Forename" then
                if ISPlayerStatsUI.instance.char:getDescriptor():getForename() == button.parent.entry:getText() then
                    doneIt = false;
                else
                    ISPlayerStatsUI.instance.char:getDescriptor():setForename(button.parent.entry:getText());
                    sendPlayerStatsChange(ISPlayerStatsUI.instance.char);
                end
            elseif changedName == "Surname" then
                if ISPlayerStatsUI.instance.char:getDescriptor():getSurname() == button.parent.entry:getText() then
                    doneIt = false;
                else
                    ISPlayerStatsUI.instance.char:getDescriptor():setSurname(button.parent.entry:getText());
                    sendPlayerStatsChange(ISPlayerStatsUI.instance.char);
                end
            elseif changedName == "Displayname" then
                if ISPlayerStatsUI.instance.char:getDisplayName() == button.parent.entry:getText() then
                    doneIt = false;
                else
                    ISPlayerStatsUI.instance.char:setDisplayName(button.parent.entry:getText());
                    sendPlayerStatsChange(ISPlayerStatsUI.instance.char);
                end
            end
            if not doneIt then
                local modal = ISModalDialog:new(0,0, 250, 150,  getText("IGUI_PlayerStats_SameName", changedName), false, nil, nil, nil);
                modal:initialise()
                modal:addToUIManager()
                table.insert(ISPlayerStatsUI.instance.windows, modal);
            end
        end
    end
end

function ISPlayerStatsUI:onRemoveTrait(button, x, y)
    self.char:getTraits():remove(button.internal);
    SyncXp(self.char);
    self:loadTraits();
end

ISPlayerStatsUI.loadTraits = function(self)
    for _,image in ipairs(self.traits) do
        self.mainPanel:removeChild(image)
        self.mainPanel:removeChild(self.traitsRemoveButtons[image.label]);
    end
    self.traits = {};

    for i=0, self.char:getTraits():size() - 1 do
        local trait = TraitFactory.getTrait(self.char:getTraits():get(i));
        if trait and trait:getTexture() then
            local textImage = ISImage:new(0, 0, trait:getTexture():getWidth(), trait:getTexture():getHeight(), trait:getTexture());
            textImage:initialise();
            textImage.label = trait:getLabel();
            textImage:setMouseOverText(trait:getDescription());
            textImage:setVisible(false);
            self.mainPanel:addChild(textImage);
            table.insert(self.traits, textImage);
            local newButton = ISButton:new(self.buttonOffset, self.height - 30, self.buttonWidth, self.buttonHeight, getText("ContextMenu_Remove"), self, self.onRemoveTrait);
            newButton.internal = trait:getType();
            newButton:initialise();
            newButton:instantiate();
            newButton:setAnchorLeft(true);
            newButton:setAnchorTop(false);
            newButton:setAnchorBottom(true);
            newButton.borderColor = self.buttonBorderColor;
            self.mainPanel:addChild(newButton);
            self.traitsRemoveButtons[trait:getLabel()] = newButton;
        end
    end
    self.Strength = self.char:getPerkLevel(Perks.Strength)
    self.Fitness = self.char:getPerkLevel(Perks.Fitness)
end

ISPlayerStatsUI.loadProfession = function(self)
    self.profession = nil;
    if self.char:getDescriptor() and self.char:getDescriptor():getProfession() then
        local prof = ProfessionFactory.getProfession(self.char:getDescriptor():getProfession());
        if prof then
            self.profession = prof:getName();
        end
    end
end



ISPlayerStatsUI.loadPerks = function(self)
    local previousSelection = self.xpListBox.selected;
    self.xpListBox:clear();
    local maxNameWidth = 0
    for i=0, Perks.getMaxIndex() - 1 do
        local perk = PerkFactory.getPerk(Perks.fromIndex(i));
        if perk and perk:getParent() ~= Perks.None then
            local newPerk = {};
            newPerk.perk = Perks.fromIndex(i);
            newPerk.name = perk:getName() .. " (" .. PerkFactory.getPerkName(perk:getParent()) .. ")";
            newPerk.level = self.char:getPerkLevel(Perks.fromIndex(i));
            newPerk.xpToLevel = perk:getXpForLevel(newPerk.level + 1);
            newPerk.xp = self.char:getXp():getXP(newPerk.perk) - ISSkillProgressBar.getPreviousXpLvl(perk, newPerk.level);
            local xpBoost = self.char:getXp():getPerkBoost(newPerk.perk);
            if xpBoost == 1 then
                newPerk.boost = "75%";
            elseif xpBoost == 2 then
                newPerk.boost = "100%";
            elseif xpBoost == 3 then
                newPerk.boost = "125%";
            else
                newPerk.boost = "50%";
            end
            newPerk.multiplier = self.char:getXp():getMultiplier(newPerk.perk);
            self.xpListBox:addItem(newPerk.name, newPerk);
            maxNameWidth = math.max(maxNameWidth, getTextManager():MeasureStringX(self.xpListBox.font, newPerk.name))
        end
    end
    self.xpListBox:sort()
    self.xpListBox.selected = previousSelection;
    self.xpListBox.columnWidth[1] = maxNameWidth + 15
    self:updateColumns()
end

function ISPlayerStatsUI:drawPerk(y, item, alt)
    local a = 0.9;

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

    if self.selected == item.index then
        self:drawRect(0, (y), self:getWidth(), self.itemheight - 1, 0.3, 0.7, 0.35, 0.15);
        self.mainUI.selectedPerk = item.item;
    end

    self:drawRect(self.columnLeft[2], y-1, 1, self.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.columnLeft[3], y-1, 1, self.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.columnLeft[4], y-1, 1, self.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.columnLeft[5], y-1, 1, self.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);
    self:drawRect(self.columnLeft[5] + self.columnWidth[5], y-1, 1, self.itemheight,1,self.borderColor.r, self.borderColor.g, self.borderColor.b);

    local yoff = 2;
    self:drawText(item.item.name, 5, y + yoff, 1, 1, 1, a, self.font);
    self:drawText(item.item.level .. "", self.columnLeft[2] + 10, y + yoff, 1, 1, 1, a, self.font);
    if item.item.xpToLevel == -1 then
        self:drawText("MAX", self.columnLeft[3] + 10, y + yoff, 1, 1, 1, a, self.font);
    else
        self:drawText(item.item.xp .. "/" .. item.item.xpToLevel, self.columnLeft[3] + 10, y + yoff, 1, 1, 1, a, self.font);
    end
    self:drawText(item.item.boost, self.columnLeft[4] + 10, y + yoff, 1, 1, 1, a, self.font);
    self:drawText(item.item.multiplier .. "", self.columnLeft[5] + 10, y + yoff, 1, 1, 1, a, self.font);

    return y + self.itemheight;
end

function ISPlayerStatsUI:onAddXP(button, perk, amount, addGlobalXP)
    if amount and amount ~= "" then
        amount = tonumber(amount);
        ISPlayerStatsUI.instance.char:getXp():AddXP(perk:getType(), amount, false, addGlobalXP, false, true);
        sendAddXp(ISPlayerStatsUI.instance.char, perk:getType(), amount, addGlobalXP, false);
        ISPlayerStatsUI.instance:loadPerks();
    end
end

function ISPlayerStatsUI:updateColumns()
    local left = 0
    self.xpListBox.columnLeft = {}
    for i=1,#self.xpListBox.columnWidth do
        self.xpListBox.columnLeft[i] = left
        local labelWidth = getTextManager():MeasureStringX(UIFont.Small, self.xpListBox.columnLabel[i])
        self.xpListBox.columnWidth[i] = math.max(self.xpListBox.columnWidth[i], labelWidth + 20)
        left = left + self.xpListBox.columnWidth[i]
    end
end

function ISPlayerStatsUI:new(x, y, width, height, playerChecked, admin)
    local o = {};
    o = ISPanel:new(x, y, width, height);
    setmetatable(o, self);
    self.__index = self;
    o.char = playerChecked;
    o.variableColor={r=0.9, g=0.55, b=0.1, a=1};
    o.admin = admin;
    o.borderColor = {r=0.4, g=0.4, b=0.4, a=1};
    o.listHeaderColor = {r=0.4, g=0.4, b=0.4, a=0.3};
    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.traits = {}
    o.traitsRemoveButtons = {};
    o.perks = {};
    o.perksAddXPButtons = {};
    o.userlogs = {};

    o.xoffset = 110;
    o.zOffsetSmallFont = 25;
    o.buttonOffset = 220;
    o.buttonWidth = 60;
    o.buttonHeight = 15;
    o.warningPoint = 0;
    ISPlayerStatsUI.instance = o;
    o.windows = {};
    o.moveWithMouse = true;
    return o;
end

ISPlayerStatsUI.loadUserlog = function(self)
    requestUserlog(self.char:getUsername());
end

ISPlayerStatsUI.receiveUserLog = function(username, logs)
    if not ISPlayerStatsUI.instance or username ~= ISPlayerStatsUI.instance.char:getUsername() then return; end
    ISPlayerStatsUI.instance.userlogs = {};
--    ISPlayerStatsUI.instance.userlogBtn.enable = logs:size() > 0;
    ISPlayerStatsUI.instance.warningPoint = 0;
    for i=0,logs:size()-1 do
        local log = logs:get(i);
        if log:getType() == UserlogType.WarningPoint:toString() then
            ISPlayerStatsUI.instance.warningPoint = ISPlayerStatsUI.instance.warningPoint + log:getAmount();
        end
        table.insert(ISPlayerStatsUI.instance.userlogs, {type = log:getType(), text = log:getText(), issuedBy = log:getIssuedBy(), amount = log:getAmount()});
    end
end

Events.OnReceiveUserlog.Add(ISPlayerStatsUI.receiveUserLog);
