using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Microsoft.VisualBasic.FileIO; //for CSV parsing

namespace EduNetworkBuilder
{
    //A temporary holding structure when loading in students from CSV for validation.
    //Once loaded and parsed, we then make actual students from them.
    public partial class PersonProfileForm : Form
    {
        enum TopTab { profiletab=0, classworktab=1}
        enum TreeDataTab { classtab=0, homeworktab=1, studentstab=2 , studenttab =3}
        PersonClass CurrentUser = null;
        string FileName = "";
        PersonClass ViewedUser = null;
        SchoolworkClass ViewedSchoolwork = null;

        ToolTip myTooltip = new ToolTip();


        class StudentHolder
        {
            public string Name = "";
            public string Password = "";
            public string FullName = "";
        }



        public PersonProfileForm(string filename = "")
        {
            InitializeComponent();
            FileName = filename;

            //We do LocalSetup at load time.  This saves us some grief.
        }

        public PersonProfileForm(PersonClass User)
        {
            InitializeComponent();
            CurrentUser = User;
            if (CurrentUser != null)
            {
                FileName = Path.Combine(CurrentUser.filepath, CurrentUser.UserName);
            }
            //We do LocalSetup at load time.  This saves us some grief.
        }

        private void PersonProfileForm_Load(object sender, EventArgs e)
        {
            LocalSetup();
            UpdateFormFromUser();
        }

        private void LanguagifyComponents()
        {
            lblFullName.Text = NB.Translate("PPF_FullName");
            lblUsername.Text = NB.Translate("PPF_UserName");
            TabClasswork.Text = NB.Translate("PPF_TabClasswork");
            TabProfile.Text = NB.Translate("PPF_TabProfile");
            btnExit.Text = NB.Translate("NB_exitToolStripMenuItem");
            btnChangePassword.Text = NB.Translate("PPF_ChangePassword");
            btnHWDelete.Text = NB.Translate("_Delete");
            btnImportStudents.Text = NB.Translate("PPF_ImportStudents");
            btnLaunch.Text = NB.Translate("PPF_Launch");
            btnGenerateStudentFiles.Text = NB.Translate("PPF_GenerateFiles");
            btnHWGive.Text = NB.Translate("PPF_HWGive");
            btnHWSave.Text = NB.Translate("_Save");
            cbTeacherAutoDHCP.Text = NB.Translate("PPF_AutoDHCP");
        }

        private void LocalSetup()
        {
            Icon = Properties.Resources.NBIco;
            LanguagifyComponents();
            HideAllTabs();

            myTooltip.AutoPopDelay = 5000;
            myTooltip.InitialDelay = 1000;
            myTooltip.ReshowDelay = 500;
            // Force the ToolTip text to be displayed whether or not the form is active.
            myTooltip.ShowAlways = true;

            myTooltip.SetToolTip(btnImportStudents, NB.Translate("PPF_ImportToolTip"));
            myTooltip.SetToolTip(btnHWGive, NB.Translate("PPF_HWGiveToolTip"));
            myTooltip.SetToolTip(btnHWSave, NB.Translate("PPF_HWSaveToolTip"));
            myTooltip.SetToolTip(btnAllHomeworkToStudents, "Take all currently defined homework and put it into the student accounts.  Do at the beginning of a class and before you generate the student files for the first time.");
            myTooltip.SetToolTip(btnExportHomework, "Export all the homework into a single homework file.  Use this file to set up for another class.");

            tvClasswork.ShowNodeToolTips = true;

            if (CurrentUser == null && FileName == "")
            {
                //Prompt for a username
                NBSettings oldsettings = NB.GetSettings(); //Grab the old settings.

                String Dest = NB.TextPromptBox(NB.Translate("PPF_EnterUserName"));
                if (Dest == "") { Close(); return; }//No name given or canceled.
                if (Dest == null) { Close(); return; }
                if (Dest[0] != '_') Dest = "_Teacher_" + Dest; //Make sure it begins with _
                //Find a directory for it.
                CurrentUser = new PersonClass(Dest, true); //Make an admin person class
                //Choose an initial folder for the file:
                OpenFileDialog OFD = NB.SelectDirectoryDialog(NB.Translate("PPF_UserDirectory"),CurrentUser.filepath);
                if (OFD.FileName == "") return;//we cancel out
                CurrentUser.filepath = Path.GetDirectoryName(OFD.FileName);
                CurrentUser.UserSettings.AutoStartPuzzles = false;
                CurrentUser.UserSettings.ChosenLanguage = oldsettings.ChosenLanguage;
                CurrentUser.UserSettings.LanguageHasBeenChosen = true;
                CurrentUser.ChangePassAtFirstLogin = true;
                CurrentUser.ChangePassword(true); //If they do not set a password now, they will do it next time

            }
            else if (CurrentUser == null)
            {
                //Try to load the file.  Close form  & give error if it fails
                try
                {
                    //Load in from the file
                }
                catch(Exception e)
                {
                    MessageBox.Show(e.ToString());
                    CurrentUser = null;
                    Close();  //we did not succeed.  Exit out
                }
            }

            tvClasswork.AfterSelect += tvClasswork_Click;

            tbHWClass.LostFocus += SaveSchoolworkDataFromForm;
            tbHWDescription.LostFocus += SaveSchoolworkDataFromForm;
            tbHWName.LostFocus += SaveSchoolworkDataFromForm;
            tbHWSubmitted.LostFocus += SaveSchoolworkDataFromForm;
            dtpHWDue.LostFocus += SaveSchoolworkDataFromForm;

            tcTabControl.SelectedIndexChanged += UpdateFormFromSchoolwork;

            //Make sure we update any profile settings they change
            tbFullName.LostFocus += SaveUserInfoFromForm;

            tbStudentFullName.LostFocus += SaveStudentDataFromForm;

            tvClasswork.DoubleClick += btnLaunch_Click;
        }

