using System.Linq;

using BeWo.Data.Access;
using BeWo.Data.Entities;

using BS.Shared.DataContracts;

namespace BeWo.Service.DCEntityMapper
{
    public class BookingSequenceDC_ResourceBookingSequence : AbstractIDCEntityMapper<ResourceBookingSequence, BookingSequenceDC>
    {
        public override BookingSequenceDC MergeWithDC(ResourceBookingSequence pEntity, BookingSequenceDC pDataContract)
        {
            pDataContract.Frequency = pEntity.FrequencyType;
            pDataContract.RepeatInterval = pEntity.RepeatInterval;
            pDataContract.SequenceEnd = pEntity.SequenceEnd.Value;
            pDataContract.Notice = pEntity.Notice;

            pDataContract.SequenceOid = pEntity.Oid;
            pDataContract.SequenceVersion = pEntity.Version;

            pDataContract.Resource = MapperFactory.ResourceDC_Resource.MapToNewDC(pEntity.Resource);

            pDataContract.RootBooking = MapperFactory.ResourceBookingDC_ResourceBooking.MapToNewDC(pEntity.Details.Single(b => b.SequencePosition == 0));
            pDataContract.ChangedElements = MapperFactory.ResourceBookingDC_ResourceBooking.MapToNewDCs(pEntity.Details.Where(b => b.SequencePosition > 0).ToList());

            if (pEntity.Employee != null)
            {
                pDataContract.Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(pEntity.Employee);
            }

            return pDataContract;
        }

        public override ResourceBookingSequence MergeWithEntity(BookingSequenceDC pDataContract, ResourceBookingSequence pEntity)
        {
            this.ConcurrencyCheck(pDataContract.SequenceVersion, pEntity);

            var lRootBooking = pEntity.Details.SingleOrDefault(b => b.SequencePosition == 0);
            if (lRootBooking != null)
            {
                pEntity.Details.Remove(lRootBooking);
            }

            MapperFactory.ResourceBookingDC_ResourceBooking.MergeWithEntitys(pDataContract.ChangedElements, pEntity.Details);

            if (lRootBooking != null)
            {
                pEntity.Details.Add(MapperFactory.ResourceBookingDC_ResourceBooking.MergeWithEntity(pDataContract.RootBooking, lRootBooking));
            }
            else
            {
                pEntity.Details.Add(MapperFactory.ResourceBookingDC_ResourceBooking.MapToNewEntity(pDataContract.RootBooking));
            }

            if (pEntity.Resource == null || pEntity.Resource.Oid != pDataContract.Resource.ResourceOid)
            {
                pEntity.Resource = DAOFactory.GenericDAO.LoadByID<Resource>(pDataContract.Resource.ResourceOid.Value);
            }

            if (pDataContract.Employee != null)
            {
                pEntity.Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewEntity(pDataContract.Employee);
            }

            this.ConcurrencyCheck(pDataContract.Resource.ResourceVersion, pEntity.Resource);

            pEntity.FrequencyType = pDataContract.Frequency;
            pEntity.RepeatInterval = pDataContract.RepeatInterval;
            pEntity.SequenceEnd = pDataContract.SequenceEnd;
            pEntity.Notice = pDataContract.Notice;

            return pEntity;
        }

        protected override bool AreDCAndEntityEqual(BookingSequenceDC pDC, ResourceBookingSequence pEntity)
        {
            if (pDC.SequenceOid == null)
            {
                return false;
            }

            return pDC.SequenceOid == pEntity.Oid;
        }
    }
}