using System;
using BS.Shared;
using BeWo.Core;

using BS.Shared.DataContracts;

namespace BeWo.ViewModel
{
    public class InvoiceItemVM : AbstractDCMapperVM<InvoiceItemDC>
    {
        #region Constants and Fields

        public static string PropertyName_AmountPerUnit = "AmountPerUnit";

        public static string PropertyName_AmountTotal = "AmountTotal";

        public static string PropertyName_GrossAmountTotal = "GrossAmountTotal";

        public static string PropertyName_ItemDescription = "ItemDescription";

        public static string PropertyName_ItemPeriodEnd = "ItemPeriodEnd";

        public static string PropertyName_ItemPeriodStart = "ItemPeriodStart";

        public static string PropertyName_RateFactor = "RateFactor";

        public static string PropertyName_UnitCount = "UnitCount";

        public static string PropertyName_UnitDescription = "UnitDescription";

        public static string PropertyName_AccountingInterval = "AccountingInterval";

        public static string PropertyName_ReceivedAmount = "ReceivedAmount";

        public static string PropertyName_MaxApprovedUnitCount = "MaxApprovedUnitCount";

        public static string PropertyName_ApprovedPerUnit = "ApprovedPerUnit";

        public static string PropertyName_ApprovalUnit = "ApprovalUnit";

        public static string PropertyName_MaxApprovedAmount = "MaxApprovedAmount";

		public static string PropertyName_Notice = "Notice";

        private decimal? _AmountPerUnit;

        private decimal? _AmountTotal;

        private decimal? _GrossAmountTotal;

        private decimal _ReceivedAmount;

        private decimal? _MaxApprovedAmount;

        private decimal? _MaxApprovedUnitCount;

        private decimal? _ApprovedPerUnit;

        private AccountingIntervalType? _ApprovalUnit;

        private string _ItemDescription;

        private DateTime? _ItemPeriodEnd;

        private DateTime? _ItemPeriodStart;

        private decimal? _RateFactor;

        private decimal _UnitCount;

        private string _UnitDescription;

		private string _Notice;

        private AccountingIntervalType? _AccountingInterval;

        #endregion

        #region Constructors and Destructors

        public InvoiceItemVM(InvoiceItemDC pDC) : base(pDC, pDC.InvoiceItemOid == null) {}

        #endregion

        #region Properties