        private void DtpHWDue_LostFocus(object sender, EventArgs e)
        {

        }

        public PersonClass Edit()
        {
            CloseAllRTFWindows();

            BuilderWindow BW = NB.GetBuilderWin();
            if(BW != null)
            {
                BW.Hide();
                this.ShowDialog();
                BW.Show();
            }
            return CurrentUser;
        }

        private void CloseAllRTFWindows()
        {
            for(int i=Application.OpenForms.Count - 1; i>=0; i--)
            {
                if (Application.OpenForms[i] is RTFWindow)
                    Application.OpenForms[i].Close();
            }
        }

        public PersonClass AddSchoolwork(Network ToAdd)
        {
            if (CurrentUser == null) return CurrentUser;
            CloseAllRTFWindows();

            BuilderWindow BW = NB.GetBuilderWin();
            SchoolworkClass NewWork = new SchoolworkClass(ToAdd, CurrentUser);
            CurrentUser.Projects.Add(NewWork);
            UpdateFormFromUser(); //make sure we list the right homeworks.
            

            ChangeTreeDataTab(TreeDataTab.homeworktab);
            tvClasswork.ExpandAll();
            tvClasswork.Update();

            //Now we want to select the item.
            foreach(TreeNode TN in tvClasswork.GetAllNodes())
            {
                TN.ExpandAll(); //Expand everything until we get to what we need.
                if(TN.Tag is SchoolworkClass)
                {
                    SchoolworkClass Check = (SchoolworkClass)TN.Tag;
                    if(Check == NewWork)
                    {
                        tvClasswork.SelectedNode = TN;
                        break;
                    }
                }
            }

            if (BW != null)
            {
                BW.Hide();
                this.tcTabControl.SelectedIndex = 1; //Jump to the items tab
                this.ShowDialog();
                BW.Show();
            }
            return CurrentUser;
        }

        public PersonClass SubmitSchoolwork(Network ToAdd)
        {
            if (CurrentUser == null) return CurrentUser;
            if (ToAdd.WhatFrom == null) return CurrentUser;  //we have it

            CloseAllRTFWindows();

            BuilderWindow BW = NB.GetBuilderWin();
            SchoolworkClass NewWork = ToAdd.WhatFrom.Clone();
            NewWork.isMaster = false;
            NewWork.IsSumbitted = true;
            NewWork.SaveDate = DateTime.Now;
            NewWork.theProject = ToAdd; //Save the changed version of the homework
            CurrentUser.Projects.Add(NewWork);
            UpdateFormFromUser(); //make sure we list the right homeworks.

            ChangeTreeDataTab(TreeDataTab.homeworktab);
            tvClasswork.ExpandAll();
            tvClasswork.Update();

            //Now we want to select the item.
            foreach (TreeNode TN in tvClasswork.GetAllNodes())
            {
                TN.ExpandAll(); //Expand everything until we get to what we need.
                if (TN.Tag is SchoolworkClass)
                {
                    SchoolworkClass Check = (SchoolworkClass)TN.Tag;
                    if (Check == NewWork)
                    {
                        tvClasswork.SelectedNode = TN;
                        break;
                    }
                }
            }

            if (BW != null)
            {
                BW.Hide();
                this.tcTabControl.SelectedIndex = 1; //Jump to the items tab
                this.ShowDialog();
                BW.Show();
            }
            return CurrentUser;
        }

