// train the currently selected skill
    private void TrainSelectedSkill()
    {
        // get access to the player data
        PlayerData playerData = DataController.m_instance.m_playerData;

        // get access to the bank player data
        PD_Bank bank = playerData.m_bank;

        if (bank.m_currentBalance < 300)
        {
            UpdateTrainingText(5);

            SoundController.m_instance.PlaySound(SoundController.Sound.Error);
        }
        else
        {
            // get access to the current personnel file we are looking at
            PD_Personnel.PD_PersonnelFile personnelFile = playerData.m_personnel.m_personnelList[m_currentFileIndex];

            // get access to the race data for this personnel file
            GD_CrewRace race = DataController.m_instance.m_gameData.m_crewRaceList[m_currentRaceIndex];

            // calculate the current skill and maximum skill points for the selected skill
            int currentSkill = personnelFile.GetSkill(m_currentSkillIndex);
            int maximumSkill = race.GetMaximumSkill(m_currentSkillIndex);

            // check if the maximum skill is zero
            if (maximumSkill == 0)
            {
                UpdateTrainingText(4);

                SoundController.m_instance.PlaySound(SoundController.Sound.Error);
            }
            else if (currentSkill < maximumSkill)               // check if we are still below the maximum skill points
            {
                // increase the skill by the learn amount
                personnelFile.SetSkill(m_currentSkillIndex, Math.Min(maximumSkill, currentSkill + race.m_learningRate));

                // take off 300 credits from the bank balance
                bank.m_currentBalance -= 300;

                // update the bank balance text
                UpdateBankBalanceText();

                // update the skill values text
                UpdateSkillValues();

                // play a ui sound
                SoundController.m_instance.PlaySound(SoundController.Sound.Update);
            }
            else             // the selected skill is already maxxed out
            {
                UpdateTrainingText(3);

                SoundController.m_instance.PlaySound(SoundController.Sound.Error);
            }
        }
    }
    // this is called if we clicked on the train button
    public void TrainClicked()
    {
        InputController.m_instance.Debounce();

        // check if the current race is an android
        if (m_currentRaceIndex == 4)
        {
            UpdateTrainingText(1);

            SoundController.m_instance.PlaySound(SoundController.Sound.Error);
        }
        else
        {
            // get access to the player data
            PlayerData playerData = DataController.m_instance.m_playerData;

            // get access to the current personnel file we are looking at
            PD_Personnel.PD_PersonnelFile personnelFile = playerData.m_personnel.m_personnelList[m_currentFileIndex];

            // get access to the race data for this personnel file
            GD_CrewRace race = DataController.m_instance.m_gameData.m_crewRaceList[m_currentRaceIndex];

            // enable the train button only if the current personnel is not maxxed out
            int maxTotalPoints     = 0;
            int currentTotalPoints = 0;

            for (int skillIndex = 0; skillIndex < c_numSkills; skillIndex++)
            {
                maxTotalPoints     = race.GetMaximumSkill(skillIndex);
                currentTotalPoints = personnelFile.GetSkill(skillIndex);
            }

            // check if we are maxxed out
            if (currentTotalPoints < maxTotalPoints)
            {
                // switch to the train select skill state
                SwitchToTrainCrewmemberState();
            }
            else
            {
                UpdateTrainingText(2);

                SoundController.m_instance.PlaySound(SoundController.Sound.Error);
            }
        }

        // play a ui sound
        SoundController.m_instance.PlaySound(SoundController.Sound.Activate);
    }
    void UpdateDisplay()
    {
        // show the up arrow only if we are not at the first position index
        m_upArrowImage.gameObject.SetActive(m_currentRole != PD_CrewAssignment.Role.First);

        // show the down arrow only if we are not at the last position index
        m_downArrowImage.gameObject.SetActive(m_currentRole != (PD_CrewAssignment.Role.Count - 1));

        // put the position selection box in the right place
        float offset = (int)m_currentRole * m_positionValuesText.renderedHeight / (int)PD_CrewAssignment.Role.Count;

        RectTransform rectTransform = m_selectionXform.GetComponent <RectTransform>();

        rectTransform.offsetMin = m_baseSelectionOffsetMin + new Vector3(0.0f, -offset, 0.0f);
        rectTransform.offsetMax = m_baseSelectionOffsetMax + new Vector3(0.0f, -offset, 0.0f);

        // get access to the personnel player data
        PD_Personnel personnel = DataController.m_instance.m_playerData.m_personnel;

        // get the personnel file
        PD_Personnel.PD_PersonnelFile personnelFile = personnel.m_personnelList[m_currentPersonnelId];

        // update the crewmember name
        if (personnelFile.m_vitality > 0)
        {
            m_nameText.text = personnelFile.m_name + " - " + personnelFile.m_vitality + "% vitality";
        }
        else
        {
            m_nameText.text = personnelFile.m_name + " - DEAD";
        }

        // update the skill values
        m_skillValuesText.text = "";

        for (int skillIndex = 0; skillIndex < c_numSkills; skillIndex++)
        {
            m_skillValuesText.text += personnelFile.GetSkill(skillIndex).ToString();

            if (skillIndex < (c_numSkills - 1))
            {
                m_skillValuesText.text += Environment.NewLine;
            }
        }
    }
    // update the skill values
    private void UpdateSkillValues()
    {
        // get access to the player data
        PlayerData playerData = DataController.m_instance.m_playerData;

        // get access to the current personnel file we are looking at
        PD_Personnel.PD_PersonnelFile personnelFile = playerData.m_personnel.m_personnelList[m_currentFileIndex];

        // update the skill values with the ones in this personnel file
        m_skillValuesText.text = "";

        for (int skillIndex = 0; skillIndex < c_numSkills; skillIndex++)
        {
            m_skillValuesText.text += personnelFile.GetSkill(skillIndex).ToString();

            if (skillIndex < (c_numSkills - 1))
            {
                m_skillValuesText.text += Environment.NewLine;
            }
        }
    }