private List<Category> GetListOfNodes()
 {
     List<Category> sourceCategories = _context.Categories.ToList();
     List<Category> categories = new List<Category>();
     foreach (Category sourceCategory in sourceCategories)
     {
         Category c = new Category();
         c.Id = sourceCategory.Id;
         c.Name = sourceCategory.Name;
         if (sourceCategory.ParentCategoryId != null)
         {
             c.Parent = new Category();
             c.Parent.Id = (int)sourceCategory.ParentCategoryId;
         }
         categories.Add(c);
     }
     return categories;
 }
        private string EnumerateNodes(Category parent)
        {
            // Init an empty string
            var content = string.Empty;

            // Add <li> category name
            content += "<li class=\"treenode\">";
            content += parent.Name;
            content +=
                string.Format(
                    "<a href=\"/Categories/Edit/{0}\" class=\"btn btn-primary btn-xs treenodeeditbutton\">Edit</a>",
                    parent.Id);
            content +=
                string.Format(
                    "<a href=\"/Categories/Delete/{0}\" class=\"btn btn-danger btn-xs treenodedeletebutton\">Delete</a>",
                    parent.Id);

            // If there are no children, end the </li>
            if (parent.Children.Count == 0)
                content += "</li>";
            else // If there are children, start a <ul>
                content += "<ul>";

            // Loop one past the number of children
            var numberOfChildren = parent.Children.Count;
            for (var i = 0; i <= numberOfChildren; i++)
            {
                // If this iteration's index points to a child,
                // call this function recursively
                if (numberOfChildren > 0 && i < numberOfChildren)
                {
                    var child = parent.Children[i];
                    content += EnumerateNodes(child);
                }

                // If this iteration's index points past the children, end the </ul>
                if (numberOfChildren > 0 && i == numberOfChildren)
                    content += "</ul>";
            }

            // Return the content
            return content;
        }
        private async Task<List<Category>> GetListOfNodes()
        {
            var categories = new List<Category>();

            var sourceCategories = await _context.Categories.ToListAsync();
            
            foreach (Category sourceCategory in sourceCategories)
            {
                var newCategory = new Category
                {
                    Id = sourceCategory.Id,
                    Name = sourceCategory.Name
                };
                if (sourceCategory.ParentCategoryId != null)
                {
                    newCategory.Parent = new Category {Id = (int) sourceCategory.ParentCategoryId};
                }
                categories.Add(newCategory);
            }
            return categories;
        }
        private void ValidateParentsAreParentless(Category category)
        {
            // There is no parent
            if(category.ParentCategoryId == null)
                return;

            // The parent has a parent
            Category parentCategory = _context.Categories.Find(category.ParentCategoryId);
            if(parentCategory.ParentCategoryId != null)
                throw new InvalidOperationException("You cannot nest this category more than two levels deep.");

            // The parent does NOT have a parent, but the category being nested has children
            int numberOfChildren = _context.Categories.Count(c => c.ParentCategoryId == category.Id);
            if(numberOfChildren > 0)
                throw new InvalidOperationException("You cannot nest this category's children more than two levels deep.");
        }
        public async Task<ActionResult> Edit([Bind(Include = "Id,ParentCategoryId,CategoryName")] CategoryViewModel categoryViewModel)
        {
            if (ModelState.IsValid)
            {
                // Unwind back to a Category
                Category editedCategory = new Category();

                try
                {
                    editedCategory.Id = categoryViewModel.Id;
                    editedCategory.ParentCategoryId = categoryViewModel.ParentCategoryId;
                    editedCategory.Name = categoryViewModel.Name;
                    ValidateParentsAreParentless(editedCategory);
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", ex.Message);
                    ViewBag.ParentCategoryIdSelectList = PopulateParentCategorySelectList(categoryViewModel.Id);
                    return View("Edit", categoryViewModel);
                }


                _context.Entry(editedCategory).State = EntityState.Modified;
                await _context.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            ViewBag.ParentCategoryIdSelectList = PopulateParentCategorySelectList(categoryViewModel.Id);
            return View(categoryViewModel);
        }
        public async Task<ActionResult> Edit(CategoryViewModel form, HttpPostedFileBase file, HttpPostedFileBase linkFile)
        {
            if (ModelState.IsValid)
            {
                if (file != null)
                {
                    FileServices.UploadFile(file, Server, _fileDestination);
                    form.PicFileName = Path.GetFileName(file.FileName);
                }

                if (linkFile != null)
                {
                    FileServices.UploadFile(file, Server, _fileDestination);
                    form.LinkToFileName = Path.GetFileName(linkFile.FileName);
                }
                // Unwind back to a Category
                var editedCategory = new Category();
                {
                    editedCategory.Id = form.Id;
                    editedCategory.ParentCategoryId = form.ParentCategoryId;
                    editedCategory.Name = form.Name;
                    editedCategory.CategoryCode = form.CategoryCode;
                    editedCategory.PicFileName = form.PicFileName;
                    editedCategory.LinkToFileName = form.LinkToFileName;
                }

                _context.Entry(editedCategory).State = EntityState.Modified;
                await _context.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            ViewBag.ParentCategoryIdSelectList = PopulateParentCategorySelectList(form.Id);
            return View(form);
        }
        public async Task<ActionResult> Add(CategoryViewModel form, HttpPostedFileBase file, HttpPostedFileBase linkFile)
        {
            if (ModelState.IsValid)
            {
                if (file != null)
                {
                    FileServices.UploadFile(file, Server, _fileDestination);
                    form.PicFileName = Path.GetFileName(file.FileName);
                }
                if (linkFile != null)
                {
                    FileServices.UploadFile(file, Server, _fileDestination);
                    form.LinkToFileName = Path.GetFileName(linkFile.FileName);
                }
                var category = new Category
                {
                    ParentCategoryId = form.ParentCategoryId,
                    CategoryCode = form.CategoryCode,
                    Name = form.Name,
                    PicFileName = form.PicFileName,
                    LinkToFileName = form.LinkToFileName

                };

                _context.Categories.Add(category);
                await _context.SaveChangesAsync();
                return RedirectToAction("Index");
            }

            ViewBag.ParentCategoryIdSelectList = PopulateParentCategorySelectList(null);
            return View(form);
        }