        private void UpdateFormFromUser()
        {
            if (CurrentUser == null) return;

            tbFullName.Text = CurrentUser.FullName;
            tbUsername.Text = CurrentUser.UserName;
            if (CurrentUser.isAdmin) this.Text = "Admin: " + CurrentUser.UserName;
            else this.Text = "Student: " + CurrentUser.UserName;

            cbTeacherAutoDHCP.Checked = CurrentUser.UserSettings.AutoDHCPAllMachinesAtNetworkLoad;

            tvClasswork.Nodes.Clear();
            if (CurrentUser.isAdmin)
            {
                cbTeacherAutoDHCP.Visible = true;
                UpdateAdminFormFromUser();
            }
            else
            {
                cbTeacherAutoDHCP.Visible = false;
                UpdateStudentFormFromUser();
            }
        }

        private void UpdateAdminFormFromUser()
        {
            btnGenerateStudentFiles.Visible = true;
            btnImportStudents.Visible = true;
            dtpHWDue.Enabled = true;


            TreeNode Node;
            //We have a class tree
            Node = new TreeNode(NB.Translate("PPF_Class"));
            Node.Tag = "Class"; //Do not translate this
            TreeNode Top = Node;
            tvClasswork.Nodes.Add(Node);

            //This is sorted reverse from what happens in PersonClass.WorkTree.
            //In PersonClass.WorkTree, we traverse it backwards.
            CurrentUser.Projects.Sort((p, q) => p.Compare(q));
            foreach (SchoolworkClass SWC in CurrentUser.Projects)
            {
                Node = new TreeNode(SWC.Name);
                Node.Tag = SWC; //Store the schoolwork record in with the node 
                Top.Nodes.Add(Node);
            }

            //we have a students tree.  Use top again so we can populate it
            Top = new TreeNode(NB.Translate("PPF_Students"));
            Top.Tag = "Students"; //Do not translate this
            tvClasswork.Nodes.Add(Top);
            //Create nodes for each student
            foreach (PersonClass PC in CurrentUser.Students)
            {
                Node = new TreeNode(PC.UserName);
                Node.Tag = PC;
                PC.WorkTree(Node, true);                
                Top.Nodes.Add(Node);
            }
        }

        private void UpdateStudentFormFromUser()
        {
            if (CurrentUser == null) return;
            btnGenerateStudentFiles.Visible = false;
            btnImportStudents.Visible = false;
            btnExportStudentPasswords.Visible = false;
            dtpHWDue.Enabled = false;
            TreeNode Top = CurrentUser.WorkTree();
            if (Top != null)
                tvClasswork.Nodes.Add(Top);
        }

        private void SaveUserInfoFromForm()
        {
            CurrentUser.FullName = tbFullName.Text;            
        }

        private void SaveUserInfoFromForm(object sender, EventArgs e)
        {
            SaveUserInfoFromForm();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            //Save during closing
            Close();
        }

        private void btnChangePassword_Click(object sender, EventArgs e)
        {
            CurrentUser.ChangePassword(true); //Try to change it once.
        }

        public Font GetFont()
        {
            if(tvClasswork.Font != null) return tvClasswork.Font;
            if (Font != null) return Font;
            BuilderWindow BW = NB.GetBuilderWin();
            if (BW != null) return BW.GetFont();
            return new Font(FontFamily.GenericSansSerif, 10.0F, FontStyle.Bold);
        }

        private void ChangeTreeDataTab(TreeDataTab WhatTo)
        {
            foreach (TreeDataTab one in Enum.GetValues(typeof(TreeDataTab)))
            {
                if (one == WhatTo) ShowTabPage(one);
                else HideTabPage(one);
            }
            tcTabControl.SelectedIndex = (int)TopTab.classworktab;
            //Now there is just one tab.  Select it
            //tcTreeData.SelectedIndex = (int)WhatTo;
            tcTreeData.SelectedIndex = 0;
        }

        private void HideAllTabs()
        {
            foreach (TreeDataTab one in Enum.GetValues(typeof(TreeDataTab)))
            HideTabPage(one);
        }

