using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using FxpConvert.Common;

namespace BaseCpuFxpConvert
{
    public class BaseCpuFxpConvert:IFxpConvert
    {
        public bool IsSupport => true;

        public unsafe void DoubleConvertToDxp(ref double value, NiFpga_FxpTypeInfo dxpinfo, ref ulong fxp, uint count)
        {
            if (count == 0) return;
            ulong* ptr = (ulong*)Unsafe.AsPointer(ref fxp);
            double pow = (2 << (dxpinfo.wordLength - dxpinfo.integerWordLength - 1));
            double* valptr = (double*)Unsafe.AsPointer(ref value);
            for (int i = 0; i < count; i++)
            {
                ptr[i] = (ulong)(valptr[i] * pow);
            }
        }

        public unsafe void FloatConvertToDxp(ref float value, NiFpga_FxpTypeInfo dxpinfo, ref ulong fxp, uint count)
        {
            if (count == 0) return;
            ulong* ptr = (ulong*)Unsafe.AsPointer(ref fxp);
            float pow = (2 << (dxpinfo.wordLength - dxpinfo.integerWordLength - 1));
            float* valptr = (float*)Unsafe.AsPointer(ref value);
            for (int i = 0; i < count; i++)
            {
                ptr[i] = (ulong)(valptr[i] * pow);
            }
        }

        public unsafe void FxpConvertToDouble(ref ulong fxp, NiFpga_FxpTypeInfo dxpinfo, ref double value, uint count)
        {
            double* ptr = (double*)Unsafe.AsPointer(ref value);
            double pow = (2 << (dxpinfo.wordLength - dxpinfo.integerWordLength - 1));
            ulong* fxpptr = (ulong*)Unsafe.AsPointer(ref fxp);
            if (count > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    ptr[i] = (dxpinfo.isSigned ? ((long)(fxpptr[i])) : fxpptr[i]) / pow;
                }
            }
        }

        public unsafe void FxpConvertToFloat(ref ulong fxp, NiFpga_FxpTypeInfo dxpinfo, ref float value, uint count)
        {
            float* ptr = (float*)Unsafe.AsPointer(ref value);
            float pow = (2 << (dxpinfo.wordLength - dxpinfo.integerWordLength - 1));
            ulong* fxpptr = (ulong*)Unsafe.AsPointer(ref fxp);
            if (count > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    ptr[i] = (dxpinfo.isSigned ? ((long)(fxpptr[i])) : fxpptr[i]) / pow;
                }
            }
        }
    }
}
