using System;
using System.Collections.Generic;
using System.Linq;

using BeWo.Data.Entities;
using BeWo.Service.Core;

using BS.Shared.DataContracts;

using Utils = BS.Shared.Core.Utils;

namespace BeWo.Service.DCEntityMapper
{
    public class VarFieldDC_VarFieldDefMapper
    {
        public List<VarFieldDC> VarFieldMapToDCs(IList<VarFieldDef> defs, IList<VarFieldValue> values)
        {
            List<VarFieldDC> result = new List<VarFieldDC>();

            foreach (var iDef in defs)
            {
                var dc = new VarFieldDC();

                dc.ControlType = iDef.ControlType;
                dc.DecimalPlaces = iDef.DecimalPlaces;
                dc.Group = iDef.Group;
                dc.Label = iDef.Label;
                if (!string.IsNullOrEmpty(iDef.PossibleItems))
                {
                    dc.PossibleItems = iDef.PossibleItems.Split(';').ToList();
                }

                dc.XCoordinate = iDef.XCoordinate;
                dc.YCoordinate = iDef.YCoordinate;
                dc.VarFieldDefOid = iDef.Oid.Value;
                dc.Height = iDef.Height;
                dc.Width = iDef.Width;
                dc.ColumnSpan = iDef.ColumnSpan;
                dc.RowSpan = iDef.RowSpan;

                if (values != null)
                {
                    var value = values.SingleOrDefault(i => i.VarFieldDefOid.Equals(iDef.Oid));
                    if (value != null)
                    {
                        dc.VarFieldValueOid = value.Oid;
                        dc.VarFieldValueVersion = value.Version;

                        Type type = Type.GetType(value.TypeName);
                        dc.VarFieldValue = Utils.XMLDeserializeFromString(value.SerializedValue, type);
                    }
                }

                result.Add(dc);
            }

            return result;
        }

        public IList<VarFieldValue> VarFieldMergeToEntity(IList<VarFieldValue> values, List<VarFieldDC> dcs, BeWoEntityBase entity)
        {
            if (dcs != null)
            {
                foreach (var idc in dcs)
                {
                    var value = values.SingleOrDefault(v => idc.VarFieldDefOid.Equals(v.VarFieldDefOid));

                    if (value != null)
                    {
                        ServiceLogic.ConcurrencyCheck(idc.VarFieldValueVersion, value);
                    }

                    if (idc.VarFieldValue == null && value != null)
                    {
                        values.Remove(value);
                    }

                    if (idc.VarFieldValue != null)
                    {
                        var typeName = idc.VarFieldValue.GetType().FullName;
                        var serializedValue = Utils.XMLSerializeToString(idc.VarFieldValue);

                        if (value == null)
                        {
                            values.Add(new VarFieldValue { SerializedValue = serializedValue, TypeName = typeName, VarFieldDefOid = idc.VarFieldDefOid, ObjectOid = entity.Oid, ObjectTid = entity.Tid });
                        }
                        else if (!typeName.Equals(value.TypeName) || !serializedValue.Equals(value.SerializedValue))
                        {
                            value.SerializedValue = serializedValue;
                            value.TypeName = typeName;
                        }
                    }
                }
            }

            return values;
        }
    }
}