/*
 * ReceiveSurface.cs
 * 
 * Gocator 2000/2300 C# Sample
 * Copyright (C) 2013 by LMI Technologies Inc.
 * 
 * Licensed under The MIT License.
 * Redistributions of files must retain the above copyright notice.
 *
 * Purpose: Connect to Gocator system and receive Surface data and translate to engineering units. Gocator must be in Surface Mmode.
 * Ethernet output for the whole part and/or intensity data must be enabled.
 */

using System;
using System.Runtime.InteropServices;
using Lmi3d.GoSdk;
using Lmi3d.Zen;
using Lmi3d.Zen.Io;
using Lmi3d.GoSdk.Messages;

static class Constants
{
    public const string SENSOR_IP = "192.168.1.10"; // IP of the sensor used for sensor connection GoSystem_FindSensorByIpAddress() call.
}

namespace ReceiveWholePart
{
    public class DataContext
    {
        public double xResolution;
        public double yResolution;
        public double zResolution;
        public double xOffset;
        public double yOffset;
        public double zOffset;
        public uint serialNumber;
    }

    class ReceiveSurface
    {
        static int Main(string[] args)
        {
            try
            {
                KApiLib.Construct();
                GoSdkLib.Construct();
                GoSystem system = new GoSystem();
                GoSensor sensor;
                KIpAddress ipAddress = KIpAddress.Parse(Constants.SENSOR_IP);
                GoDataSet dataSet = new GoDataSet();
                sensor = system.FindSensorByIpAddress(ipAddress);
                sensor.Connect();
                GoSetup setup = sensor.Setup;
                setup.ScanMode = GoMode.Surface;
                system.EnableData(true);
                system.Start();
                Console.WriteLine("Waiting for Whole Part Data...");
                dataSet = system.ReceiveData(30000000);
                DataContext context = new DataContext();
                for (UInt32 i = 0; i < dataSet.Count; i++)
                {
                    GoDataMsg dataObj = (GoDataMsg)dataSet.Get(i);
                    switch (dataObj.MessageType)
                    {
                        case GoDataMessageType.Stamp:
                            {
                                GoStampMsg stampMsg = (GoStampMsg)dataObj;
                                for (UInt32 j = 0; j < stampMsg.Count; j++)
                                {
                                    GoStamp stamp = stampMsg.Get(j);
                                    Console.WriteLine("Frame Index = {0}", stamp.FrameIndex);
                                    Console.WriteLine("Time Stamp = {0}", stamp.Timestamp);
                                    Console.WriteLine("Encoder Value = {0}", stamp.Encoder);
                                }
                            }
                            break;
                        case GoDataMessageType.Surface:
                            {
                                GoSurfaceMsg surfaceMsg = (GoSurfaceMsg)dataObj;
                                long width = surfaceMsg.Width;
                                long height = surfaceMsg.Length;
                                long bufferSize = width * height;
                                IntPtr bufferPointer = surfaceMsg.Data;

                                Console.WriteLine("Whole Part Height Map received:");
                                Console.WriteLine(" Buffer width: {0}", width);
                                Console.WriteLine(" Buffer height: {0}", height);

                                short[] ranges = new short[bufferSize];
                                Marshal.Copy(bufferPointer, ranges, 0, ranges.Length);
                            }
                            break;
                        case GoDataMessageType.SurfaceIntensity:
                            {
                                GoSurfaceIntensityMsg surfaceMsg = (GoSurfaceIntensityMsg)dataObj;
                                long width = surfaceMsg.Width;
                                long height = surfaceMsg.Length;
                                long bufferSize = width * height;
                                IntPtr bufferPointeri = surfaceMsg.Data;

                                Console.WriteLine("Whole Part Intensity Image received:");
                                Console.WriteLine(" Buffer width: {0}", width);
                                Console.WriteLine(" Buffer height: {0}", height);
                                byte[] ranges = new byte[bufferSize];
                                Marshal.Copy(bufferPointeri, ranges, 0, ranges.Length);
                            }
                            break;
                    }
                }
                system.Stop();
            }
            catch (KException ex)
            {
                Console.WriteLine("Error: {0}", ex.Status);
            }
            // wait for ESC key
            Console.WriteLine("\nPress ENTER to continue");
            do
            {
                System.Threading.Thread.Sleep(100);
            } while (Console.Read() != (int)ConsoleKey.Enter);
            return 1;
        }
    }
}
