namespace App.Mvc.Controllers
{
    using Contracts;
    using Mvc;
    using Contracts.Services;
    using Models;
    using Filters;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;
    using System.Web;
	[Filters.ExceptionHandler]
    public class DelegateController : Controller
    {
		private readonly ILogProvider log ; 
		private const string LogName = "Delegate";
        private readonly IDelegateService service ;   
        public DelegateController(ILogProvider log, IDelegateService service )
        {
            this.service = service;
			this.log = log;
            
        }
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
			log.LogActionExecuting(LogName,filterContext);
			ViewBag.Title = "App";
            ViewBag.SectionTitle = "Delegate";
        }
        // GET: Delegate
		[RolesRequired("Admin","ListDelegate")]
        public ActionResult Index()
        {
            var errors = new List<IModelError>();
            var models = service.GetAll(x => x != null, errors);
            ViewBag.Errors = errors;
            ViewBag.ToolButtons = "VED"; // View Edit Delete 
			ViewBag.Title = "List Delegate" ; 
            return View(models);            
        }
        // Display a form for viewing Delegate
		[RolesRequired("Admin","ViewDelegate")]
        public ActionResult View(int id = -1)
        {			 
            var errors = new List<IModelError>();
            ViewBag.Readonly = true;
            ViewBag.ButtonFlag = "";
			ViewBag.Title = "View Delegate" ; 
            var model = GetViewModel(id,errors);
            return View("Form",model);
        }
        // Display a form for editing Delegate
		[RolesRequired("Admin","SaveDelegate")]        
        public ActionResult Edit(int id = -1)
        {
            var errors = new List<IModelError>();
            ViewBag.Readonly = false;
			ViewBag.ButtonFlag = "RS"; // Relationship Submit
			ViewBag.Title = "Edit Delegate" ; 
            var model = GetViewModel(id,errors);
            return View("Form",model);
        }
		[RolesRequired("Admin","SaveDelegate")]   
        [HttpPost]
        public ActionResult Edit(DelegateViewModel model)
        {
            var errors = new List<IModelError>();
            service.TrySave(model, errors);          
			if (errors.Any())
            {
                this.AddModelErrors(errors);
                ViewBag.Readonly = false;
				ViewBag.ButtonFlag = "RS"; // Relationship Submit
				ViewBag.Title = "Edit Delegate" ; 
                return View("Form", model);
            }
            else
            {
                return RedirectToAction("index", new { updated = model.Id });
            } 
        }
        // Display a form for creating Delegate
		[RolesRequired("Admin","SaveDelegate")]   
        public ActionResult Create(int id = -1)
        {
            var errors = new List<IModelError>();
            ViewBag.Readonly = false;
			ViewBag.ButtonFlag = "S"; // Submit
			ViewBag.Title = "New Delegate" ; 
            var model = GetViewModel(id,errors);
            return View("Form",model);
        }
		[RolesRequired("Admin","SaveDelegate")]   
        [HttpPost]
        public ActionResult Create(DelegateViewModel model)
        {
            var errors = new List<IModelError>();
			service.TrySave(model, errors);  
			if (errors.Any())
            {
                this.AddModelErrors(errors);
                ViewBag.Readonly = false;
                ViewBag.ButtonFlag = "S"; // Submit
				ViewBag.Title = "New Delegate" ; 
                return View("Form", model);
            }
            else
            {
                return RedirectToAction("index", new { creaated = model.Id });
            } 
        }
        // Display a form for deleting Delegate
		[RolesRequired("Admin","DeleteDelegate")]   
        public ActionResult Delete(int id = -1)
        {
            var errors = new List<IModelError>();
            ViewBag.Readonly = true;
            ViewBag.ShowRelationships = false;
			ViewBag.Title = "Delete Delegate" ; 
            var model = GetViewModel(id,errors);
            return View("Form",model);
        }
		[RolesRequired("Admin", "DeleteDelegate")]
        [HttpPost]
        public ActionResult Delete(DelegateViewModel model, int _post)
        {
            var errors = new List<IModelError>();
            var result = service.TryDelete(model.Id, errors);
            ViewBag.Title = "Delete Delegate";
            if (errors.Any())
            {
                model = GetViewModel(model.Id, errors);
                this.AddModelErrors(errors);
                ViewBag.Readonly = false;
                ViewBag.ButtonFlag = "S"; // Submit
                ViewBag.Title = "Delete Delegate";
                return View("Form", model);
            }
            else
            {
                return RedirectToAction("index", new { deleted = model.Id });
            }
        }
		