        private void HideTabPage(TreeDataTab What)
        {
            TabPage Tab = null;
            switch(What)
            {
                case TreeDataTab.classtab:
                    Tab = tabClass;
                    break;
                case TreeDataTab.homeworktab:
                    Tab = TabHomework;
                    break;
                case TreeDataTab.studentstab:
                    Tab = TabStudents;
                    break;
                case TreeDataTab.studenttab:
                    Tab = TabStudent;
                    break;
            }
            if(tcTreeData.TabPages.Contains(Tab))
                tcTreeData.TabPages.Remove(Tab);
        }

        private void ShowTabPage(TreeDataTab What)
        {
            TabPage Tab = null;
            switch (What)
            {
                case TreeDataTab.classtab:
                    Tab = tabClass;
                    break;
                case TreeDataTab.homeworktab:
                    Tab = TabHomework;
                    break;
                case TreeDataTab.studentstab:
                    Tab = TabStudents;
                    break;
                case TreeDataTab.studenttab:
                    Tab = TabStudent;
                    break;
            }
            if (!tcTreeData.TabPages.Contains(Tab))
                tcTreeData.TabPages.Add(Tab);
        }

        private void tvClasswork_Click(object sender, EventArgs e)
        {
            if (tvClasswork.SelectedNode == null) return;

            TreeNode Node = tvClasswork.SelectedNode;
            if (Node == null) return; //Break out to avoid exploding

            if (Node.Tag is SchoolworkClass)
            {
                SchoolworkClass SWC = (SchoolworkClass)Node.Tag;
                //It is a homework.  Select the homework tab and fill it
                ChangeTreeDataTab(TreeDataTab.homeworktab);
                UpdateFormFromSchoolwork(SWC);
            }
            if(Node.Tag is PersonClass)
            {
                PersonClass PC = (PersonClass)Node.Tag;
                //It is an individual student
                ChangeTreeDataTab(TreeDataTab.studenttab);
                UpdateFormFromStudent(PC);
            }
            if(Node.Tag is string)
            {
                string Selected = (string)Node.Tag;
                if (Selected == "Class") //Do not translate this
                    ChangeTreeDataTab(TreeDataTab.classtab);
                if (Selected == "Students") //Do not translate this
                    ChangeTreeDataTab(TreeDataTab.studentstab);
            }
        }

        void SaveSchoolworkDataFromForm(object sender, EventArgs e)
        {
            SaveSchoolworkDataFromForm();
        }
        private void SaveSchoolworkDataFromForm()
        {
            if (ViewedSchoolwork == null) return;
            ViewedSchoolwork.Class = tbHWClass.Text;
            ViewedSchoolwork.Description = tbHWDescription.Text;
            ViewedSchoolwork.Name = tbHWName.Text;
            ViewedSchoolwork.DueDate = dtpHWDue.Value;
        }
        private void UpdateFormFromSchoolwork(object sender, EventArgs e)
        {
            UpdateFormFromSchoolwork();
        }

        private void UpdateFormFromSchoolwork(SchoolworkClass What)
        {
            ViewedSchoolwork = What;
            UpdateFormFromSchoolwork();
        }
        private void UpdateFormFromSchoolwork()
        {
            bool OnStudentTree = false;
            TreeNode Node = tvClasswork.SelectedNode;
            if (Node != null && Node.FullPath.StartsWith("Student"))
                OnStudentTree = true;
            if (ViewedSchoolwork == null)
            {
                tbHWClass.Text = "";
                tbHWDescription.Text = "";
                tbHWName.Text ="";
                tbHWSubmitted.Visible = false;
                dtpHWDue.Visible = false;
                lblHWDue.Visible = false;
                btnHWDelete.Visible = false;
                btnLaunch.Visible = false;
                btnHWGive.Visible = false;
                btnHWSave.Visible = false;
                return;
            }

            tbHWClass.Text = ViewedSchoolwork.Class;
            tbHWDescription.Text = ViewedSchoolwork.Description;
            tbHWName.Text = ViewedSchoolwork.Name;

            myTooltip.SetToolTip(tbHWClass, tbHWClass.Text);
            myTooltip.SetToolTip(tbHWDescription, tbHWDescription.Text);
            myTooltip.SetToolTip(tbHWName, tbHWName.Text);

            dtpHWDue.Visible = true;
            lblHWDue.Visible = true;
            if (ViewedSchoolwork.IsSumbitted)
            {
                tbHWSubmitted.Visible = true;
                lblHWDue.Visible = true;
                lblHWSubmitted.Visible = true;
                tbHWSubmitted.Text = ViewedSchoolwork.SaveDate.ToString();
            }
            else
            {
                tbHWSubmitted.Visible = false;                
                lblHWSubmitted.Visible = false;
            }
            if (ViewedSchoolwork.DueDate < dtpHWDue.MinDate) ViewedSchoolwork.DueDate = dtpHWDue.MinDate;
            dtpHWDue.Value = ViewedSchoolwork.DueDate;
            if (CurrentUser != null && CurrentUser.isAdmin)
            {
                btnHWDelete.Visible = true; //Only the teacher can delete the homework
                btnHWGive.Visible = true;
                btnHWSave.Visible = true;

            }
            else
            {
                btnHWDelete.Visible = false; //Only the teacher can delete the homework
                btnHWGive.Visible = false;
                btnHWSave.Visible = false; 
            }
            if(OnStudentTree)
            {   //We cannot give or delete submitted stuff
                btnHWDelete.Visible = false; 
                btnHWGive.Visible = false;
            }
            btnLaunch.Visible = true;
        }

