using System;
using System.Runtime.Serialization;
using TimeScheduler.Common;
using TimeScheduler.Model;

namespace TimeScheduler.Domain.Impl
{
  /// <summary>Beinhaltet den Datenbestand eines Zeitelementes</summary>
  /// <remarks>
  /// <see cref="ISerializable"/> muss implementiert werden, damit die Daten über den BinarFormater serialisiert werden können.
  /// Für den XmlSerializer müsste die Klasse auf Public gestellt werden, was nicht immer gewünscht ist
  /// </remarks>
  [Serializable]
  public class TimeItem : NotifyableObject, ITimeItem//, ISerializable
  {
    #region Konstruktion
    /// <summary>Standard-Konstruktor</summary>
    public TimeItem() { key_ = -1; From = DateTime.Now.Date; Till = From; }

    /// <summary>Konstruktor</summary>
    /// <param name="description">Beschreibung</param>
    /// <param name="from">Von</param>
    /// <param name="till">Bis</param>
    /// <param name="costUnit">Kostenstelle</param>
    /// <param name="itemType">Elementtyp</param>
    /// <param name="key">Schlüssel</param>
    public TimeItem(string description, DateTime from, DateTime till, int costUnit, TimeItemType itemType, int? key = null) : this()
    {
      description_ = description;
      from_ = from;
      till_ = till;
      costUnit_ = costUnit;
      itemType_ = itemType;
      if (key.HasValue)
        key_ = key.Value;
    }

    /// <summary>Kopier-Konstruktor</summary>
    /// <param name="rhs">Element von dem kopiert wird</param>
    public TimeItem(ITimeItem rhs) { Copy(rhs); Key = rhs.Key; }
    #endregion

    //#region ISerializable
    //public TimeItem(SerializationInfo info, StreamingContext context)
    //{
    //  Description = (string)info.GetValue("Description", typeof(string));
    //}
    //public void GetObjectData(SerializationInfo info, StreamingContext context)
    //{
    //  info.AddValue("Description", Description, typeof(string));
    //}
    //#endregion

    #region Methoden
    /// <summary>Kopiert die Werte der Eigenschaften auf diese Objekt, ohney Key</summary>
    /// <param name="rhs">Objkt von em kopiert werden soll</param>
    public void Copy(ITimeItem rhs)
    {
      Description = rhs.Description;
      From = rhs.From;
      Till = rhs.Till;
      CostUnit = rhs.CostUnit;
      ItemType = rhs.ItemType;
    }
    #endregion

    #region ITimeItem (Eigenschaften nicht implizit implementieren, sonst funktioniert das Binden nicht)
    private int key_;
    /// <inheritdoc/>
    public int Key { get { return key_; } set { SetField(ref key_, value); } }

    private string description_;
    /// <inheritdoc/>
    public string Description { get { return description_; } set { SetField(ref description_, value); } }

    private DateTime from_;
    /// <inheritdoc/>
    public DateTime From
    {
      get { return from_; }
      set
      {
        if (SetField(ref from_, value.Subtract(TimeSpan.FromMinutes(value.Minute % 15))))
          if (From > Till)
            Till = From;
      }
    }

    private DateTime till_;
    /// <inheritdoc/>
    public DateTime Till
    {
      get { return till_; }
      set
      {
        if (SetField(ref till_, value.Subtract(TimeSpan.FromMinutes(value.Minute % 15))))
          if (Till < From)
            From = Till;
      }
    }

    private int costUnit_;
    /// <inheritdoc/>
    public int CostUnit { get { return costUnit_; } set { SetField(ref costUnit_, value); } }

    private TimeItemType itemType_;
    /// <inheritdoc/>
    public TimeItemType ItemType { get { return itemType_; } set { SetField(ref itemType_, value); } }

    private bool isCurrentItem_;
    /// <inheritdoc/>
    public bool IsCurrentItem { get { return isCurrentItem_; } set { SetField(ref isCurrentItem_, value); } }
    #endregion
  }
}
