using System;
using System.ComponentModel;
using System.Linq;

using BeWo.Validation;

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

namespace BeWo.ViewModel
{
    public class TaskVM : AbstractDCMapperVM<TaskDC>
    {
        public static string PropertyName_CompletedDate = "CompletedDate";

        public static string PropertyName_CompletedNotice = "CompletedNotice";

        public static string PropertyName_Description = "Description";

        public static string PropertyName_DueDate = "DueDate";

        public static string PropertyName_DueTime = "DueTime";

        public static string PropertyName_Employees = "Employees";

        public static string PropertyName_Title = "Title";

        private DateTime? _CompletedDate;

        private string _CompletedNotice;

        private string _Description;

        private DateTime? _DueDate;

        private DateTime? _DueTime;

        private BindingList<CompactEmployeeDC> _Employees;

        private string _Title;

        public TaskVM(TaskDC pDC) : base(pDC, !pDC.TaskOid.HasValue)
        {
        }

        public DateTime? CompletedDate
        {
            get { return this._CompletedDate; }

            set
            {
                if (this.AreDifferent(this._CompletedDate, value))
                {
                    this._CompletedDate = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.CompletedDate, value), PropertyName_CompletedDate);
                    this.FirePropertyChanged(PropertyName_CompletedDate);
                }
            }
        }

        public string CompletedNotice
        {
            get { return this._CompletedNotice; }

            set
            {
                if (this.AreDifferent(this._CompletedNotice, value))
                {
                    this._CompletedNotice = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.CompletedNotice, value), PropertyName_CompletedNotice);
                    this.FirePropertyChanged(PropertyName_CompletedNotice);
                }
            }
        }

        public string Description
        {
            get { return this._Description; }

            set
            {
                if (this.AreDifferent(this._Description, value))
                {
                    this._Description = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.Description, value), PropertyName_Description);
                    this.FirePropertyChanged(PropertyName_Description);
                }
            }
        }

        public DateTime? DueDate
        {
            get { return this._DueDate; }

            set
            {
                if (this.AreDifferent(this._DueDate, value))
                {
                    this._DueDate = value;
                    this.StoreDirtyInformation(true, PropertyName_DueDate);
                    this.FirePropertyChanged(PropertyName_DueDate);
                }
            }
        }

        public DateTime? DueTime
        {
            get { return this._DueTime; }

            set
            {
                if (this.AreDifferent(this._DueTime, value))
                {
                    this._DueTime = value;
                    this.StoreDirtyInformation(true, PropertyName_DueTime);
                    this.FirePropertyChanged(PropertyName_DueTime);
                }
            }
        }

        public BindingList<CompactEmployeeDC> Employees
        {
            get { return this._Employees; }

            set
            {
                if (this.AreDifferent(this._Employees, value))
                {
                    this._Employees = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.Employees, value), PropertyName_Employees);
                    this.FirePropertyChanged(PropertyName_Employees);
                }
            }
        }

        public string EmployeesString
        {
            get { return this._Employees != null ? string.Join(" | ", this._Employees.OrderBy(i => i.ToString()).Select(v => v.ToString()).ToArray()) : string.Empty; }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public string Title
        {
            get { return this._Title; }

            set
            {
                if (this.AreDifferent(this._Title, value))
                {
                    this._Title = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.Title, value), PropertyName_Title);
                    this.FirePropertyChanged(PropertyName_Title);
                }
            }
        }

        protected override void InitByDataContract(TaskDC pDataContract)
        {
            if (pDataContract.Employees != null)
            {
                this._Employees = new BindingList<CompactEmployeeDC>(pDataContract.Employees);
            }
            else
            {
                this._Employees = new BindingList<CompactEmployeeDC>();
            }

            if (pDataContract.DueDate.HasValue)
            {
                this._DueDate = pDataContract.DueDate.Value.Date;
                this._DueTime = pDataContract.DueDate;
            }

            this._CompletedNotice = pDataContract.CompletedNotice;
            this._CompletedDate = pDataContract.CompletedDate;
            this._Title = pDataContract.Title;
            this._Description = pDataContract.Description;

            this._Employees.ListChanged += (s, e) => this.StoreDirtyInformation(true, PropertyName_Employees);
        }

        protected override TaskDC MapToDataContract(TaskDC pDataContract, bool doCommit)
        {
            pDataContract.DueDate = this._DueDate;

            if (this._DueDate.HasValue && this._DueTime.HasValue)
            {
                pDataContract.DueDate = new DateTime(this._DueDate.Value.Year, this._DueDate.Value.Month, this._DueDate.Value.Day, this._DueTime.Value.Hour, this._DueTime.Value.Minute, 0);
            }

            pDataContract.CompletedNotice = this._CompletedNotice;
            pDataContract.CompletedDate = this._CompletedDate;
            pDataContract.Title = this._Title;
            pDataContract.Description = this._Description;
            pDataContract.Employees = this._Employees.ToList();
            return pDataContract;
        }
    }
}