        void UpdateFormFromStudent(PersonClass Student)
        {
            ViewedUser = Student;
            UpdateFormFromStudent();
        }
        void UpdateFormFromStudent()
        {
            if (ViewedUser == null)
            {
                btnStudentChangePassword.Visible = false;
                btnStudentUpdateFile.Visible = false;
                return;
            }
            tbStudentFullName.Text = ViewedUser.FullName;
            tbStudentUsername.Text = ViewedUser.UserName;
            btnStudentChangePassword.Visible = true;
            btnStudentUpdateFile.Visible = true;
        }

        void SaveStudentDataFromForm(object sender, EventArgs e)
        {
            SaveStudentDataFromForm();
        }

        void SaveStudentDataFromForm()
        {
            if (ViewedUser == null) return;
            ViewedUser.FullName = tbStudentFullName.Text;
        }

        private void btnHWDelete_Click(object sender, EventArgs e)
        {
            if (ViewedSchoolwork == null) return;
            if (CurrentUser != null && CurrentUser.isAdmin)//Only the teacher can delete the homework
            {
                DialogResult Sure = MessageBox.Show(NB.Translate("PPF_ConfirmHWDelete"), "", MessageBoxButtons.YesNoCancel);
                if (Sure == DialogResult.Yes)
                {
                    CurrentUser.Projects.Remove(ViewedSchoolwork);
                    ViewedSchoolwork = null;
                    UpdateFormFromUser();
                    UpdateFormFromSchoolwork();
                }
            }
        }

        private void btnLaunch_Click(object sender, EventArgs e)
        {
            BuilderWindow BW = NB.GetBuilderWin();
            if (tvClasswork.SelectedNode != null && tvClasswork.SelectedNode.Tag is string) return;
            if (tvClasswork.SelectedNode != null && tvClasswork.SelectedNode.Tag is PersonClass) return;
            if (BW != null && ViewedSchoolwork != null && ViewedSchoolwork.theProject != null)
            {
                ViewedSchoolwork.theProject.WhatFrom = ViewedSchoolwork; //Store the homework info.  Used for pushing it back
                BW.LoadNetworkFromNetwork(ViewedSchoolwork.theProject);
                Close(); //Exit out of the profile
            }
        }

        private void btnImportStudents_Click(object sender, EventArgs e)
        {
            //Get a csv file
            //try to read it in
            //Import them all
            Random myRandom = NB.GetRandom();
            bool AutoCreatePWs = true;
            bool ForcePWChange = true;
            OpenFileDialog mydialog = new OpenFileDialog();
            mydialog.AddExtension = true;
            string filter = "Comma Separated List (*.csv)|*.csv";
            mydialog.Filter = filter;
            mydialog.Multiselect = false;
            mydialog.CheckFileExists = true;
            mydialog.ShowHelp = true;
            if (CurrentUser.UserSettings.LastPath != null && CurrentUser.UserSettings.LastPath != "")
                mydialog.FileName = CurrentUser.UserSettings.LastPath;
            DialogResult result = mydialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.Cancel) return;

            //Prompt for import settings.
            Dictionary<string, bool> Checks = new Dictionary<string, bool>();
            Checks.Add(NB.Translate("PPF_AutoGenPW"), AutoCreatePWs);
            Checks.Add(NB.Translate("PPF_ForcePWChange"), ForcePWChange);

