using Android.App;
using Android.Widget;
using Android.OS;
using System;
using CommonDeviceAPI.Android;
using GLNeuroTech.Devices.Common;
using System.Collections.Generic;
using GLNeuroTech.Devices.BioRadio;
using GLNeuroTech.Devices.BioRadio.Configuration;
using Android.Views;
using System.Threading.Tasks;

namespace SampleProject_BioRadio_XamarinSDK
{
    [Activity(Label = "SampleProject_BioRadio_XamarinSDK", MainLauncher = true)]
    public class MainActivity : Activity
    {
        TextView pairedSensorIdText;
        Button startScan;
        ListView lstDevices;
        Button connectButton;
        Button startDataButton;
        BluetoothSearchUtility search;
        ArrayAdapter<string> adapter;
        List<BluetoothDeviceInfo> deviceList = new List<BluetoothDeviceInfo>();
        List<string> deviceListForUI = new List<string>();
        BioRadioDevice device;
        string macId = "";
        string deviceId = "";
        TextView scrollViewText;
        private ProgressBar progressbar;
        string displayInfo = "";
       
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            pairedSensorIdText = FindViewById<TextView>(Resource.Id.pairedSensorIdText);
            scrollViewText = FindViewById<TextView>(Resource.Id.scrollViewText);

            startScan = FindViewById<Button>(Resource.Id.startScan);
            startScan.Click += OnStartScan;

            lstDevices = FindViewById<ListView>(Resource.Id.lstDevices);
            lstDevices.ItemClick += OnItemClick;
            adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, deviceListForUI);
            lstDevices.Adapter = adapter;

            connectButton = FindViewById<Button>(Resource.Id.connectButton);
            connectButton.Click += ConnectButton_Click;

            startDataButton = FindViewById<Button>(Resource.Id.startDataButton);
            startDataButton.Click += StartButton_Click;

