using System;
using System.Collections.Generic;

namespace BeWo.ViewModel
{
	public abstract class AbstractDCMapperVM<DCType> : AbstractBaseVM where DCType : new()
	{
		#region Constants and Fields

		private readonly List<string> _DirtyProps = new List<string>();

		private bool? _IsNew;

		#endregion

		#region Constructors and Destructors

		public AbstractDCMapperVM() { }

		public AbstractDCMapperVM(DCType pDataContract, bool pIsNew)
		{
			_IsNew = pIsNew;
			DataContract = pDataContract;
			InitByDataContract(DataContract);
		}

		#endregion

		#region Properties

		public override bool IsDirty
		{
			get { return _DirtyProps.Count > 0; }
		}

		public bool IsNew
		{
			get
			{
				if (_IsNew == null)
				{
					throw new NotImplementedException();
				}

				return _IsNew.Value;
			}

			set { _IsNew = value; }
		}

		internal DCType DataContract { get; set; }

		#endregion

		#region Public Methods

		public DCType CommitToDataContract()
		{
			return MapToDataContract(DataContract, true);
		}

		public DCType CopyToEmptyDataContract()
		{
			return MapToDataContract(new DCType(), false);
		}

		public override void SetDirty(bool newDirty)
		{
			if (!newDirty)
			{
				_DirtyProps.Clear();
			}
		}

		#endregion

		#region Methods

		protected abstract void InitByDataContract(DCType pDataContract);

		protected abstract DCType MapToDataContract(DCType pDataContract, bool doCommit);

		protected void StoreDirtyInformation(bool pDirty, string pPropName)
		{
			if (_DirtyProps.Contains(pPropName) && !pDirty)
			{
				_DirtyProps.Remove(pPropName);
			}
			else if (!_DirtyProps.Contains(pPropName) && pDirty)
			{
				_DirtyProps.Add(pPropName);
			}
		}

		#endregion
	}
}