            Dictionary<string, bool> Response = NB.CheckPromptBox(Checks, NB.Translate("PPF_ImportSettings"),Properties.Resources.NBIco);
            if (Response == null) return; //We canceled out
            if (Response.ContainsKey(NB.Translate("PPF_AutoGenPW"))) AutoCreatePWs = Response[NB.Translate("PPF_AutoGenPW")];
            if (Response.ContainsKey(NB.Translate("PPF_ForcePWChange"))) ForcePWChange = Response[NB.Translate("PPF_ForcePWChange")];

            List<StudentHolder> tList = new List<StudentHolder>();
            List<string> InvalidUsers = new List<string>();
            List<string> InvalidFullName = new List<string>();
            List<string> InvalidPasswords = new List<string>();

            //Now we have a csv file.  Try to parse it
            bool HadError = false;
            try
            {
                using (TextFieldParser parser = new TextFieldParser(mydialog.FileName))
                {
                    StudentHolder TStudent = new StudentHolder();

                    parser.TextFieldType = FieldType.Delimited;
                    parser.SetDelimiters(",");
                    while (!parser.EndOfData)
                    {
                        //Process row
                        int index = 0;
                        string[] fields = parser.ReadFields();
                        foreach (string field in fields)
                        {
                            //TODO: Process field
                            if (index == 0)
                            {
                                TStudent = new StudentHolder();
                                TStudent.Name = field;
                                if (!NB.ValidateUsername(field))
                                {
                                    HadError = true;
                                    InvalidUsers.Add(TStudent.Name);
                                }

                            }
                            if (index == 1)
                            {
                                TStudent.FullName = field;
                                if (!NB.ValidateFullName(field))
                                {
                                    HadError = true;
                                    InvalidFullName.Add(TStudent.Name);
                                }
                            }
                            if (index == 2)
                            {
                                TStudent.Password = field;
                                if (!NB.ValidatePassword(field))
                                {
                                    HadError = true;
                                    InvalidPasswords.Add(TStudent.Name);
                                }
                            }
                            index++;  //Track which field we are in.
                        }
                        if (AutoCreatePWs && TStudent.Password == "")
                            TStudent.Password = TrippleDESDocumentEncryption.GenUserPW(myRandom);
                        tList.Add(TStudent);
                    }
                }
                if (HadError)
                {
                    ShowInvalid("Username", InvalidUsers);
                    ShowInvalid("Full Name", InvalidFullName);
                    ShowInvalid("Password", InvalidPasswords);
                    return; //Break out without adding them
                }
            }
            catch (Exception except)
            {
                MessageBox.Show(except.ToString());
                return; //Break out without trying to add something
            }
            //If we get here, we are ready to add students.
            int dup_students = 0;
            int new_students = 0;

            //Loop through them all and add ones that do not already exist.
            foreach(StudentHolder SH in tList)
            {
                //find if they already exist
                if(StudentFromUsername(SH.Name) == null)
                {
                    new_students++;
                    PersonClass tPC = new PersonClass(SH.Name,false); //Make a new account that is not an admin
                    tPC.FullName = SH.FullName;
                    tPC.ChangePassword(SH.Password);
                    tPC.ChangePassAtFirstLogin = ForcePWChange;
                    tPC.UserSettings.AutoStartPuzzles = false; //They will start with homework
                    tPC.UserSettings.ChosenLanguage = CurrentUser.UserSettings.ChosenLanguage;
                    tPC.UserSettings.LanguageHasBeenChosen = true; //No need to start by prompting.
                    CurrentUser.Students.Add(tPC);
                }
                else
                {
                    dup_students++;
                }
            }
            UpdateFormFromUser();
            MessageBox.Show(string.Format(NB.Translate("PPF_ImportSummary"),"\n\t" + new_students,"\n\t" + dup_students));
        }

        PersonClass StudentFromUsername(string Username)
        {
            foreach(PersonClass pc in CurrentUser.Students)
            {
                if (pc.UserName == Username)
                    return pc;
            }
            return null;
        }

        private void ShowInvalid(string What, List<string> BadUsers)
        {
            if (BadUsers.Count < 1) return;
            string message = NB.Translate("PPF_NoImportInvalid") + ": " + What;
            foreach (string one in BadUsers)
                message += "\n" + one;
            MessageBox.Show(message);
        }

