using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void anButtonValueChangeCallBack(YFunction fct, string value)
        {
            Console.WriteLine(fct.get_hardwareId() + ": " + value + " (new value)");
        }

        static void sensorValueChangeCallBack(YSensor fct, string value)
        {
            Console.WriteLine(fct.get_hardwareId() + ": " + value + " " + fct.get_userData() + " (new value)");
        }

        static void sensorTimedReportCallBack(YSensor fct, YMeasure measure)
        {
            Console.WriteLine(fct.get_hardwareId() + ": " + measure.get_averageValue() + " " + fct.get_userData() + " (timed report)");
        }

        static void deviceLog(YModule module, string logline)
        {
            Console.WriteLine("log: " + module.get_hardwareId() + ":" + logline);
        }

        static void configChange(YModule m)
        {
            Console.WriteLine("config change: " + m.get_serialNumber());
        }


        static void beaconChange(YModule m, int beacon)
        {
            Console.WriteLine("Beacon of " + m.get_serialNumber() + " changed to " + beacon);
        }


        static void deviceArrival(YModule m)
        {
            string serial = m.get_serialNumber();
            Console.WriteLine("Device arrival : " + serial);
            m.registerLogCallback(deviceLog);
            m.registerConfigChangeCallback(configChange);
            m.registerBeaconCallback(beaconChange);

            // First solution: look for a specific type of function (eg. anButton)
            int fctcount = m.functionCount();
            for (int i = 0; i < fctcount; i++) {
                string hardwareId = serial + "." + m.functionId(i);
                if (hardwareId.IndexOf(".anButton") >= 0) {
                    Console.WriteLine("- " + hardwareId);
                    YAnButton anButton = YAnButton.FindAnButton(hardwareId);
                    anButton.registerValueCallback(anButtonValueChangeCallBack);
                }
            }

            // Alternate solution: register any kind of sensor on the device
            YSensor sensor = YSensor.FirstSensor();
            while (sensor != null) {
                if (sensor.get_module().get_serialNumber() == serial) {
                    string hardwareId = sensor.get_hardwareId();
                    Console.WriteLine("- " + hardwareId);
                    string unit = sensor.get_unit();
                    sensor.set_userData(unit);
                    sensor.registerValueCallback(sensorValueChangeCallBack);
                    sensor.registerTimedReportCallback(sensorTimedReportCallBack);
                }

                sensor = sensor.nextSensor();
            }
        }

        static void deviceRemoval(YModule m)
        {
            Console.WriteLine("Device removal : " + m.get_serialNumber());
        }

        private static void log(string line)
        {
            Console.Write("LOG : " + line);
        }

        static void Main(string[] args)
        {
            string errmsg = "";

            YAPI.RegisterLogFunction(log);

            if (YAPI.RegisterHub("usb", ref errmsg) != YAPI.SUCCESS) {
                Console.WriteLine("RegisterHub error : " + errmsg);
                Environment.Exit(0);
            }

            YAPI.RegisterDeviceArrivalCallback(deviceArrival);
            YAPI.RegisterDeviceRemovalCallback(deviceRemoval);

            Console.WriteLine("Hit Ctrl-C to Stop ");

            while (true) {
                YAPI.UpdateDeviceList(ref errmsg); // traps plug/unplug events
                YAPI.Sleep(500, ref errmsg); // traps others events
            }
        }
    }
}