            progressbar = FindViewById<ProgressBar>(Resource.Id.pb);
            progressbar.Visibility = ViewStates.Invisible;
        }

        /// <summary>
        /// Scan available devices.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async private void OnStartScan(object sender, EventArgs e)
        {
            pairedSensorIdText.Text = "Scanning ...please wait! ";
            scrollViewText.Text = "\nPlease wait ... scanning for BioRadio device(s)!  \n\nTime: Up to 30 seconds.";
            progressbar.Visibility = ViewStates.Visible;
            await scanForDevice();
            progressbar.Visibility = ViewStates.Invisible;
            scrollViewText.Text = "\nSelect a BioRadio device!";
        }

        async Task scanForDevice()
        {
            await Task.Run(() =>
            {
                DisconnectDevice();
                search = new BluetoothSearchUtility("BioRadio");
                search.DeviceFoundEvent += MyFoundDvice;
                List<BluetoothDeviceInfo> l = search.FindBluetoothDevices();
                pairedSensorIdText.Text = "Select a device!";
            });
        }

        /// <summary>
        /// Generate the list of devices available.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyFoundDvice(object sender, DeviceFoundEventArgs e)
        {
            if (newDevice(e.DeviceInfo.DeviceId))
            {
                deviceList.Add(e.DeviceInfo);
                ((ArrayAdapter)lstDevices.Adapter).Add(e.DeviceInfo.DeviceId);
            }
        }

        /// <summary>
        /// Check if the device discovered is a new device.
        /// </summary>
        /// <param name="dev"></param>
        /// <returns></returns>
        private bool newDevice(string dev)
        {
            for (int i = 0; i < deviceList.Count; i++)
            {
                if (deviceList[i].DeviceId == dev)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Select a device from the available devices list.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            deviceId = deviceList[e.Position].DeviceId;
            macId = deviceList[e.Position].MacId;
            Android.Widget.Toast.MakeText(this, deviceId + "  :  " + macId, Android.Widget.ToastLength.Short).Show();

            pairedSensorIdText.Visibility = ViewStates.Visible;
            pairedSensorIdText.Text = string.Format("Device selected: {0}", deviceId);
            scrollViewText.Text = "\nBioRadio device selected: " + deviceId;
        }

        /// <summary>
        /// Connect the device and display general configuration.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async private void ConnectButton_Click(object sender, EventArgs e)
        {
            scrollViewText.Text = "";
            if (macId != "")
            {
                scrollViewText.Text = "\nPlease wait ... connecting the device: " + deviceId + "\n\nTime: Up to 1 minute.";                
                progressbar.Visibility = ViewStates.Visible;
                await connectDevice();
                progressbar.Visibility = ViewStates.Invisible;
                scrollViewText.Text = displayInfo;
            }
            else
            {
                scrollViewText.Text = "\nSelect a BioRadio device first!";                
            }
        }


        /// <summary>
        /// Connection device method.
        /// </summary>
        /// <returns></returns>
        private async Task connectDevice()
        {
            await Task.Run(() =>
            {
                DisconnectDevice();
                AndroidTransportProvider trans = new AndroidTransportProvider();
                BioRadioDeviceManager mgr = new BioRadioDeviceManager(trans);
                using (device = mgr.GetBluetoothDevice(macId))
                {
                    //Initial configuration for BioRadio Device
                    BioRadioConfiguration config = InitialConfiguration.GetInitialConfiguration();

                    //Set configuration to the selected device
                    device.SetConfiguration(config);

                    //Retrieve configuration from the device and display some of the configuration
                    BioRadioConfiguration deviceConfig = device.GetConfiguration();
                    BatteryInfo battery = device.GetBatteryInfo();
                    DateTime deviceTime = device.GetDeviceTime();

                    displayInfo = "Device Connected: " + deviceId;
                    displayInfo += "\nVoltage: " + battery.Voltage.ToString();
                    displayInfo += "\nCurrent Device Time: " + deviceTime.ToString();
                    displayInfo += "\n        Will now retrieve configuration data:";
                    displayInfo += "\nTermination: " + deviceConfig.Termination;
                    displayInfo += "\nName: " + deviceConfig.Termination;
                    displayInfo += "\nPatientGroundDriven: " + deviceConfig.PatientGroundDriven;
                    displayInfo += "\nPerformLeadOffDetection: " + deviceConfig.PerformLeadOffDetection;
                    displayInfo += "\nSampleRate: " + deviceConfig.SampleRate;
                    displayInfo += "\n       Signals ENABLED";
                    foreach (var signal in device.SignalGroups)
                    {
                        displayInfo += "\nSignal_ " + signal.Name;
                    }
                }
            });
        }


        /// <summary>
        /// Start acquisition and display first 3000 values acquired.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async private void StartButton_Click(object sender, EventArgs e)
        {
            scrollViewText.Text = "";
            if (macId != "")
            {
                scrollViewText.Text = "\nPlease wait ... start acquisition! \n\n Shake the BioRadio for gyro data! \n\n Time: Up to 2 minute.";
                DisconnectDevice();
                Android.Widget.Toast.MakeText(this, "Please wait ... starting acquisition! ", Android.Widget.ToastLength.Long).Show();

                progressbar.Visibility = ViewStates.Visible;
                await startAcquisition();
                progressbar.Visibility = ViewStates.Invisible;
                scrollViewText.Text = displayInfo;
            }
            else
            {
                scrollViewText.Text = "\n Select a BioRadio device first!";                
            }
        }

        /// <summary>
        /// Start acquisition method.
        /// </summary>
        /// <returns></returns>
        private async Task startAcquisition()
        {
            await Task.Run(() =>
            {
                displayInfo = "  Acquisition results:";

                BioRadioConfiguration config = InitialConfiguration.GetInitialConfiguration();
                BioRadioConfiguration finalConfig = additionalConfig(config);

                AndroidTransportProvider trans = new AndroidTransportProvider();
                BioRadioDeviceManager mgr = new BioRadioDeviceManager(trans);
                using (device = mgr.GetBluetoothDevice(macId))
                {
                    device.SetConfiguration(finalConfig);
                    device.StartAcquisition();
                    int i = 0;

                    while (i < 3000)
                    {
                        foreach (var signalGroup in device.SignalGroups)
                        {
                            foreach (BioRadioSignal signal in signalGroup)
                            {
                                var samples = signal.GetScaledValueArray();
                                foreach (var val in samples)
                                {
                                    i++;
                                    displayInfo += "\nFrom: " + signal.Name + " - Value_ " + i + " :  " + val.ToString("##.####   ");
                                    if (i > 3000)
                                    {
                                        device.StopAcquisition();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            });

        }

        /// <summary>
        /// Disconnect the device method.
        /// </summary>
        private void DisconnectDevice()
        {
            if (device != null)
            {
                if (device.IsRecording)
                {
                    device.StopRecording();
                }
                if (device.IsAcquiring)
                {
                    device.StopAcquisition();
                }
                device.Disconnect();
            }
        }

        /// <summary>
        /// Set additional bio radio configuration for the connected device.
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        private BioRadioConfiguration additionalConfig(BioRadioConfiguration config)
        {
            config.Termination = BioPotentialTermination.SingleEnded;
            //config.MemsChannel.Enabled = false;
            config.EventMarkerChannel.Enabled = false;
            config.ExternalSensors[0].Enabled = false;
            config.ExternalSensors[1].Enabled = false;

            // use mixed bit resolutions for the channels
            config.BioPotentialChannels[0].BitResolution = 12;
            config.BioPotentialChannels[1].BitResolution = 16;
            config.BioPotentialChannels[2].Enabled = false;
            config.BioPotentialChannels[3].Enabled = false;
            config.BioPotentialChannels[4].Enabled = false;
            config.BioPotentialChannels[5].Enabled = false;

            config.BioPotentialChannels[6].Enabled = false;
            config.BioPotentialChannels[7].Enabled = false;

            return config;
        }
    }
}