        /// <summary>
        /// Generate The student files for all the students.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGenerateStudentFiles_Click(object sender, EventArgs e)
        {
            //Verify (choose) student file directory
            //Loop through all the students
            //Calculate the filename for the student file
            //See if the file exists.  If not, gen a new file
            //Keep track of total # students, # new files, # skipped because they existed
            int NumStudent = 0;
            int NumMade = 0;
            int NumSkipped = 0;

            OpenFileDialog OFD = NB.SelectDirectoryDialog(NB.Translate("PPF_SelectStudentDir"),CurrentUser.StudentFilePath);
            if (OFD.FileName == "") return;//we cancel out
            CurrentUser.StudentFilePath = Path.GetDirectoryName(OFD.FileName);

            foreach(PersonClass PC in CurrentUser.Students)
            {
                NumStudent++;
                string FileName = Path.Combine(CurrentUser.StudentFilePath, PC.FileName);

                if (File.Exists(FileName)) NumSkipped++;
                else
                {
                    PC.filepath = CurrentUser.StudentFilePath; //For now.  This changes, but it helps for now.
                    NumMade++;
                    PC.Save(FileName);
                }
            }

            //Now, print the stats
            MessageBox.Show(string.Format(NB.Translate("PPF_StudentWriteStats"),"\n\t" + NumStudent, "\n\t" + NumMade, "\n\t" + NumSkipped));
        }

        private void btnHWGive_Click(object sender, EventArgs e)
        {
            int NumStudents = 0;
            int NumGiven = 0;
            int NumAlready = 0;
            //Create a new homework class for each student, containing this homework
            if (ViewedSchoolwork == null) return;//We do not have homework selected
            foreach(PersonClass PC in CurrentUser.Students)
            {
                NumStudents++;
                SchoolworkClass SWC = ViewedSchoolwork.Clone();
                SWC.isMaster = true; //It is homework
                SWC.IsSumbitted = false; //It has not yet been submitted
                bool didit = PC.AddHomework(SWC);
                if (didit) NumGiven++;
                else NumAlready++;
            }
            MessageBox.Show(string.Format(NB.Translate("PPF_GiveHWStats"),"\n\t" + NumStudents, "\n\t" + NumGiven, "\n\t" + NumAlready ));
        }

        private void btnHWSave_Click(object sender, EventArgs e)
        {
            if (ViewedSchoolwork == null) return;
            //Prompt for the filename where to save it
            //Save the Schoolwork file
            SaveFileDialog SFD = new SaveFileDialog();
            SFD.InitialDirectory = CurrentUser.filepath; //Save wherever the teacher file is stored
            SFD.OverwritePrompt = true;
            SFD.FileName = ViewedSchoolwork.FileName;
            SFD.AddExtension = true;
            SFD.Filter = "EduNetworkBuilder Homework File (*.eduh)|*.eduh";
            DialogResult Answer = SFD.ShowDialog();
            if (Answer == DialogResult.Cancel) return;

            //If we are here, we are ready to save it
            ViewedSchoolwork.Save(SFD.FileName);
        }

        private void btnAllHomeworkToStudents_Click(object sender, EventArgs e)
        {
            NB.NotImplimentedMessage();
        }

        private void btnExportHomework_Click(object sender, EventArgs e)
        {
            //Generate a list of homework, so we can make a check-box for it...
            Dictionary<string, bool> HWList = new Dictionary<string, bool>();
            foreach(SchoolworkClass sc in CurrentUser.Projects)
            {
                string one = sc.DueDate.ToShortDateString() + " - " + sc.Name;
                HWList.Add(one, false);
            }

            //Now, make a prompt box for it.

            Dictionary<string, bool> Response = NB.CheckPromptBox(HWList, "Homework to include", Properties.Resources.NBIco);
            if (Response == null) return; //if we canceled out
            //Add each homework to a list
            List<SchoolworkClass> HWClassList = new List<SchoolworkClass>();
            int index = 0;
            foreach(string one in HWList.Keys)
            {
                if (index < CurrentUser.Projects.Count)
                {
                    if (Response[one])
                        HWClassList.Add(CurrentUser.Projects[index]);
                }
                index++;
            }
            if (HWClassList.Count == 0) return; //none selected.

            OpenFileDialog mydialog = new OpenFileDialog();
            //If we have a user loaded, we can open homework files
            string filter = "EduNetworkBuilder Homework File (*.enbh)|*.enbh;";
            mydialog.Filter = filter;
            mydialog.Multiselect = false;
            mydialog.ShowHelp = true;
            mydialog.CheckFileExists = false;
            mydialog.CheckPathExists = true;
            mydialog.AddExtension = true;
            DialogResult result = mydialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.Cancel) return;            //Choose a file
            
