using System.Threading;
using Microsoft.SPOT.Hardware;
using System;
using Microsoft.SPOT;

namespace HWModules
{
    //TODO P2 need a method to setup ADC registers
    public class ADC2485 : I2CPortBase
    {
        private static I2CDevice.I2CTransaction[] xActionsDouble;
        private static I2CDevice.I2CTransaction[] xActionsSingle;

        private static byte[] sampleBytes = new byte[4];
        private static byte[] convertBytes = new byte[4];
        private static byte[] mode0 = new byte[1] { 0x00 };//External input, 50 and 60 Hz filter, 1X speed
        private static byte[] mode4 = new byte[1] { 0x04 };//External input, 60 Hz filter, 1X speed

        private static int xActionReturn = 0;

        private static int value = int.MaxValue;

        public ADC2485(I2CDevice.Configuration config, int slotNumber)
            : base(config, slotNumber)
        {
            xActionsDouble = new I2CDevice.I2CTransaction[2];
            xActionsSingle = new I2CDevice.I2CTransaction[1];

            // create read buffer to read the returned data
            xActionsDouble[1] = CreateReadTransaction(sampleBytes);

            // create write buffer, send 2485 mode command
            xActionsDouble[0] = CreateWriteTransaction(mode4);

            xActionsSingle[0] = CreateWriteTransaction(mode4);

        }



        private long ticksOfLastWrite = 0;
        private long currentTicks;

        private int lastVal;

        public int readValue()
        {
            try
            {
                //Check whether we just tried
                currentTicks = Utility.GetMachineTime().Ticks;
                if ( (currentTicks - ticksOfLastWrite) < ((long)140 * TimeSpan.TicksPerMillisecond) )
                {
                    //Debug.Print("----ADC Waiting");
                    //Debug.Print("current ticks = " + currentTicks.ToString());
                    //Debug.Print("ticksOfLastWrite = " + ticksOfLastWrite.ToString());
                    //Debug.Print("Diff = " + (currentTicks - ticksOfLastWrite).ToString());
                    //Debug.Print("Threshold = " + (140 * TimeSpan.TicksPerMillisecond).ToString());
                    return lastVal;
                }

                xActionReturn = Execute(xActionsDouble, 1000);

                //Check if no bytes came back
                if (xActionReturn == 0)
                {
                    EngrLogger.writeToColumns("[ERROR] executing 2485 Transaction = " + xActionReturn.ToString());
                    return lastVal = int.MaxValue;
                }

                //Successful interaction, let's update the timer
                ticksOfLastWrite = Utility.GetMachineTime().Ticks;

                //Check if some came back
                if ((sampleBytes[0] >= (byte)0xC0) || (sampleBytes[0] < (byte)0x40))
                {
                    EngrLogger.writeToColumns("[ERROR] 2485 Sample out of range");
                    return lastVal = int.MaxValue;
                }

                convertBytes[0] = sampleBytes[3];
                convertBytes[1] = sampleBytes[2];
                convertBytes[2] = sampleBytes[1];
                convertBytes[3] = sampleBytes[0];
                return lastVal = GHI.Utilities.Arrays.ExtractInt32(convertBytes, 0);
            }
            catch
            {
                //TODO P1 need a proper error handler
                EngrLogger.writeToColumns("[ERROR] ADC2485.readValue Method");
                return (int.MaxValue);
            }
        }
    }
}
