/// <summary>
        /// There is only one template pattern at the moment - Standard template
        /// </summary>
        /// <param name="anEvent"></param>
        /// <param name="customer"></param>
        /// <param name="documentType"></param>
        /// <param name="booking"></param>
        /// <param name="bes"></param>
        public EventCommandSendEmail(Event anEvent, int EmailTemplateId, Customer customer, Booking booking = null, BookingExtraSelection bes = null)
        {
            this.Event = anEvent;
            this.customer = customer;           
            this.booking = booking;
            this.bes = bes;
            this.EmailTemplateId = EmailTemplateId;

        }
 public EventCommandCreateDocument(Event anEvent, Customer customer, PRCDocument.PRCDocumentType documentType, Booking booking = null, BookingExtraSelection bes = null)
 {
     //inject properties
     this.Event = anEvent;
     this.customer = customer;
     this.documentType = documentType;
     this.booking = booking;
     this.bes = bes;
 }
        //PRIVATE METHODS

        /* private CreateEmailBody()
         {
            

         }*/

        /////////MAIN PUBLIC EXPOSED METHODS



        //takes a type, creates an Event
        public Event CreateEmailEvent(EventType eventType/*EmailTypeToCreate*/)
        {
            var theEvent = new Event
            {



            };

            return theEvent;
        }
        //passes back a fully formed document
        public Event CreateDocumentEvent(EventType eventType, List<IEventCommand> commandsToRun)
        {
            //new it up and add the commands
            var theEvent = new Event
            {



            };

            return theEvent;
        }
        //NOT PROCESS TYPE SPECIFIC!!
        public Event CreateEvent(EventType type)
        {
              //set up standard filds
            Event eve = new Event
            {
                WhenCreated = DateTime.Now,
                EventTypeID =  type.EventTypeID,
            };


        
            return eve;

        }
        /// <summary>
        /// Logs
        /// </summary>
        /// <returns></returns>
        public int LogEventAndCommandandCommandResult(Event anEvent, EventCommand eventCommand, EventCommandResult result)
        {
            anEvent.EventCommands = null;
            //can't log a command without an event
            if (LogEvent(anEvent).Equals(0))
            {
                _commandLogger.Log(anEvent.EventID, eventCommand);
                return 0;
            }

            return -1;


        }
        public int LogEvent(Event eventToLog)
        {

            try
            {
                _dbContext.Events.Add(eventToLog);
                _dbContext.SaveChanges();
                return 0;
            }
            catch (Exception ex)
            {
                return -1;
                //log error

                //contact someone
            }


        }
        Event LoadEventCommandToExecute(Event theEvent)
        {
            EventType type = context.EventTypes.Where(x => x.EventTypeID == theEvent.EventTypeID).FirstOrDefault();

            //depending on subtype, need to get docs, emails, add reminder, whatever we need to do, 
            //and add it to commands to be executed

          /*  switch (type.EventSubTypeID)
            {
                    //it's an email, assign the email command
                case 2:
                    theEvent.EventCommands.Add(new EventCommandSendEmail());
                    break;
                case 3:
                    theEvent.EventCommands.Add(new EventCommandSendEmailWithDocAttachment());
                    break;
                default:
                    break;
            }*/



            return theEvent;
        }
        public void TestEventCommandAndLogging()
        {
            var db = new PortugalVillasContext();

            var anEvent = new Event();
            anEvent.WhenCreated = DateTime.Now;



            anEvent.Booking = db.Bookings.Find(4);

            long customerID = anEvent.Booking.CustomerID;

            //get other vars
            Customer aCustomer = db.Customers.Where(x => x.CustomerID == customerID).FirstOrDefault();


            EventCommandCreateDocument docEventCommand = new EventCommandCreateDocument(anEvent, aCustomer, PRCDocument.PRCDocumentType.UK_AirportTransfer, anEvent.Booking);

            anEvent.EventCommands.Add(docEventCommand);

            var result = new EventCommandResult();
            foreach (var command in anEvent.EventCommands)
            {
                result = command.ExecuteCommand();

            }

            //all done, do the logging

            var eventLogger = new EventLogger(db, new CommandLogger(db));

            eventLogger.LogEventAndCommandandCommandResult(anEvent, docEventCommand,
                result);

        }
        public void TestEventLogging()
        {
            var an = new Event();
            an.WhenCreated = DateTime.Now;
            an.EventTypeID = 3;


            var log = new EventLogger(new PortugalVillasContext());
            log.LogEvent(an);

        }
        public void TestFullDocumentGenerateStack()
        {

            var db = new PortugalVillasContext();

            //Test WITH PARENT

            //TEST WITH BOOKING
            Booking booking = db.Bookings.Where(x => x.BookingID.Equals(4)).FirstOrDefault();
            booking.PropertyID = 221;
            /*           Booking booking = null;*/



            //TEST WITH CUSTOMER
            Customer aCustomer = db.Customers.Where(x => x.CustomerID == 1).FirstOrDefault();
            //TEST WITH BES
            var bes = db.BookingExtraSelections.Where(x => x.BookingExtraSelectionID == 3).First();
            bes.BookingExtraID = 1;

            //set up vars


            var type = PRCDocument.PRCDocumentType.UK_WineTasting;




            //create event  - need to give it type thus name
            var anEvent = new Event();
            anEvent.Documents = new List<Document>();
            //TEST ADD ID - PLEASE REMOVE
            anEvent.EventID = 2;
            //END TEST CODE

            anEvent.WhenCreated = DateTime.Now;
            var commandsAndResultsToLog = new List<EventCommand>();


            //create correct command
            //doc
            //email out with doc

            EventCommandCreateDocument createDocCommand;
            EventCommandSendEmail sendEmail;
            //HOW DO WE DECIDE WHAT TYPE OF EVENT WE WANT??? depends on type??

            if (booking != null)
            {
                createDocCommand = new EventCommandCreateDocument(anEvent, aCustomer, type, booking);
                /* sendEmail = new EventCommandSendEmail(anEvent, aCustomer, booking);*/

            }
            else
            {
                createDocCommand = new EventCommandCreateDocument(anEvent, aCustomer, type, null, bes);
                /*/sendEmail = new EventCommandSendEmail(anEvent, aCustomer, null, bes);*/
            }



            //create all commands
            anEvent.EventCommands.Add(createDocCommand);
            /*       anEvent.EventCommands.Add(sendEmail);*/


            //create document using executes
            var result = new EventCommandResult();
            foreach (var command in anEvent.EventCommands)
            {
                command.EventCommandResults.Add(command.ExecuteCommand());
                commandsAndResultsToLog.Add(command);
            }

            //render

            //save to DB with all correct commands etc

            var EventCommandLogger = new CommandLogger(db);
            var eventLogger = new EventLogger(db, EventCommandLogger);

            //save event
            eventLogger.LogEvent(anEvent);
            //save eventcoomand and result


            foreach (var commandAndResult in commandsAndResultsToLog)
            {
                EventCommandLogger.Log(anEvent.EventID, commandAndResult);
            }

            //save document generated

            //NEED TO ADD CORRECT PARAMS (which are what??)

            //if there's any docs, write them to the DB
            foreach (var doc in anEvent.Documents)
            {
                doc.EventID = anEvent.EventID;
                doc.DocumentDescription = type.ToString();
                doc.EmailTo = aCustomer.EmailAddress;
                doc.CustomerID = aCustomer.CustomerID;

                db.Documents.Add(doc);
                db.SaveChanges();
            }





        }
 public ActionResult Edit(Event anEvent)
 {
     if (ModelState.IsValid)
     {
         db.Entry(anEvent).State = EntityState.Modified;
         db.SaveChanges();
         //              return RedirectToAction("Index");
     }
     ViewBag.BookingID = new SelectList(db.Bookings, "BookingID", "BookingPRCReference", anEvent.BookingID);
     ViewBag.BookingExtraSelectionID = new SelectList(db.BookingExtraSelections, "BookingExtraSelectionID", "Test", anEvent.BookingExtraSelectionID);
     ViewBag.EventTypeID = new SelectList(db.EventTypes, "EventTypeID", "EventTypeName", anEvent.EventTypeID);
     return View(anEvent);
 }