private void ButtonDelete_Click(object sender, EventArgs e)
        {
            DialogResult res = DialogResult.Yes;

            Person selectedPerson = listBoxPeople.SelectedItem as Person;

            if (selectedPerson == null)
            {
                return;
            }

            int numShifts = selectedPerson.GetShifts().Where(p => p.Clickable).Count();

            if (numShifts > 0)
            {
                res = MessageBox.Show($"{selectedPerson.Text} has {numShifts} shifts. Are you sure you want to delete them?", "Delete Person", MessageBoxButtons.YesNo);
            }

            if (res == DialogResult.Yes)
            {
                //Update pending changes
                Common.PendingPersonChanges.Add(new Tuple <Person, Edit>(selectedPerson, Edit.Delete));
                UpdatePersonListBox();
                UpdateAllComboBoxesWithPeople();
                RefreshGanttChart?.Invoke();
            }
        }
        private void ButtonClearScheduleWeek_Click(object sender, EventArgs e)
        {
            if (!AreUsernamesValid(Common.AllData()))
            {
                return;
            }

            DateTime     sourceWeek = dateTimePickerSource5.Value;
            List <Shift> shiftsToRemove;

            if (comboBoxPerson6.SelectedIndex == 0)
            {
                List <Person> allPeople = Common.AllData();
                foreach (Person person in allPeople)
                {
                    foreach (Shift shift in person.GetShiftsForWeek(sourceWeek))
                    {
                        Common.PendingShiftChanges.Add(new Tuple <Shift, Person, Edit>(shift, person, Edit.Delete));
                    }
                }
            }
            else
            {
                Person sourcePerson = comboBoxPerson6.SelectedItem as Person;
                shiftsToRemove = sourcePerson.GetShiftsForWeek(sourceWeek);

                shiftsToRemove.ForEach(p => Common.PendingShiftChanges.Add(new Tuple <Shift, Person, Edit>(p, sourcePerson, Edit.Delete)));
            }

            RefreshGanttChart?.Invoke();
        }
        private void ButtonCopyPersonDate_Click(object sender, EventArgs e)
        {
            if (!AreUsernamesValid(Common.AllData()))
            {
                return;
            }

            Person   sourcePerson = comboBoxPerson3.SelectedItem as Person;
            DateTime sourceDay    = dateTimePickerSource2.Value;
            Person   targetPerson = comboBoxPerson4.SelectedItem as Person;
            DateTime targetDay    = dateTimePickerTarget2.Value;
            int      dayDiff      = (targetDay - sourceDay).Days;

            if (sourcePerson == targetPerson && sourceDay.Date == targetDay.Date)
            {
                return;
            }

            List <Shift> shiftsToCopy = sourcePerson.GetShiftsForDay(sourceDay);

            shiftsToCopy.ForEach(p => //Adjust shiftsToCopy to targetDay
            {
                p.StartTime.AddDays(dayDiff);
                p.EndTime.AddDays(dayDiff);
            });
            List <Shift> filteredShifts = FilterListByConflicts(targetPerson.GetShifts(), shiftsToCopy);

            //Update main form's gantt chart
            filteredShifts.ForEach(p => Common.PendingShiftChanges.Add(new Tuple <Shift, Person, Edit>(p, targetPerson, Edit.Add)));
            RefreshGanttChart?.Invoke();
        }
        private void ButtonSendPeopleToChart_Click(object sender, EventArgs e)
        {
            foreach (Person person in navGanttChart.GanttChart.Rows.Cast <Person>())
            {
                Common.PendingPersonChanges.Add(new Tuple <Person, Edit>(person.Clone(false), Edit.Add));
            }

            UpdatePersonListBox();
            UpdateAllComboBoxesWithPeople();

            RefreshGanttChart?.Invoke();
        }
        private void SyncHolidaysToCharts()
        {
            Common.Holidays.Clear();
            foreach (Holiday item in checkedListBoxHolidays.Items.Cast <Holiday>())
            {
                item.Active = checkedListBoxHolidays.GetItemChecked(checkedListBoxHolidays.Items.IndexOf(item));
                Common.Holidays.Add(item);
            }

            //Update main gantt chart with new holidays
            RefreshGanttChart?.Invoke();

            //Update preview gantt chart with new holidays
            NavGanttChart_UpdateHolidays();
        }
        private void ButtonAdd_Click(object sender, EventArgs e)
        {
            if (IsPersonValid(true))
            {
                Person person = new Person(textBoxName.Text);
                person.Username         = textBoxUsername.Text;
                person.EmployeeLocation = (EmployeeLocation)Enum.Parse(typeof(EmployeeLocation), comboBoxLocation.SelectedValue.ToString());
                person.Permissions      = (Permissions)Enum.Parse(typeof(Permissions), comboBoxPermissions.SelectedValue.ToString());

                //Update pending changes
                Common.PendingPersonChanges.Add(new Tuple <Person, Edit>(person, Edit.Add));
                UpdatePersonListBox();
                UpdateAllComboBoxesWithPeople();

                RefreshGanttChart?.Invoke();
            }
        }
        private void ButtonSave_Click(object sender, EventArgs e)
        {
            if (IsPersonValid(false))
            {
                int    index          = listBoxPeople.SelectedIndex;
                Person selectedPerson = listBoxPeople.SelectedItem as Person;
                selectedPerson.Text             = textBoxName.Text;
                selectedPerson.Username         = textBoxUsername.Text;
                selectedPerson.EmployeeLocation = (EmployeeLocation)Enum.Parse(typeof(EmployeeLocation), comboBoxLocation.SelectedValue.ToString());
                selectedPerson.Permissions      = (Permissions)Enum.Parse(typeof(Permissions), comboBoxPermissions.SelectedValue.ToString());

                //Update pending changes
                Common.PendingPersonChanges.Add(new Tuple <Person, Edit>(selectedPerson, Edit.Overwrite));
                UpdatePersonListBox();
                UpdateAllComboBoxesWithPeople();
                RefreshGanttChart?.Invoke();
            }
        }
        private void ButtonCopyEntireSchedule_Click(object sender, EventArgs e)
        {
            if (!AreUsernamesValid(Common.AllData()))
            {
                return;
            }

            DateTime sourceWeek = dateTimePickerSource3.Value;
            DateTime targetWeek = dateTimePickerTarget3.Value;
            int      dayDiff    = (Common.GetMondayForWeek(targetWeek) - Common.GetMondayForWeek(sourceWeek)).Days;

            if (Common.GetMondayForWeek(sourceWeek) == Common.GetMondayForWeek(targetWeek))
            {
                return;
            }

            List <Person> peopleWithShiftsToCopy = new List <Person>();

            foreach (Person person in Common.AllData())
            {
                List <Shift> shiftsToCopy = person.GetShiftsForWeek(sourceWeek);
                shiftsToCopy.ForEach(p => //Adjust shiftsToCopy to targetWeek
                {
                    p.StartTime.AddDays(dayDiff);
                    p.EndTime.AddDays(dayDiff);
                });

                Person clone = person.Clone(false);
                clone.TimeBlocks.AddRange(shiftsToCopy);
                peopleWithShiftsToCopy.Add(clone);
            }

            List <Person> filteredPeopleWithShifts = FilterListByConflicts(peopleWithShiftsToCopy);

            foreach (Person person in filteredPeopleWithShifts)
            {
                foreach (Shift shift in person.GetShifts())
                {
                    Common.PendingShiftChanges.Add(new Tuple <Shift, Person, Edit>(shift, person, Edit.Add));
                }
            }

            RefreshGanttChart?.Invoke();
        }
        private void ButtonSendShiftsToChart_Click(object sender, EventArgs e)
        {
            //Make sure everyone has usernames first (otherwise there will be some issues when trying to merge pending changes with current data)
            List <Person> allGanttPeople = navGanttChart.GanttChart.Rows.Cast <Person>().ToList();

            if (AreUsernamesValid(allGanttPeople, false) || AreUsernamesValid(Common.AllData(), false))
            {
                ButtonSendPeopleToChart_Click(null, null);
                MessageBox.Show("Please go to the \"People\" tab and make sure a username is defined for everyone");

                return;
            }

            List <Person> filteredPeople = FilterListByConflicts(allGanttPeople);

            //Update pending changes
            filteredPeople.ForEach(p => Common.PendingPersonChanges.Add(new Tuple <Person, Edit>(p, Edit.Merge)));
            RefreshGanttChart?.Invoke();

            UpdatePersonListBox();
            UpdateAllComboBoxesWithPeople();
        }