        public AccountingIntervalType? AccountingInterval
        {
            get { return this._AccountingInterval; }

            set
            {
                if (this.AreDifferent(this._AccountingInterval, value))
                {
                    this._AccountingInterval = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.AccountingInterval, value), PropertyName_AccountingInterval);
                    this.FirePropertyChanged(PropertyName_AccountingInterval);
                }
            }
        }

        public decimal? AmountPerUnit
        {
            get
            {
                return this._AmountPerUnit;
            }

            set
            {
                if (this.AreDifferent(this._AmountPerUnit, value))
                {
                    this._AmountPerUnit = value;
                    if (this._AmountPerUnit != null)
                    {
                        this.AmountTotal = this._AmountPerUnit.Value * this.UnitCount;
                    }
                    else
                    {
                        this.AmountTotal = 0;
                    }

                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.AmountPerUnit, value), PropertyName_AmountPerUnit);
                    this.FirePropertyChanged(PropertyName_AmountPerUnit);
                }
            }
        }

        public decimal? AmountTotal
        {
            get
            {
                return this._AmountTotal;
            }

            set
            {
                if (this.AreDifferent(this._AmountTotal, value))
                {
                    this._AmountTotal = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.AmountTotal, value), PropertyName_AmountTotal);
                    this.FirePropertyChanged(PropertyName_AmountTotal);
                }
            }
        }

        public decimal? GrossAmountTotal
        {
            get
            {
                return this._GrossAmountTotal;
            }

            set
            {
                if (this.AreDifferent(this._GrossAmountTotal, value))
                {
                    this._GrossAmountTotal = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.GrossAmountTotal, value), PropertyName_GrossAmountTotal);
                    this.FirePropertyChanged(PropertyName_GrossAmountTotal);
                }
            }
        }

        public decimal GrossAmountTotalUntilMax
        {
            get
            {
                decimal amount = GrossAmountTotal ?? 0;
                if (MaxApprovedAmount.HasValue && MaxApprovedAmount.Value > 0 && amount > MaxApprovedAmount.Value)
                    amount = MaxApprovedAmount.Value;
                return amount;

            }
        }

        public decimal ReceivedAmount
        {
            get
            {
                return this._ReceivedAmount;
            }

            set
            {
                if (this.AreDifferent(this._ReceivedAmount, value))
                {
                    this._ReceivedAmount = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ReceivedAmount, value), PropertyName_ReceivedAmount);
                    this.FirePropertyChanged(PropertyName_ReceivedAmount);
                }
            }
        }

        public decimal? MaxApprovedAmount
        {
            get
            {
                return this._MaxApprovedAmount;
            }

            set
            {
                if (this.AreDifferent(this._MaxApprovedAmount, value))
                {
                    this._MaxApprovedAmount = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.MaxApprovedAmount, value), PropertyName_MaxApprovedAmount);
                    this.FirePropertyChanged(PropertyName_MaxApprovedAmount);
                }
            }
        }

        public decimal? MaxApprovedUnitCount
        {
            get
            {
                return this._MaxApprovedUnitCount;
            }

            set
            {
                if (this.AreDifferent(this._MaxApprovedUnitCount, value))
                {
                    this._MaxApprovedUnitCount = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.MaxApprovedUnitCount, value), PropertyName_MaxApprovedUnitCount);
                    this.FirePropertyChanged(PropertyName_MaxApprovedUnitCount);
                }
            }
        }

        public decimal? ApprovedPerUnit
        {
            get
            {
                return this._ApprovedPerUnit;
            }

            set
            {
                if (this.AreDifferent(this._ApprovedPerUnit, value))
                {
                    this._ApprovedPerUnit = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ApprovedPerUnit, value), PropertyName_ApprovedPerUnit);
                    this.FirePropertyChanged(PropertyName_ApprovedPerUnit);
                }
            }
        }

        public AccountingIntervalType? ApprovalUnit
        {
            get
            {
                return this._ApprovalUnit;
            }

            set
            {
                if (this.AreDifferent(this._ApprovalUnit, value))
                {
                    this._ApprovalUnit = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ApprovalUnit, value), PropertyName_ApprovalUnit);
                    this.FirePropertyChanged(PropertyName_ApprovalUnit);
                }
            }
        }

        public string ItemDescription
        {
            get
            {
                return this._ItemDescription;
            }

            set
            {
                if (this.AreDifferent(this._ItemDescription, value))
                {
                    this._ItemDescription = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ItemDescription, value), PropertyName_ItemDescription);
                    this.FirePropertyChanged(PropertyName_ItemDescription);
                }
            }
        }

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

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

        public DateTime? ItemPeriodEnd
        {
            get
            {
                return this._ItemPeriodEnd;
            }

            set
            {
                if (this.AreDifferent(this._ItemPeriodEnd, value))
                {
                    this._ItemPeriodEnd = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ItemPeriodEnd, value), PropertyName_ItemPeriodEnd);
                    this.FirePropertyChanged(PropertyName_ItemPeriodEnd);
                }
            }
        }

        public DateTime? ItemPeriodStart
        {
            get
            {
                return this._ItemPeriodStart;
            }

            set
            {
                if (this.AreDifferent(this._ItemPeriodStart, value))
                {
                    this._ItemPeriodStart = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.ItemPeriodStart, value), PropertyName_ItemPeriodStart);
                    this.FirePropertyChanged(PropertyName_ItemPeriodStart);
                }
            }
        }

        public decimal? RateFactor
        {
            get
            {
                return this._RateFactor;
            }

            set
            {
                if (this.AreDifferent(this._RateFactor, value))
                {
                    this._RateFactor = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.RateFactor, value), PropertyName_RateFactor);
                    this.FirePropertyChanged(PropertyName_RateFactor);
                }
            }
        }

        public decimal UnitCount
        {
            get
            {
                return BeWoWpfUtils.GetDecimalValueWithMaxDecimal(this._UnitCount, -1) ?? 0m;
            }

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

                    if (this.AmountPerUnit != null)
                    {
                        this.AmountTotal = this.AmountPerUnit.Value * this.UnitCount;
                    }
                    else
                    {
                        this.AmountTotal = 0;
                    }

                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.UnitCount, value), PropertyName_UnitCount);
                    this.FirePropertyChanged(PropertyName_UnitCount);
                }
            }
        }

        public decimal UnitCountUntilMax
        {
            get
            {
                decimal count = UnitCount;
                if (MaxApprovedUnitCount.HasValue && count > MaxApprovedUnitCount.Value)
                    count = MaxApprovedUnitCount.Value;
                return Math.Round(count, 2, MidpointRounding.AwayFromZero);

            }
        }

        public string UnitDescription
        {
            get
            {
                return this._UnitDescription;
            }

            set
            {
                if (this.AreDifferent(this._UnitDescription, value))
                {
                    this._UnitDescription = value;
                    this.StoreDirtyInformation(this.AreDifferent(this.DataContract.UnitDescription, value), PropertyName_UnitDescription);
                    this.FirePropertyChanged(PropertyName_UnitDescription);
                }
            }
        }

        #endregion

        #region Methods

        protected override void InitByDataContract(InvoiceItemDC pDataContract)
        {
            this._AmountTotal = pDataContract.AmountTotal;
            this._AmountPerUnit = pDataContract.AmountPerUnit;
            this._UnitDescription = pDataContract.UnitDescription;
            this._UnitCount = pDataContract.UnitCount ?? 0m;
            this._ItemDescription = pDataContract.ItemDescription;
            this._ItemPeriodEnd = pDataContract.ItemPeriodEnd;
            this._ItemPeriodStart = pDataContract.ItemPeriodStart;
            this._GrossAmountTotal = pDataContract.GrossAmountTotal;
            this._RateFactor = pDataContract.RateFactor;
            this._AccountingInterval = pDataContract.AccountingInterval;
            this._ReceivedAmount = pDataContract.ReceivedAmount;
            this._MaxApprovedUnitCount = pDataContract.MaxApprovedUnitCount;
            this._ApprovedPerUnit = pDataContract.ApprovedPerUnit;
            this.ApprovalUnit = pDataContract.ApprovalUnit;
            this._MaxApprovedAmount = pDataContract.MaxApprovedAmount;
	        this._Notice = pDataContract.Notice;
        }

        protected override InvoiceItemDC MapToDataContract(InvoiceItemDC pDataContract, bool doCommit)
        {
            pDataContract.AmountTotal = this._AmountTotal;
            pDataContract.AmountPerUnit = this._AmountPerUnit;
            pDataContract.UnitDescription = this._UnitDescription;
            pDataContract.UnitCount = this._UnitCount;
            pDataContract.ItemDescription = this._ItemDescription;
            pDataContract.ItemPeriodEnd = this._ItemPeriodEnd;
            pDataContract.ItemPeriodStart = this._ItemPeriodStart;
            pDataContract.RateFactor = this._RateFactor;
            pDataContract.GrossAmountTotal = this._GrossAmountTotal;
            pDataContract.AccountingInterval = this._AccountingInterval;
            pDataContract.ReceivedAmount = this._ReceivedAmount;
            pDataContract.MaxApprovedAmount = this._MaxApprovedAmount;
            pDataContract.MaxApprovedUnitCount = this._MaxApprovedUnitCount;
            pDataContract.ApprovedPerUnit = this._ApprovedPerUnit;
            pDataContract.ApprovalUnit = this._ApprovalUnit;
	        pDataContract.Notice = this._Notice;

            return pDataContract;
        }

        #endregion
    }
}