// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : Nounours.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-10-16
//
// ========================================================================

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ex_042_002_EF_CodeFirst_data_annotations
{
    /// <summary>
    /// Nounours est une classe POCO, i.e. Plain Old CLR Object.
    /// Nous avons vu dans l'exemple précédent comment utiliser les conventions d'écriture. Cette méthode est pratique mais ne nous laisse pas beaucoup 
    /// de possibilités de modifier la table selon nos désirs. 
    /// Cet exemple montre comment utiliser les data annotations. En voici quelques exemples principaux :
    /// - la classe utilise l'annotation [Table("TableNounours")] qui permet de modifier le nom de la table dans la base de données
    /// - la propriété DateDeNaissance a une annotation "Column" permettant de choisir un nom pour la colonne
    /// - la propriété Nom n'a pas d'annotation "Column", c'est donc la convention d'écriture qui s'applique pour le nom de la colonne => "Nom"
    /// - la propriété Nom a une annotation "Required" qui indique que le champ est obligatoire
    /// - la propriété Nom a une annotation MaxLength indiquant combien de caractères peut avoir le Nom au maximum dans la base de données
    /// - la propriété NbPoils a une annotation NotMapped indiquant qu'il n'y aura pas de colonne associée à cette propriété dans la table
    /// - la propriété UniqueId a une annotation Key pour indiquer que c'est cette propriété qu'il faut utiliser comme clé primaire
    /// - la propriété UniqueId a également une annotation DatabaseGenerated permettant d'indiquer que c'est lors de l'insertion dans la table qu'une 
    /// clé primaire (ici de type Guid, et pas obligatoirement int) lui sera attribuée
    /// 
    /// Il existe d'autres annotations que vous pouvez découvrir et utiliser par la suite comme ForeignKey, TimeStamp, ConcurrencyCheck, CreditCard, 
    /// EmailAddress, Phone, StringLength, Url...
    /// </summary>
    [Table("TableNounours")]
    public class Nounours
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid UniqueId
        {
            get; set;
        }

        [Required]
        [MaxLength(256)]
        public string Nom
        {
            get;
            set;
        }

        [Column("Naissance")]
        public DateTime DateDeNaissance
        {
            get;
            set;
        }

        [NotMapped]
        public int NbPoils
        {
            get;
            set;
        }

        /// <summary>
        /// returns a hash code in order to use this class in hash table
        /// </summary>
        /// <returns>hash code</returns>
        public override int GetHashCode()
        {
            return Nom.GetHashCode();
        }

        /// <summary>
        /// checks if the "right" object is equal to this Nounours or not
        /// </summary>
        /// <param name="right">the other object to be compared with this Nounours</param>
        /// <returns>true if equals, false if not</returns>
        public override bool Equals(object right)
        {
            //check null
            if (object.ReferenceEquals(right, null))
            {
                return false;
            }

            if (object.ReferenceEquals(this, right))
            {
                return true;
            }

            if (this.GetType() != right.GetType())
            {
                return false;
            }

            return this.Equals(right as Nounours);
        }

        /// <summary>
        /// checks if this Nounours is equal to the other Nounours
        /// </summary>
        /// <param name="other">the other Nounours to be compared with</param>
        /// <returns>true if equals</returns>
        public bool Equals(Nounours other)
        {
            return (this.Nom.Equals(other.Nom) && this.DateDeNaissance == other.DateDeNaissance);
        }

        public override string ToString()
        {
            return $"{UniqueId}: {Nom} ({DateDeNaissance:dd/MM/yyyy}, {NbPoils} poils)";
        }

    }
}
