public async Task <IActionResult> Edit(int id, CandidateViewModel model)
        {
            if (id != model.Candidate.CandidateId)
            {
                return(NotFound());
            }

            // Remove the "deleted" details from the list
            if (model.RemovedDetails != null && model.RemovedDetails != "")
            {
                string[] itemsToRemove = model.RemovedDetails.Split(',', StringSplitOptions.RemoveEmptyEntries);
                int[]    indexes       = new int[itemsToRemove.Length];
                for (int i = 0; i < itemsToRemove.Length; ++i)
                {
                    indexes[i] = int.Parse(itemsToRemove[i]);
                }

                // sort in ascending order
                indexes = indexes.OrderBy(i => i).ToArray();

                for (int i = indexes.Length - 1; i >= 0; --i)
                {
                    model.Candidate.Details.RemoveAt(indexes[i]);
                }
            }

            // Remove the "deleted" contacts from the list
            if (model.RemovedContacts != null && model.RemovedContacts != "")
            {
                string[] contactsToRemove = model.RemovedContacts.Split(',', StringSplitOptions.RemoveEmptyEntries);
                int[]    indexes          = new int[contactsToRemove.Length];
                for (int i = 0; i < contactsToRemove.Length; ++i)
                {
                    indexes[i] = int.Parse(contactsToRemove[i]);
                }

                // sort in ascending order
                indexes = indexes.OrderBy(i => i).ToArray();

                for (int i = indexes.Length - 1; i >= 0; --i)
                {
                    model.Candidate.Contacts.RemoveAt(indexes[i]);
                }
            }

            List <CandidateRace> candidateRaces = null;

            if (model.RaceIds != null)
            {
                candidateRaces = new List <CandidateRace>();

                foreach (string raceid in model.RaceIds)
                {
                    int next = _context.CandidateRaces.Where(c => c.RaceId == int.Parse(raceid)).Count() + 1;

                    CandidateRace cr = new CandidateRace
                    {
                        CandidateId = model.Candidate.CandidateId,
                        RaceId      = int.Parse(raceid),
                        BallotOrder = next
                    };
                    candidateRaces.Add(cr);
                }
            }

            model.Candidate.ElectionId     = _managedElectionID;
            model.Candidate.CandidateRaces = candidateRaces;

            ModelState.Clear();

            model.Races = new SelectList(_context.Races
                                         .Where(r => r.ElectionId == _managedElectionID)
                                         .OrderBy(r => r.BallotOrder),
                                         "RaceId", "PositionName");
            model.Organizations = new SelectList(_context.Organizations, "OrganizationId", "Name", model.Candidate.OrganizationId);

            if (TryValidateModel(model.Candidate))
            {
                if (model.Image != null)
                {
                    if (model.Image.ContentType != "image/jpeg" &&
                        model.Image.ContentType != "image/png" &&
                        model.Image.ContentType != "image/gif")
                    {
                        ViewData["ImageMessage"] = "Invalid image type. Image must be a JPEG, GIF, or PNG.";
                        return(View(model));
                    }

                    if (model.Image.Length < 4500)
                    {
                        ViewData["ImageMessage"] = "Invalid image size. Image must be a minimum size of 5KB.";
                        return(View(model));
                    }

                    string nameOfile   = "images\\" + Utility.GetCurrentDateTime + Path.GetFileName(model.Image.FileName);
                    string fileName    = "wwwroot\\" + nameOfile;
                    var    oldFileName = "wwwroot\\" + model.Candidate.Picture;
                    var    newFile     = new FileStream(fileName, FileMode.Create);
                    model.Image.CopyTo(newFile);
                    newFile.Dispose();
                    model.Candidate.Picture = nameOfile;
                    if (System.IO.File.Exists(oldFileName) && oldFileName != "wwwroot\\images/default.jpg")
                    {
                        System.GC.Collect();
                        System.GC.WaitForPendingFinalizers();
                        System.IO.File.Delete(oldFileName);
                    }
                }
                else
                {
                    var existing = _context.Candidates
                                   .Where(c => c.CandidateId == id)
                                   .Select(c => new { Pic = c.Picture });
                    foreach (var result in existing)
                    {
                        model.Candidate.Picture = result.Pic;
                    }
                }

                try
                {
                    // remove all the candidate's current details, contacts, and races because the update
                    // will recreate them
                    var existingDetails = _context.CandidateDetails.Where(cd => cd.CandidateId == id).ToList();
                    _context.RemoveRange(existingDetails);
                    var existingContacts = _context.Contacts.Where(cd => cd.CandidateId == id).ToList();
                    _context.RemoveRange(existingContacts);
                    var existingRaces = _context.CandidateRaces.Where(cr => cr.CandidateId == id).ToList();
                    _context.RemoveRange(existingRaces);

                    _context.Update(model.Candidate);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!CandidateExists(model.Candidate.CandidateId))
                    {
                        return(NotFound());
                    }
                    else
                    {
                        throw;
                    }
                }
                return(RedirectToAction(nameof(Index)));
            }
            var errors = ModelState.Values.SelectMany(v => v.Errors);

            return(View(model));
        }
        private static void GetCandidatesAndContacts(List <JSONCandidate> candidateData)
        {
            List <Contact>         contacts       = new List <Contact>();
            List <CandidateDetail> details        = new List <CandidateDetail>();
            List <CandidateRace>   candidateRaces = new List <CandidateRace>();

            foreach (var existingCandidate in candidateData)
            {
                Candidate candidate = new Candidate()
                {
                    ElectionId     = DummyElectionId,
                    Name           = existingCandidate.Name,
                    Picture        = "images/" + existingCandidate.Picture,
                    OrganizationId = _context.Organizations
                                     .Where(organization => organization.Name == existingCandidate.Party)
                                     .Single()
                                     .OrganizationId,
                };

                _context.Candidates.Add(candidate);
                _context.SaveChanges();

                if (!string.IsNullOrEmpty(existingCandidate.Priority1))
                {
                    details.Add(new CandidateDetail()
                    {
                        Title       = "Priority 1",
                        Format      = CandidateDetailFormat.OrderedList,
                        Text        = existingCandidate.Priority1,
                        Lang        = Language.en,
                        CandidateId = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Priority2))
                {
                    details.Add(new CandidateDetail()
                    {
                        Title       = "Priority 2",
                        Format      = CandidateDetailFormat.OrderedList,
                        Text        = existingCandidate.Priority2,
                        Lang        = Language.en,
                        CandidateId = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Priority3))
                {
                    details.Add(new CandidateDetail()
                    {
                        Title       = "Priority 3",
                        Format      = CandidateDetailFormat.OrderedList,
                        Text        = existingCandidate.Priority3,
                        Lang        = Language.en,
                        CandidateId = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Platform))
                {
                    details.Add(new CandidateDetail()
                    {
                        Title       = "Platform",
                        Format      = CandidateDetailFormat.Text,
                        Text        = existingCandidate.Platform,
                        Lang        = Language.en,
                        CandidateId = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Biography))
                {
                    details.Add(new CandidateDetail()
                    {
                        Title       = "Biography",
                        Format      = CandidateDetailFormat.Text,
                        Text        = existingCandidate.Biography,
                        Lang        = Language.en,
                        CandidateId = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Twitter))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Twitter,
                        ContactValue  = existingCandidate.Twitter,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Facebook))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Facebook,
                        ContactValue  = existingCandidate.Facebook,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Instagram))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Instagram,
                        ContactValue  = existingCandidate.Instagram,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.YouTube))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.YouTube,
                        ContactValue  = existingCandidate.YouTube,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Other))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Other,
                        ContactValue  = existingCandidate.Other,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Phone))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Phone,
                        ContactValue  = existingCandidate.Phone,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Email))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Email,
                        ContactValue  = existingCandidate.Email,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                if (!string.IsNullOrEmpty(existingCandidate.Website))
                {
                    contacts.Add(new Contact()
                    {
                        ContactMethod = ContactMethod.Website,
                        ContactValue  = existingCandidate.Website,
                        CandidateId   = candidate.CandidateId,
                    });
                }

                CandidateRace candidateRace = new CandidateRace()
                {
                    CandidateId = candidate.CandidateId,
                    RaceId      = _context.Races
                                  .Where(races => races.PositionName == existingCandidate.Position)
                                  .First()
                                  .RaceId,
                    BallotOrder = int.Parse(existingCandidate.BallotOrder),
                };

                candidateRaces.Add(candidateRace);
            }

            _context.CandidateRaces.AddRange(candidateRaces);
            _context.SaveChanges();

            _context.CandidateDetails.AddRange(details);
            _context.SaveChanges();

            _context.Contacts.AddRange(contacts);
            _context.SaveChanges();
        }
        public async Task <IActionResult> Create(CandidateViewModel model)
        {
            var wwwrootPath = "";
            var imagesPath  = "";

            if (model.Image != null)
            {
                if (model.Image.ContentType != "image/jpeg" &&
                    model.Image.ContentType != "image/png" &&
                    model.Image.ContentType != "image/gif")
                {
                    ViewData["ImageMessage"] = "Invalid image type. Image must be a JPEG, GIF, or PNG.";
                    return(View(model));
                }

                if (model.Image.Length < 4500)
                {
                    ViewData["ImageMessage"] = "Invalid image size. Image must be a minimum size of 5KB.";
                    return(View(model));
                }

                imagesPath  = "images\\" + Utility.GetCurrentDateTime + Path.GetFileName(model.Image.FileName);
                wwwrootPath = "wwwroot\\" + imagesPath;
                model.Image.CopyTo(new FileStream(wwwrootPath, FileMode.Create));
                model.Candidate.Picture = imagesPath;
            }
            else
            {
                model.Candidate.Picture = "images\\default.jpg";
            }

            // Remove the "deleted" details from the list
            if (model.RemovedDetails != null && model.RemovedDetails != "")
            {
                string[] itemsToRemove = model.RemovedDetails.Split(',', StringSplitOptions.RemoveEmptyEntries);
                int[]    indexes       = new int[itemsToRemove.Length];
                for (int i = 0; i < itemsToRemove.Length; ++i)
                {
                    indexes[i] = int.Parse(itemsToRemove[i]);
                }

                // sort in ascending order
                indexes = indexes.OrderBy(i => i).ToArray();

                for (int i = indexes.Length - 1; i >= 0; --i)
                {
                    model.Candidate.Details.RemoveAt(indexes[i]);
                }
            }

            // Remove the "deleted" contacts from the list
            if (model.RemovedContacts != null && model.RemovedContacts != "")
            {
                string[] contactsToRemove = model.RemovedContacts.Split(',', StringSplitOptions.RemoveEmptyEntries);
                int[]    indexes          = new int[contactsToRemove.Length];
                for (int i = 0; i < contactsToRemove.Length; ++i)
                {
                    indexes[i] = int.Parse(contactsToRemove[i]);
                }

                // sort in ascending order
                indexes = indexes.OrderBy(i => i).ToArray();

                for (int i = indexes.Length - 1; i >= 0; --i)
                {
                    model.Candidate.Contacts.RemoveAt(indexes[i]);
                }
            }

            List <CandidateRace> candidateRaces = null;

            if (model.RaceIds != null)
            {
                candidateRaces = new List <CandidateRace>();

                foreach (string raceid in model.RaceIds)
                {
                    int next = _context.CandidateRaces.Where(c => c.RaceId == int.Parse(raceid)).Count() + 1;

                    CandidateRace cr = new CandidateRace
                    {
                        CandidateId = model.Candidate.CandidateId,
                        RaceId      = int.Parse(raceid),
                        BallotOrder = next
                    };
                    candidateRaces.Add(cr);
                }
            }

            model.Candidate.ElectionId     = _managedElectionID;
            model.Candidate.CandidateRaces = candidateRaces;

            ModelState.Clear();

            if (TryValidateModel(model.Candidate))
            {
                _context.Add(model.Candidate);
                await _context.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }
            var errors = ModelState.Values.SelectMany(v => v.Errors);

            return(View(model));
        }
        public async Task <IActionResult> Copy(int?id)
        {
            // New Election
            var election = await _context.Elections.FindAsync(id);

            election.ElectionId   = _context.Elections.OrderByDescending(e => e.ElectionId).FirstOrDefault().ElectionId + 1;
            election.ElectionName = "Copy of " + election.ElectionName;
            _context.Add(election);
            await _context.SaveChangesAsync();

            // Copy Races
            var races  = _context.Races.Where(r => r.ElectionId == id);
            var raceId = _context.Races.OrderByDescending(r => r.RaceId).FirstOrDefault().RaceId;
            var i      = 1;

            foreach (var r in races)
            {
                var tempRace = r;
                tempRace.RaceId     = raceId + i;
                tempRace.ElectionId = election.ElectionId;
                _context.Add(tempRace);
                await _context.SaveChangesAsync();

                i++;
            }

            // Copy Steps
            var steps   = _context.Steps.Where(s => s.ElectionId == id);
            var stepsId = _context.Steps.OrderByDescending(s => s.ID).FirstOrDefault().ID;

            foreach (var s in steps)
            {
                var tempS = s;
                tempS.ID         = ++stepsId;
                tempS.ElectionId = election.ElectionId;
                _context.Add(tempS);
                await _context.SaveChangesAsync();
            }

            // Copy Candidate
            var candidates   = _context.Candidates.Where(c => c.ElectionId == id);
            var candidatesId = _context.Candidates.OrderByDescending(c => c.CandidateId).FirstOrDefault().CandidateId;

            i = 1;
            foreach (var c in candidates)
            {
                var tempCandidate = new Candidate {
                    CandidateId    = candidatesId + i,
                    ElectionId     = election.ElectionId,
                    Name           = c.Name,
                    Picture        = "images/default.jpg",
                    OrganizationId = c.OrganizationId
                };
                _context.Add(tempCandidate);
                await _context.SaveChangesAsync();

                i++;

                // Copy CandidateDetails
                var candidateDetails   = _context.CandidateDetails.Where(cd => cd.CandidateId == c.CandidateId);
                var candidateDetailsId = _context.CandidateDetails.OrderByDescending(cd => cd.ID).FirstOrDefault().ID;
                var j = 1;
                foreach (var cd in candidateDetails)
                {
                    var tempCandidateDetails = new CandidateDetail {
                        ID          = candidateDetailsId + j,
                        CandidateId = tempCandidate.CandidateId,
                        Title       = cd.Title,
                        Text        = cd.Text,
                        Format      = cd.Format,
                        Lang        = cd.Lang
                    };
                    _context.Add(tempCandidateDetails);
                    await _context.SaveChangesAsync();

                    j++;
                }

                // Copy Candidate Contacts
                var candidateContacts   = _context.Contacts.Where(con => con.CandidateId == c.CandidateId);
                var candidateContactsId = _context.Contacts.OrderByDescending(con => con.ContactId).FirstOrDefault().ContactId;
                j = 1;
                foreach (var con in candidateContacts)
                {
                    var tempCandidateContacts = new Contact {
                        ContactId     = candidateContactsId + j,
                        ContactMethod = con.ContactMethod,
                        ContactValue  = con.ContactValue,
                        CandidateId   = tempCandidate.CandidateId
                    };
                    _context.Add(tempCandidateContacts);
                    await _context.SaveChangesAsync();

                    j++;
                }

                // Copy Candidate Races
                var newRaces = _context.Races.Where(r => r.ElectionId == election.ElectionId);
                var k        = 0;
                foreach (var r in races)
                {
                    var candidateRaces   = _context.CandidateRaces.Where(cr => cr.CandidateId == c.CandidateId && cr.RaceId == r.RaceId);
                    var candidateRacesId = _context.CandidateRaces.OrderByDescending(cr => cr.CandidateRaceId).FirstOrDefault().CandidateRaceId;
                    j = 1;
                    foreach (var cr in candidateRaces)
                    {
                        var tempCR = new CandidateRace {
                            CandidateRaceId = candidateRacesId + j,
                            CandidateId     = tempCandidate.CandidateId,
                            RaceId          = newRaces.Skip(k).First().RaceId,
                            BallotOrder     = cr.BallotOrder
                        };
                        _context.Add(tempCR);
                        await _context.SaveChangesAsync();

                        j++;
                    }
                    k++;
                }
            }

            // Copy Polling Places
            var pollingPlaces   = _context.PollingPlaces.Where(c => c.ElectionId == id);
            var pollingPlacesId = _context.PollingPlaces.OrderByDescending(pp => pp.PollingPlaceId).FirstOrDefault().PollingPlaceId;

            i = 1;
            foreach (var pp in pollingPlaces)
            {
                var tempPp = new PollingPlace {
                    PollingPlaceId     = pollingPlacesId + i,
                    ElectionId         = election.ElectionId,
                    PollingPlaceName   = pp.PollingPlaceName,
                    PollingStationName = pp.PollingStationName,
                    Address            = pp.Address,
                    WheelchairInfo     = pp.WheelchairInfo,
                    ParkingInfo        = pp.ParkingInfo,
                    Latitude           = pp.Latitude,
                    Longitude          = pp.Longitude,
                    AdvanceOnly        = pp.AdvanceOnly,
                    LocalArea          = pp.LocalArea,
                    Phone = pp.Phone,
                    Email = pp.Email
                };
                _context.Add(tempPp);
                await _context.SaveChangesAsync();

                i++;

                // Copy PollingPlaceDates
                var pollingPlaceDates = _context.PollingPlaceDates.Where(ppd => ppd.PollingPlaceId == pp.PollingPlaceId);
                var pollingDateId     = _context.PollingPlaceDates.OrderByDescending(ppd => ppd.PollingDateId).FirstOrDefault().PollingDateId;
                var j = 1;
                foreach (var ppd in pollingPlaceDates)
                {
                    var tempPpd = new PollingPlaceDate {
                        PollingDateId  = pollingDateId + j,
                        PollingPlaceId = tempPp.PollingPlaceId,
                        PollingDate    = ppd.PollingDate,
                        StartTime      = ppd.StartTime,
                        EndTime        = ppd.EndTime
                    };
                    _context.Add(tempPpd);
                    await _context.SaveChangesAsync();

                    j++;
                }
            }

            // Copy BallotIssues
            var ballotIssues   = _context.BallotIssues.Where(b => b.ElectionId == id);
            var ballotIssuesId = _context.BallotIssues.OrderByDescending(b => b.BallotIssueId).FirstOrDefault().BallotIssueId;

            i = 1;
            foreach (var b in ballotIssues)
            {
                var tempB = new BallotIssue {
                    BallotIssueId    = ballotIssuesId + i,
                    ElectionId       = election.ElectionId,
                    BallotIssueTitle = b.BallotIssueTitle,
                    Description      = b.Description
                };
                _context.Add(tempB);
                await _context.SaveChangesAsync();

                i++;

                // IssueOptions
                var issueOptions   = _context.IssueOptions.Where(io => io.BallotIssueId == b.BallotIssueId);
                var issueOptionsId = _context.IssueOptions.OrderByDescending(io => io.IssueOptionId).FirstOrDefault().IssueOptionId;
                var j = 1;
                foreach (var bi in issueOptions)
                {
                    var tempBi = new IssueOption {
                        IssueOptionId   = issueOptionsId + j,
                        IssueOptionInfo = bi.IssueOptionInfo,
                        BallotIssueId   = tempB.BallotIssueId
                    };
                    _context.Add(tempBi);
                    await _context.SaveChangesAsync();

                    j++;
                }
            }

            // Copy Social Medias
            var socialMedias   = _context.SocialMedias.Where(c => c.ElectionId == id);
            var socialMediasId = _context.SocialMedias.OrderByDescending(sm => sm.ID).FirstOrDefault().ID;

            foreach (var sm in socialMedias)
            {
                var tempSM = sm;
                tempSM.ID         = ++socialMediasId;
                tempSM.ElectionId = election.ElectionId;
                _context.Add(tempSM);
                await _context.SaveChangesAsync();
            }

            return(RedirectToAction(nameof(Index)));
        }