// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : Program.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-10-05
// Mise à jour   : 2016-10-12
//
// ========================================================================

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Xml;
using static System.Console;

namespace ex_038_001_DataContractSerializer_bases
{
    class Program
    {
        static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "ex_038_001_DataContractSerializer_bases", "XML"));
            string xmlFile = "nounours.xml";

            Nounours chewie = new Nounours()
            {
                Nom = "Chewbacca",
                DateDeNaissance = new DateTime(1977, 5, 27),
                NbPoils = 1234567
            };

            Nounours yoda = new Nounours()
            {
                Nom = "Yoda",
                DateDeNaissance = new DateTime(1980, 5, 21),
                NbPoils = 3
            };

            Nounours ewok = new Nounours()
            {
                Nom = "Ewok",
                DateDeNaissance = new DateTime(1983, 5, 25),
                NbPoils = 3456789
            };

            chewie.Amis.Add(yoda);
            chewie.Amis.Add(ewok);

            WriteLine(chewie);


            //ATTENTION : pour que le DataContractSerializer fonctionne, vous devez avoir décoré l'objet à sérialiser !
            //cf. Nounours.cs


            //1. Sérialisation d'un chewie en xml avec la méthode par défaut
            //- on construit le sérialiseur en précisant le type de l'objet à sérialiser
            //- on crée le flux (de préférence avec using pour ne pas oublier d'appeler Dispose à la fin) en écriture
            //- on appelle WriteObject pour sérialiser
            var serializer = new DataContractSerializer(typeof(Nounours));

            using (Stream s = File.Create(xmlFile))
            {
                serializer.WriteObject(s, chewie);
            }

            //- pour désérialiser, on crée le flux (de préférence avec using) en lecture
            //- on appelle ReadObject
            Nounours nounours2;
            using (Stream s = File.OpenRead(xmlFile))
            {
                nounours2 = serializer.ReadObject(s) as Nounours;
            }

            WriteLine(nounours2);





            //2. spécifier le XmlWriter pour que cela soit plus lisible (indentation)
            //- même chose qu'avant, mais en utilisant un XmlWriter, on peut ajouter des settings, notamment pour l'indentation et le rendre plus lisible
            string xmlFile2 = "nounours2.xml";

            XmlWriterSettings settings = new XmlWriterSettings() { Indent = true };
            using (TextWriter tw = File.CreateText(xmlFile2))
            {
                using (XmlWriter writer = XmlWriter.Create(tw, settings))
                {
                    serializer.WriteObject(writer, chewie);
                }
            }




            // Par défaut, le formatage est XML, mais vous pouvez spécifier un formatage binaire.
            //3. Formatage binaire
            using (FileStream stream = File.Create("nounours.txt"))
            {
                using (XmlDictionaryWriter xmlDicoWriter = XmlDictionaryWriter.CreateBinaryWriter(stream))
                {
                    serializer.WriteObject(xmlDicoWriter, chewie);
                }
            }

            Nounours nounours3;
            using (FileStream stream2 = File.OpenRead("nounours.txt"))
            {
                using (XmlDictionaryReader xmlDicoReader = XmlDictionaryReader.CreateBinaryReader(stream2, XmlDictionaryReaderQuotas.Max))
                {
                    nounours3 = serializer.ReadObject(xmlDicoReader) as Nounours;
                }
            }
            WriteLine(nounours3);

            //... ou Json avec un DataContractJsonSerializer
            //4. Formatage Json
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Nounours));
            MemoryStream memoryStream = new MemoryStream();
            jsonSerializer.WriteObject(memoryStream, chewie);
            using (FileStream stream = File.Create("nounours.json"))
            {
                memoryStream.WriteTo(stream);
            }

            Nounours nounours4;
            using (FileStream stream2 = File.OpenRead("nounours.json"))
            {
                nounours4 = jsonSerializer.ReadObject(stream2) as Nounours;
            }
            WriteLine(nounours4);
        }
    }
}