        // list all Delegate entities
		[RolesRequired("Admin","ListDelegate")]  
        public ActionResult List() 
        {
            var errors = new List<IModelError>();
            var models = service.GetAll(x =>x != null, errors);
            ViewBag.Errors = errors;
            ViewBag.ToolButtons = "VP"; // View Pick 
            ViewBag.PickState = false;
            return View("DelegateList", models);
        }
                
        
        // Supports the many to many relationship (DelegateEvent) between Delegate (parent) Event (child)
        //[Authorize(Roles = "Admin,ListDelegateEvent")]
		[RolesRequired("Admin","ListDelegateEvent")]  
        public ActionResult GetDelegateEvent(int id, bool selected = false) 
        {
            var models = service.GetAllForDelegateEvent(id);
            ViewBag.ToolButtons = "VP"; // View Pick 
            ViewBag.PickState = selected;
            return View("DelegateList", models);
        }
        // Add a relationship (DelegateEvent) between Delegate (parent) Event (child)
        //[Authorize(Roles = "Admin,SaveDelegateEvent")]
		[RolesRequired("Admin","SaveDelegateEvent")]  
        public ActionResult AddDelegateEvent(int id)
        {
            ViewBag.Readonly = false;
            ViewBag.ShowRelationships = false;
            ViewBag.ModelId = new int?(id);
            return View("Form", new DelegateViewModel());
        }
        // Add a relationship (DelegateEvent) between Delegate (parent) Event (child)
        [HttpPost]
        //[Authorize(Roles = "Admin,SaveDelegateEvent")]
		[RolesRequired("Admin","SaveDelegateEvent")]
        public ActionResult SaveDelegateEvent(DelegateViewModel model, int modelId)
        {
            var errors = new List<IModelError>();
            model.Id = 0 ; // force a new object regardless
            var result = service.TrySave(model, errors);
            if (result)
            {
                service.AddEventToDelegateForDelegateEvent(model.Id, modelId);
            }
            return Json(new
            {
                Model = model,
                Success = result,
                Errors = errors
            });
        }
        // remove a relationship (DelegateEvent) between Delegate (parent) Event (child) 
        [HttpPost]
		[RolesRequired("Admin","SaveDelegateEvent")]       
        public ActionResult UnLinkDelegateEvent(int modelId , int[] items)
        {
            var result = true;
            try
            {
                items.DefaultIfNull().AsParallel().ToList().ForEach(i => {
					service.RemoveEventFromDelegateForDelegateEvent(modelId, i);					                  
                });
            }
            catch 
            {
				items.DefaultIfNull().AsParallel().ToList().ForEach(i => {                    
					service.AddEventToDelegateForDelegateEvent(modelId, i);  
                });
                result = false;  
            }
                                   
            return Json(new
            {
                Success = result
            });
        }
        // add a relationship (DelegateEvent) between existing Delegate (parent) Event (child) 
        [HttpPost]
        [RolesRequired("Admin","SaveDelegateEvent")]  
        public ActionResult LinkDelegateEvent(int modelId , int[] items)
        {
            var result = true;
            try
            {
                items.DefaultIfNull().AsParallel().ToList().ForEach(i => {
					service.AddEventToDelegateForDelegateEvent(modelId, i);                    
                });
            }
            catch 
            {
				items.DefaultIfNull().AsParallel().ToList().ForEach(i => {                    
					service.RemoveEventFromDelegateForDelegateEvent(modelId, i);
                });
                result = false;  
            }
                                   
            return Json(new
            {
                Success = result
            });
        }
                
