/// <summary>
        /// Creates a TaxonMove view model
        /// </summary>
        /// <param name="taxon"></param>
        /// <param name="isOkToMove"></param>
        /// <returns></returns>
        public TaxonMoveViewModel CreateTaxonMoveViewModel(ITaxon taxon, ITaxonRevision taxonRevision, bool isOkToMove = true)
        {
            var model = new TaxonMoveViewModel();

            model.TaxonId          = taxon.Id;
            model.OldParentTaxonId = taxon.Id;
            model.HasChildren      = true;
            model.IsOkToMove       = isOkToMove;

            // Child taxa
            model.ChildTaxa = new List <RelatedTaxonViewModel>();
            if (taxon.GetNearestChildTaxonRelations(_user).IsNotEmpty())
            {
                foreach (ITaxonRelation taxonRelation in taxon.GetNearestChildTaxonRelations(_user))
                {
                    model.ChildTaxa.Add(new RelatedTaxonViewModel(taxonRelation.ChildTaxon, taxonRelation.ChildTaxon.Category, null, taxonRelation.IsMainRelation));
                }
            }
            if (model.ChildTaxa.Count == 0)
            {
                // TODO cant throw exception
                //throw new Exception("Taxon has no children");
                model.HasChildren = false;
            }

            // Available parents
            TaxonCategoryList categories2 = new TaxonCategoryList();

            model.AvailableParents = new List <RelatedTaxonViewModel>();
            if (model.ChildTaxa.Count != 0)
            {
                ITaxon    revisionTaxon = CoreData.TaxonManager.GetTaxon(_user, model.ChildTaxa[0].TaxonId);
                TaxonList list          = revisionTaxon.GetTaxaPossibleParents(_user, taxonRevision);
                foreach (var tx in list)
                {
                    categories2.Merge(tx.Category);
                }
                categories2.Sort(new TaxonCategoryComparer());

                foreach (ITaxon possibleParentTaxon in list)
                {
                    model.AvailableParents.Add(new RelatedTaxonViewModel(possibleParentTaxon, possibleParentTaxon.Category, null));
                }
            }

            // Taxon categories
            model.TaxonCategories = new List <TaxonCategoryViewModel>();
            // var categories = GetTaxonCategories(taxon);
            // Get all categories within this revision
            TaxonCategoryList categories = GetTaxonCategories(taxonRevision.RootTaxon);

            foreach (ITaxonCategory taxonCategory in categories2)
            {
                model.TaxonCategories.Add(new TaxonCategoryViewModel(taxonCategory.Id, taxonCategory.Name));
            }

            return(model);
        }
 /// <summary>
 /// Searches among the direct children in childtaxonrelations.
 /// </summary>
 public static IList <ITaxonRelation> GetChildTaxonRelations(
     this ITaxon taxon,
     IUserContext userContext,
     bool isTaxonRevisionEditor,
     bool includeHistorical,
     bool isMainRelation = false)
 {
     if (includeHistorical == false && taxon.IsValid == false)
     {
         return(new List <ITaxonRelation>());
     }
     else
     {
         // TaxonRevisionEditor == true (in revision - return published data + data that is changed in the revision)
         if (isTaxonRevisionEditor)
         {
             if (includeHistorical)
             {
                 return((from taxonRelation in taxon.GetNearestChildTaxonRelations(userContext)
                         where taxonRelation.IsMainRelation == true || isMainRelation == false
                         select taxonRelation).ToList());
             }
             // includeHistorical == false
             else
             {
                 return((from taxonRelation in taxon.GetNearestChildTaxonRelations(userContext)
                         where (taxonRelation.ValidToDate > DateTime.Now && (!taxonRelation.ReplacedInTaxonRevisionEventId.HasValue)) &&
                         (taxonRelation.IsMainRelation == true || isMainRelation == false)
                         select taxonRelation).ToList());
             }
         }
         // TaxonRevisionEditor == false (NOT in revision - return public data)
         else
         {
             if (includeHistorical)
             {
                 return((from taxonRelation in taxon.GetNearestChildTaxonRelations(userContext)
                         where taxonRelation.IsPublished == true &&
                         (taxonRelation.IsMainRelation == true || isMainRelation == false)
                         select taxonRelation).ToList());
             }
             // includeHistorical = false
             else
             {
                 return((from taxonRelation in taxon.GetNearestChildTaxonRelations(userContext)
                         where (taxonRelation.ValidToDate > DateTime.Now && taxonRelation.IsPublished == true) &&
                         (taxonRelation.IsMainRelation == true || isMainRelation == false)
                         select taxonRelation).ToList());
             }
         }
     }
 }
        public void ReInitializeTaxonMoveViewModel(TaxonMoveViewModel model, ITaxonRevision taxonRevision, bool isOkToMove = true) //, ITaxon taxon, bool isOkToMove = true)
        {
            ITaxon taxon = CoreData.TaxonManager.GetTaxon(_user, model.OldParentTaxonId);

            model.HasChildren = true;
            model.IsOkToMove  = isOkToMove;

            // Child taxa
            model.ChildTaxa = new List <RelatedTaxonViewModel>();
            if (taxon.GetNearestChildTaxonRelations(_user).IsNotEmpty())
            {
                foreach (ITaxonRelation taxonRelation in taxon.GetNearestChildTaxonRelations(_user))
                {
                    model.ChildTaxa.Add(new RelatedTaxonViewModel(taxonRelation.ChildTaxon, taxonRelation.ChildTaxon.Category, null));
                }
            }
            if (model.ChildTaxa.Count == 0)
            {
                // TODO cant throw exception
                //throw new Exception("Taxon has no children");
                model.HasChildren = false;
            }

            // Available parents
            model.AvailableParents = new List <RelatedTaxonViewModel>();
            if (model.ChildTaxa.Count != 0)
            {
                ITaxon    revisionTaxon = CoreData.TaxonManager.GetTaxon(_user, model.ChildTaxa[0].TaxonId);
                TaxonList list          = revisionTaxon.GetTaxaPossibleParents(_user, taxonRevision);
                foreach (ITaxon possibleParentTaxon in list)
                {
                    model.AvailableParents.Add(new RelatedTaxonViewModel(possibleParentTaxon, possibleParentTaxon.Category, null));
                }
            }

            // Taxon categories
            model.TaxonCategories = new List <TaxonCategoryViewModel>();
            // var categories = GetTaxonCategories(taxon);
            // Get all categories within this revision
            var categories = GetTaxonCategories(taxonRevision.RootTaxon);

            foreach (ITaxonCategory taxonCategory in categories)
            {
                model.TaxonCategories.Add(new TaxonCategoryViewModel(taxonCategory.Id, taxonCategory.Name));
            }
        }
        /// <summary>
        /// Creates the model for lumping
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="taxon"></param>
        /// <param name="revisionId"></param>
        /// <param name="replacingTaxonId"></param>
        /// <param name="lumpTaxonIdList"></param>
        /// <returns></returns>
        public TaxonLumpViewModel GetTaxonLumpViewModel(IUserContext userContext, ITaxon taxon, int revisionId, int?replacingTaxonId, List <int?> lumpTaxonIdList, bool isOkToLump, bool isReloaded)
        {
            TaxonLumpViewModel model        = new TaxonLumpViewModel();
            IUserContext       loggedInUser = userContext;

            if (loggedInUser.IsNotNull())
            {
                if (taxon.IsNotNull() && taxon.Id.IsNotNull())
                {
                    model.TaxonErrorId = taxon.Id.ToString();
                    if (revisionId.IsNotNull())
                    {
                        model.RevisionErrorId = revisionId.ToString();
                        model.RevisionId      = revisionId.ToString();
                        model.TaxonId         = taxon.Id.ToString();
                        model.IsSelectedTaxonSetAsReplacingTaxon = false;
                        model.IsSelectedTaxonAlreadyInLumpList   = false;
                        model.IsReplacingTaxonSet      = false;
                        model.IsSelectedTaxonChildless = true;
                        model.IsAnyLumpTaxonSet        = false;
                        model.IsOkToLump               = isOkToLump;
                        model.IsReloaded               = isReloaded;
                        model.IsReplacingTaxonValid    = true;
                        model.IsLumpTaxonValid         = true;
                        model.IsLumpTaxonCategoryValid = true;

                        // 1. first we check selected taxon if it has any children
                        if (taxon.GetNearestChildTaxonRelations(userContext).IsNotEmpty())
                        {
                            model.IsSelectedTaxonChildless = false;
                        }
                        //model.SelectedTaxon = new List<TaxonParentViewModelHelper>();
                        //// Get selected taxon ie taxon selected in GUI
                        //TaxonParentViewModelHelper selectedTaxon = new TaxonParentViewModelHelper();
                        //selectedTaxon.Category = CoreData.TaxonManager.GetTaxonCategoryById(loggedInUser, taxon.Category).Name;
                        //selectedTaxon.CommonName = taxon.RecommendedCommonName.IsNotNull() ? taxon.RecommendedCommonName.Name : string.Empty;
                        //selectedTaxon.ScientificName = taxon.RecommendedScentificName.IsNotNull() ? taxon.RecommendedScentificName.Name : string.Empty;
                        //selectedTaxon.TaxonId = taxon.Id.ToString();
                        //model.SelectedTaxon.Add(selectedTaxon);
                        // we now check if selected taxon exist in list to lump
                        if (lumpTaxonIdList.IsNotNull() && !lumpTaxonIdList.Contains(null) && lumpTaxonIdList.Contains(taxon.Id))
                        {
                            model.IsSelectedTaxonAlreadyInLumpList = true;
                        }

                        //2. Check if replacing taxon is set, if so show it.
                        if (replacingTaxonId.IsNotNull())
                        {
                            model.IsReplacingTaxonSet = true;
                            ITaxon repTaxon = CoreData.TaxonManager.GetTaxon(loggedInUser, (int)replacingTaxonId);
                            model.ReplacingTaxon = new List <TaxonParentViewModelHelper>();
                            TaxonParentViewModelHelper replacingTaxon = new TaxonParentViewModelHelper();
                            replacingTaxon.Category       = repTaxon.Category.Name;
                            replacingTaxon.CommonName     = repTaxon.CommonName.IsNotEmpty() ? repTaxon.CommonName : string.Empty;
                            replacingTaxon.ScientificName = repTaxon.ScientificName.IsNotEmpty() ? repTaxon.ScientificName : string.Empty;
                            replacingTaxon.TaxonId        = repTaxon.Id.ToString();
                            model.ReplacingTaxon.Add(replacingTaxon);

                            model.ReplacingTaxonId = repTaxon.Id.ToString();
                            // Now we must check if selected taxon equals replacing taxon
                            if (repTaxon.Id == taxon.Id)
                            {
                                model.IsSelectedTaxonSetAsReplacingTaxon = true;
                            }
                            if (!model.IsOkToLump)
                            {
                                if (repTaxon.GetCheckedOutChangesTaxonProperties(userContext).IsValid == false)
                                {
                                    model.IsReplacingTaxonValid = false;
                                    model.TaxonErrorName        = repTaxon.ScientificName;
                                    //  model.IsOkToLump = true;
                                }
                            }
                        }

                        // 3. Check and populate list of taxon to lump
                        model.LumpTaxonList = new List <TaxonParentViewModelHelper>();
                        if (taxon.IsNotNull())
                        {
                            if (lumpTaxonIdList.IsNotNull() && !lumpTaxonIdList.Contains(null))
                            {
                                var       lumpIdList = lumpTaxonIdList.Cast <int>().ToList();
                                TaxonList taxa       = CoreData.TaxonManager.GetTaxa(loggedInUser, lumpIdList);
                                if (taxa.IsNotNull() && taxa.Count > 0)
                                {
                                    var category = taxa[0].GetCheckedOutChangesTaxonProperties(userContext).TaxonCategory;
                                    foreach (ITaxon lumpTaxon in taxa)
                                    {
                                        var lumpTaxonModel = new TaxonParentViewModelHelper();
                                        lumpTaxonModel.Category       = lumpTaxon.Category.Name;
                                        lumpTaxonModel.SortOrder      = lumpTaxon.Category.SortOrder;
                                        lumpTaxonModel.CommonName     = lumpTaxon.CommonName.IsNotEmpty() ? lumpTaxon.CommonName : string.Empty;
                                        lumpTaxonModel.ScientificName = lumpTaxon.ScientificName.IsNotEmpty() ? lumpTaxon.ScientificName : string.Empty;
                                        lumpTaxonModel.TaxonId        = lumpTaxon.Id.ToString();
                                        model.LumpTaxonList.Add(lumpTaxonModel);
                                        // Check why it is not ok to lump
                                        if (!model.IsOkToLump)
                                        {
                                            if (lumpTaxon.GetCheckedOutChangesTaxonProperties(userContext).TaxonCategory.Id != category.Id)
                                            {
                                                model.IsLumpTaxonCategoryValid = false;
                                                model.TaxonErrorName           = lumpTaxon.ScientificName;
                                                // model.IsOkToLump = true;
                                            }

                                            if (lumpTaxon.GetCheckedOutChangesTaxonProperties(userContext).IsValid == false)
                                            {
                                                model.IsLumpTaxonValid = false;
                                                model.TaxonErrorName   = lumpTaxon.ScientificName;
                                                // model.IsOkToLump = true;
                                            }
                                        }
                                    }
                                }

                                model.IsAnyLumpTaxonSet = true;
                            }
                        }
                    }
                    else
                    {
                        model.ErrorMessage = Resources.DyntaxaResource.TaxonSharedInvalidRevision;
                    }
                }
                else
                {
                    model.ErrorMessage = Resources.DyntaxaResource.TaxonSharedInvalidTaxon;
                }
            }
            else
            {
                model.ErrorMessage = Resources.DyntaxaResource.SharedInvalidUserContext;
            }
            return(model);
        }
        /// <summary>
        /// Create view model for split
        /// </summary>
        /// <param name="userContext"></param>
        /// <param name="taxon"></param>
        /// <param name="revisionId"></param>
        /// <param name="replaceTaxonIdList"></param>
        /// <param name="splitTaxonId"></param>
        /// <returns></returns>
        public TaxonSplitViewModel GetTaxonSplitViewModel(IUserContext userContext, ITaxon taxon, int revisionId, List <int?> replaceTaxonIdList, int?splitTaxonId, bool isOkToSplit, bool isReloaded)
        {
            TaxonSplitViewModel model        = new TaxonSplitViewModel();
            IUserContext        loggedInUser = userContext;

            if (loggedInUser.IsNotNull())
            {
                if (taxon.IsNotNull() && taxon.Id.IsNotNull())
                {
                    model.TaxonErrorId = taxon.Id.ToString();
                    if (revisionId.IsNotNull())
                    {
                        model.RevisionErrorId = revisionId.ToString();
                        model.RevisionId      = revisionId.ToString();
                        model.TaxonId         = taxon.Id.ToString();
                        model.IsSelectedTaxonSetAsSplitTaxon        = false;
                        model.IsSelectedTaxonAlreadyInReplacingList = false;
                        model.IsSelectedTaxonChildless = true;
                        model.IsAnyReplacingTaxonSet   = false;
                        model.IsSplitTaxonSet          = false;
                        model.IsOkToSplit                   = isOkToSplit;
                        model.IsReloaded                    = isReloaded;
                        model.IsSplitTaxonValid             = true;
                        model.IsReplacingTaxonValid         = true;
                        model.IsReplacingTaxonCategoryValid = true;

                        // 1. first we check selected taxon if it has any children
                        if (taxon.GetNearestChildTaxonRelations(userContext).IsNotEmpty())
                        {
                            model.IsSelectedTaxonChildless = false;
                        }
                        model.SelectedTaxon = new List <TaxonParentViewModelHelper>();
                        // Set selected taxon
                        TaxonParentViewModelHelper selectedTaxon = new TaxonParentViewModelHelper();
                        selectedTaxon.Category       = taxon.Category.Name;
                        selectedTaxon.CommonName     = taxon.CommonName.IsNotEmpty() ? taxon.CommonName : string.Empty;
                        selectedTaxon.ScientificName = taxon.ScientificName.IsNotEmpty() ? taxon.ScientificName : string.Empty;
                        selectedTaxon.TaxonId        = taxon.Id.ToString();
                        model.SelectedTaxon.Add(selectedTaxon);
                        // We now check if selected taxon exist in list of replacing taxa
                        if (replaceTaxonIdList.IsNotNull() && !replaceTaxonIdList.Contains(null) && replaceTaxonIdList.Contains(taxon.Id))
                        {
                            model.IsSelectedTaxonAlreadyInReplacingList = true;
                        }

                        // 2. Check and populate list of replacing taxa
                        model.ReplacingTaxonList = new List <TaxonParentViewModelHelper>();
                        if (taxon.IsNotNull())
                        {
                            if (replaceTaxonIdList.IsNotNull() && !replaceTaxonIdList.Contains(null))
                            {
                                var       replaceIdList = replaceTaxonIdList.Cast <int>().ToList();
                                TaxonList taxa          = CoreData.TaxonManager.GetTaxa(loggedInUser, replaceIdList);
                                var       category      = taxa[0].GetCheckedOutChangesTaxonProperties(userContext).TaxonCategory;

                                if (taxa.IsNotNull() && taxa.Count > 0)
                                {
                                    foreach (ITaxon replaceTaxon in taxa)
                                    {
                                        var splitTaxonModel = new TaxonParentViewModelHelper();
                                        splitTaxonModel.Category       = replaceTaxon.Category.Name;
                                        splitTaxonModel.SortOrder      = replaceTaxon.Category.SortOrder;
                                        splitTaxonModel.CommonName     = replaceTaxon.CommonName.IsNotEmpty() ? replaceTaxon.CommonName : string.Empty;
                                        splitTaxonModel.ScientificName = replaceTaxon.ScientificName.IsNotEmpty() ? replaceTaxon.ScientificName : string.Empty;
                                        splitTaxonModel.TaxonId        = replaceTaxon.Id.ToString();
                                        model.ReplacingTaxonList.Add(splitTaxonModel);

                                        // Check why it is not ok to split
                                        if (!model.IsOkToSplit)
                                        {
                                            if (replaceTaxon.GetCheckedOutChangesTaxonProperties(userContext).TaxonCategory.Id != category.Id)
                                            {
                                                model.IsReplacingTaxonCategoryValid = false;
                                                model.TaxonErrorName = replaceTaxon.ScientificName;
                                                // model.IsOkToSplit = true;
                                            }

                                            if (replaceTaxon.GetCheckedOutChangesTaxonProperties(userContext).IsValid == false)
                                            {
                                                model.IsReplacingTaxonValid = false;
                                                model.TaxonErrorName        = replaceTaxon.ScientificName;
                                                // model.IsOkToSplit = true;
                                            }
                                        }
                                    }
                                }
                                model.IsAnyReplacingTaxonSet = true;
                            }
                        }

                        //3. Check if split taxon is set, if so show it.
                        if (splitTaxonId.IsNotNull())
                        {
                            ITaxon repTaxon = CoreData.TaxonManager.GetTaxon(loggedInUser, (int)splitTaxonId);
                            model.SplitTaxon = new List <TaxonParentViewModelHelper>();
                            TaxonParentViewModelHelper replacingTaxon = new TaxonParentViewModelHelper();
                            replacingTaxon.Category       = repTaxon.Category.Name;
                            replacingTaxon.CommonName     = repTaxon.CommonName.IsNotEmpty() ? repTaxon.CommonName : string.Empty;
                            replacingTaxon.ScientificName = repTaxon.ScientificName.IsNotEmpty() ? repTaxon.ScientificName : string.Empty;
                            replacingTaxon.TaxonId        = repTaxon.Id.ToString();
                            model.SplitTaxon.Add(replacingTaxon);
                            model.IsSplitTaxonSet  = true;
                            model.ReplacingTaxonId = repTaxon.Id.ToString();
                            // Now we must check if selected taxon equals replacing taxon
                            if (repTaxon.Id == taxon.Id)
                            {
                                model.IsSelectedTaxonSetAsSplitTaxon = true;
                            }
                            if (!model.IsOkToSplit)
                            {
                                if (repTaxon.GetCheckedOutChangesTaxonProperties(userContext).IsValid == false)
                                {
                                    model.IsSplitTaxonValid = false;
                                    model.TaxonErrorName    = repTaxon.ScientificName;
                                    // model.IsOkToSplit = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        model.ErrorMessage = Resources.DyntaxaResource.TaxonSharedInvalidRevision;
                    }
                }
                else
                {
                    model.ErrorMessage = Resources.DyntaxaResource.TaxonSharedInvalidTaxon;
                }
            }
            else
            {
                model.ErrorMessage = Resources.DyntaxaResource.SharedInvalidUserContext;
            }
            return(model);
        }