using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO.MemoryMappedFiles;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace memory_client
{
    public partial class Form1 : Form
    {
        [Serializable]
        public class WeatherDataInfo
        {
            //[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
            public byte[] fileName = new byte[512];

            public uint timeLayerNum;
            public uint latitudeNum;
            public uint longitudeNum;
            public uint startTime;
            public uint intervalTime;
            public uint reserved;

            public double[] geoInfo = new double[4];
        }


        [Serializable]
        public class WindSpeedData
        {
            public string[,] values;
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            WindSpeedData wsd = ReadObjectFromMMF("windSpeedData") as WindSpeedData;
            Console.WriteLine("wsd:" + wsd.values[0, 1]);


            WeatherDataInfo wsi = new WeatherDataInfo();
            wsi = ReadObjectFromMMF("") as WeatherDataInfo;
            Console.WriteLine("wdi_file:" + wsi.fileName.GetType() + "// " + wsi.fileName[0]);
            Console.WriteLine("wdi_timeLayerNum:" + wsi.timeLayerNum.GetType() + "// " + wsi.timeLayerNum);
            Console.WriteLine("wdi_lat:" + wsi.latitudeNum.GetType() + "// " + wsi.latitudeNum);
            Console.WriteLine("wdi_lon:" + wsi.longitudeNum.GetType() + "// " + wsi.longitudeNum);
            Console.WriteLine("wdi_startTime:" + wsi.startTime.GetType() + "// " + wsi.startTime);
            Console.WriteLine("wdi_intervalTime:" + wsi.intervalTime.GetType() + "// " + wsi.intervalTime);
            Console.WriteLine("wdi_reserved:" + wsi.reserved.GetType() + "// " + wsi.reserved);
            Console.WriteLine("wdi_geoInfo:" + wsi.geoInfo.GetType() + "// " + wsi.geoInfo); 

        }

        public object ReadObjectFromMMF(string name)
        {
            // Get a handle to an existing memory mapped file
            Console.WriteLine(name);
            using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(name, MemoryMappedFileRights.ReadWrite))
            {
                // Create a view accessor from which to read the data
                using (MemoryMappedViewAccessor mmfReader = mmf.CreateViewAccessor())
                {
                    // Create a data buffer and read entire MMF view into buffer
                    byte[] buffer = new byte[mmfReader.Capacity];
                    mmfReader.ReadArray<byte>(0, buffer, 0, buffer.Length);

                    // Convert the buffer to a .NET object
                    return ByteArrayToObject(buffer);
                }
            }
        }

        public object ByteArrayToObject(byte[] buffer)
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter(); // Create new BinaryFormatter
            MemoryStream memoryStream = new MemoryStream(buffer);    // Convert buffer to memorystream
            return binaryFormatter.Deserialize(memoryStream);        // Deserialize stream to an object
        }
    }
}