            //save that list in that file
            SchoolworkClass.Save(HWClassList, mydialog.FileName);
        }

        private void btnReadAllStudentHomework_Click(object sender, EventArgs e)
        {
            //Ask for a directory
            //Loop through all students
            //Read in the file for that student
            //   make temp person record
            //   loop through all networks
            //   Find any that are submitted, which are not in the admin file
            //   copy them into the admin file
            //Track
            //  Num submitted homeworks.
            //  Num students
            //  Num of students with no submissions

            bool HadASubmission = false;
            int NumStudent = 0;
            int NumSubmitted = 0;
            int NumStudentsNoSubmissions = 0;
            int NumErrorFiles = 0;
            int NumStudentsNoFiles = 0;

            //Ask for a directory
            OpenFileDialog OFD = NB.SelectDirectoryDialog(NB.Translate("PPF_SelectStudentDir"), CurrentUser.StudentFilePath);
            if (OFD.FileName == "") return;//we cancel out
            CurrentUser.StudentFilePath = Path.GetDirectoryName(OFD.FileName);

            //Loop through all students
            foreach (PersonClass storedStudent in CurrentUser.Students)
            {
                NumStudent++;
                HadASubmission = false;
                string FullName = Path.Combine(CurrentUser.StudentFilePath, storedStudent.FileName);
                //Read in the file for that student
                try
                {
                    if (File.Exists(FullName))
                    {
                        //   make temp person record
                        PersonClass tempStudent = PersonClass.TryLoad(FullName, storedStudent.AltPassword);
                        if(tempStudent == null)
                        {
                            NumErrorFiles++;
                            continue; //Do not try to load in the data
                        }

                        int tCountSubmitted = CurrentUser.TeacherImportStudentHomework(tempStudent);
                        NumSubmitted += tCountSubmitted;
                        if (tCountSubmitted >0)
                            NumStudentsNoSubmissions++;
                    }
                    else
                    {
                        NumStudentsNoFiles++;
                    }
                }
                catch
                {
                    NumErrorFiles++;
                }
            }
            UpdateFormFromUser();
            MessageBox.Show(string.Format(NB.Translate("PPF_BringInHWSummary"),
                "\n\t" + NumStudent, "\n\t" + NumSubmitted,
                "\n\t" + NumStudentsNoSubmissions, "\n\t" + NumStudentsNoFiles,
                "\n\t" + NumErrorFiles));
        }

        private void WriteStudentCSVFile(string path)
        {
            try
            {
                using (var w = new StreamWriter(path))
                {
                    foreach (PersonClass pc in CurrentUser.Students)
                    {
                        string UName = NB.CSVSafeString(pc.UserName);
                        string FName = NB.CSVSafeString(pc.FullName);
                        string Pass = NB.CSVSafeString(pc.Password);
                        var line = string.Format("{0},{1},{2}", UName, FName, Pass);
                        w.WriteLine(line);
                        w.Flush();
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

        private void btnExportStudentPasswords_Click(object sender, EventArgs e)
        {
            SaveFileDialog mydialog = new SaveFileDialog();
            mydialog.AddExtension = true;
            string filter = "Comma Separated List (*.csv)|*.csv";
            mydialog.Filter = filter;
            mydialog.CheckFileExists = false;
            mydialog.ShowHelp = true;
            if (CurrentUser.UserSettings.LastPath != null && CurrentUser.UserSettings.LastPath != "")
                mydialog.FileName = CurrentUser.UserSettings.LastPath;
            DialogResult result = mydialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.Cancel) return;

            WriteStudentCSVFile(mydialog.FileName);
        }

        private void cbTeacherAutoDHCP_CheckedChanged(object sender, EventArgs e)
        {
            CurrentUser.UserSettings.AutoDHCPAllMachinesAtNetworkLoad = cbTeacherAutoDHCP.Checked;
        }

        private void bthAutoTestStudentHomework_Click(object sender, EventArgs e)
        {
            if (CurrentUser == null) return;
            //Test all student's homework that is ungraded.
            foreach(PersonClass student in CurrentUser.Students)
            {
                foreach(SchoolworkClass homework in student.Projects)
                {
                    if(homework.IsSumbitted && !homework.IsGraded && homework.HomeworkStatus == HomeworkSolvedStatus.NeverChecked)
                    {
                        //We only need to test homework that is submitted and not graded.
                        homework.CheckThatHomeworkIsSolved(); //Process it
                    }
                }
            }
            UpdateFormFromUser(); //rebuild the tree.
        }
    }
}