        // Supports the many to many relationship (DelegateExamResult) between Delegate (parent) ExamResult (child)
        //[Authorize(Roles = "Admin,ListDelegateExamResult")]
		[RolesRequired("Admin","ListDelegateExamResult")]  
        public ActionResult GetDelegateExamResult(int id, bool selected = false) 
        {
            var models = service.GetAllForDelegateExamResult(id);
            ViewBag.ToolButtons = "VP"; // View Pick 
            ViewBag.PickState = selected;
            return View("DelegateList", models);
        }
        // Add a relationship (DelegateExamResult) between Delegate (parent) ExamResult (child)
        //[Authorize(Roles = "Admin,SaveDelegateExamResult")]
		[RolesRequired("Admin","SaveDelegateExamResult")]  
        public ActionResult AddDelegateExamResult(int id)
        {
            ViewBag.Readonly = false;
            ViewBag.ShowRelationships = false;
            ViewBag.ModelId = new int?(id);
            return View("Form", new DelegateViewModel());
        }
        // Add a relationship (DelegateExamResult) between Delegate (parent) ExamResult (child)
        [HttpPost]
        //[Authorize(Roles = "Admin,SaveDelegateExamResult")]
		[RolesRequired("Admin","SaveDelegateExamResult")]
        public ActionResult SaveDelegateExamResult(DelegateViewModel model, int modelId)
        {
            var errors = new List<IModelError>();
            model.Id = 0 ; // force a new object regardless
            var result = service.TrySave(model, errors);
            if (result)
            {
                service.AddExamResultToDelegateForDelegateExamResult(model.Id, modelId);
            }
            return Json(new
            {
                Model = model,
                Success = result,
                Errors = errors
            });
        }
        // remove a relationship (DelegateExamResult) between Delegate (parent) ExamResult (child) 
        [HttpPost]
		[RolesRequired("Admin","SaveDelegateExamResult")]       
        public ActionResult UnLinkDelegateExamResult(int modelId , int[] items)
        {
            var result = true;
            try
            {
                items.DefaultIfNull().AsParallel().ToList().ForEach(i => {
					service.RemoveExamResultFromDelegateForDelegateExamResult(modelId, i);					                  
                });
            }
            catch 
            {
				items.DefaultIfNull().AsParallel().ToList().ForEach(i => {                    
					service.AddExamResultToDelegateForDelegateExamResult(modelId, i);  
                });
                result = false;  
            }
                                   
            return Json(new
            {
                Success = result
            });
        }
        // add a relationship (DelegateExamResult) between existing Delegate (parent) ExamResult (child) 
        [HttpPost]
        [RolesRequired("Admin","SaveDelegateExamResult")]  
        public ActionResult LinkDelegateExamResult(int modelId , int[] items)
        {
            var result = true;
            try
            {
                items.DefaultIfNull().AsParallel().ToList().ForEach(i => {
					service.AddExamResultToDelegateForDelegateExamResult(modelId, i);                    
                });
            }
            catch 
            {
				items.DefaultIfNull().AsParallel().ToList().ForEach(i => {                    
					service.RemoveExamResultFromDelegateForDelegateExamResult(modelId, i);
                });
                result = false;  
            }
                                   
            return Json(new
            {
                Success = result
            });
        }
                
        // Supports the many to many relationship (EventDelegate) between Delegate (child) Event (parent)
        [RolesRequired("Admin","ListEventDelegate")]  
        public ActionResult GetEventDelegate(int id) 
        {
            var models = service.GetAllForEventDelegate(id);
            ViewBag.ToolButtons = "VP"; // View Pick 
            ViewBag.PickState = true;
            return View("DelegateList", models);
        }
        // Add a relationship (EventDelegate) between Event (parent) Delegate (child)
        [RolesRequired("Admin","SaveEventDelegate")] 
        public ActionResult AddEventDelegate()
        {
            ViewBag.Readonly = false;
            ViewBag.ShowRelationships = false;


Answer:             return View("Form", new DelegateViewModel());