using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;

namespace DXGfxLib.Serialization
{
    public class Manager
    {
        private static Manager globalInstance = null;

        public Manager()
        {
            if (globalInstance != null)
            {
                throw new Exception("There is already one instance of the Manager class in this AppDomain. It is improper to have several!");
            }
            globalInstance = this;
        }

        public void Dispose()
        {
            globalInstance = null;
        }

        public static Manager GetGlobalInstance()
        {
            return globalInstance;
        }

        public void SaveScene(Scene scene, string fileName)
        {
        }

        public void SaveScene(OutDoorScene scene, string fileName)
        {
            // 1. Construct the desired formatter
            IFormatter formatter = new SoapFormatter();

            // 2. Construct a SurrogateSelector object
            SurrogateSelector ss = new SurrogateSelector();

            // 3. Construct an instances of our serialization surrogate types
            OutDoorSceneSurrogate odss = new OutDoorSceneSurrogate();
            TerrainSurrogate ts = new TerrainSurrogate();
            SceneObjectSurrogate sos = new SceneObjectSurrogate();
            CursorSurrogate cs = new CursorSurrogate();
            SkyDomeSurrogate sds = new SkyDomeSurrogate();
            Water2Surrogate ws = new Water2Surrogate();

            // 4. Tell the surrogate selector to use our objects
            ss.AddSurrogate(typeof(OutDoorScene),
               new StreamingContext(StreamingContextStates.All),
               odss);
            ss.AddSurrogate(typeof(Terrain),
               new StreamingContext(StreamingContextStates.All),
               ts);
            ss.AddSurrogate(typeof(SceneObject),
               new StreamingContext(StreamingContextStates.All),
               sos);
            ss.AddSurrogate(typeof(SkyBox),
                new StreamingContext(StreamingContextStates.All),
                sos);
            ss.AddSurrogate(typeof(Water),
                new StreamingContext(StreamingContextStates.All),
                sos);
            ss.AddSurrogate(typeof(MeshObject),
                new StreamingContext(StreamingContextStates.All),
                sos);
            ss.AddSurrogate(typeof(Cursor),
                new StreamingContext(StreamingContextStates.All),
                cs);
            ss.AddSurrogate(typeof(SkyDome),
                new StreamingContext(StreamingContextStates.All),
                sds);
            ss.AddSurrogate(typeof(Water2),
                new StreamingContext(StreamingContextStates.All),
                ws);
            // 5. Have the formatter use our surrogate selector
            formatter.SurrogateSelector = ss;

            // Serialize our outdoorscene.
            formatter.Serialize(new FileStream(fileName, FileMode.Create, FileAccess.Write), scene);



        }

        public Scene LoadScene(string fileName)
        {
            return null;
        }

        public OutDoorScene LoadOutdoor(string fileName)
        {
            // 1. Construct the desired formatter
            IFormatter formatter = new SoapFormatter();

            // 2. Construct a SurrogateSelector object
            SurrogateSelector ss = new SurrogateSelector();

            // 3. Construct an instances of our serialization surrogate types
            OutDoorSceneSurrogate odss = new OutDoorSceneSurrogate();
            TerrainSurrogate ts = new TerrainSurrogate();
            SceneObjectSurrogate sos = new SceneObjectSurrogate();
            CursorSurrogate cs = new CursorSurrogate();
            SkyDomeSurrogate sds = new SkyDomeSurrogate();
            Water2Surrogate ws = new Water2Surrogate();

            // 4. Tell the surrogate selector to use our objects
            ss.AddSurrogate(typeof(OutDoorScene),
               new StreamingContext(StreamingContextStates.All),
               odss);
            ss.AddSurrogate(typeof(Terrain),
               new StreamingContext(StreamingContextStates.All),
               ts);
            ss.AddSurrogate(typeof(SceneObject),
               new StreamingContext(StreamingContextStates.All),
               sos);
            ss.AddSurrogate(typeof(SkyBox),
                new StreamingContext(StreamingContextStates.All),
                sos);
            ss.AddSurrogate(typeof(Water),
                new StreamingContext(StreamingContextStates.All),
                sos);
            ss.AddSurrogate(typeof(MeshObject),
                new StreamingContext(StreamingContextStates.All),
                sos);
            ss.AddSurrogate(typeof(Cursor),
                new StreamingContext(StreamingContextStates.All),
                cs);
            ss.AddSurrogate(typeof(SkyDome),
                new StreamingContext(StreamingContextStates.All),
                sds);
            ss.AddSurrogate(typeof(Water2),
                new StreamingContext(StreamingContextStates.All),
                ws);

            // 5. Have the formatter use our surrogate selector
            formatter.SurrogateSelector = ss;

            // 6. Deserialize our outdoorscene.
            FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            OutDoorScene outdoorScene = (OutDoorScene)formatter.Deserialize(fStream);
            fStream.Close();

            return outdoorScene;
        }
    }
}
