using System.Collections.ObjectModel;
using System.Linq;

using BeWo.Validation;

using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;

namespace BeWo.ViewModel
{
    public class TeamVM : AbstractDCMapperVM<TeamDC>
    {
        public static string PropertyName_Leader = "Leader";

        public static string PropertyName_LeaderString = "LeaderString";

        public static string PropertyName_Member = "Member";

        public static string PropertyName_Name = "Name";

        public static string PropertyName_Notice = "Notice";

        private CompactEmployeeDC _Leader;

        private ObservableCollection<CompactEmployeeDC> _Member;

        private string _Name;

        private string _Notice;

        public TeamVM(TeamDC pDataContract) : base(pDataContract, pDataContract.TeamOid == null)
        {
        }

        public CompactEmployeeDC Leader
        {
            get { return this._Leader; }

            set
            {
                if (this.AreDifferent(this._Leader, value))
                {
                    this._Leader = value;

                    bool lSame = (this.DataContract.Leader == null && value == null) || (this.DataContract.Leader != null && value != null && this.DataContract.Leader.EmployeeOid == value.EmployeeOid);
                    this.StoreDirtyInformation(!lSame, PropertyName_Leader);
                    this.FirePropertyChanged(PropertyName_Leader);
                    this.FirePropertyChanged(PropertyName_LeaderString);
                }
            }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public string LeaderString
        {
            get { return this._Leader.ToStringNullCheck(); } // Validation Workaround
            set { }
        }

        public ObservableCollection<CompactEmployeeDC> Member
        {
            get { return this._Member; }

            set
            {
                if (this.AreDifferent(this._Member, value))
                {
                    this._Member = value;
                    this.FirePropertyChanged(PropertyName_Member);
                }
            }
        }

        [ValidationAttribute(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public string Name
        {
            get { return this._Name; }

            set
            {
                if (this.AreDifferent(this._Name, value))
                {
                    this._Name = value;
                    this.StoreDirtyInformation(this.DataContract.Name != value, PropertyName_Name);
                    this.FirePropertyChanged(PropertyName_Name);
                }
            }
        }

        public string Notice
        {
            get { return this._Notice; }

            set
            {
                if (this.AreDifferent(this._Notice, value))
                {
                    this._Notice = value;
                    this.StoreDirtyInformation(this.DataContract.Notice != value, PropertyName_Notice);
                    this.FirePropertyChanged(PropertyName_Notice);
                }
            }
        }

        protected override void InitByDataContract(TeamDC pDataContract)
        {
            this._Member = new ObservableCollection<CompactEmployeeDC>();

            if (!this.IsNew)
            {
                this._Name = pDataContract.Name;
                this._Notice = pDataContract.Notice;
                this._Leader = pDataContract.Leader;

                if (pDataContract.Member != null)
                {
                    this._Member.AddRange(pDataContract.Member.OrderBy(m => string.Format("{0},{1}", m.LastName, m.FirstName)));
                }
            }

            this._Member.CollectionChanged += (s, e) => this.StoreDirtyInformation(!pDataContract.Member.ContainsSameItemsAs(this._Member), PropertyName_Member);
        }

        protected override TeamDC MapToDataContract(TeamDC pDataContract, bool doCommit)
        {
            pDataContract.Leader = this._Leader;
            pDataContract.Name = this._Name;
            pDataContract.Notice = this._Notice;
            pDataContract.Member = this._Member.ToList();

            return pDataContract;
        }
    }
}