using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FxpConvert.Common;

namespace NIFPGA.lvbitx
{
    public class Bitfile
    {
        public string FilePath { get; set; } = string.Empty;
        public string BitfileVersion { get; set; } =string.Empty;
        public string SignatureRegister { get; set; } = string.Empty;
        public string SignatureGuids { get; set; } = string.Empty;
        public string SignatureNames { get; set; } = string.Empty;
        public string BitstreamVersion { get; set; } = string.Empty;
        public VI VI { get; } = new VI();
        public Project Project { get; } = new Project();
    }
    public class VI
    {
        public string Name { get; set; } = string.Empty;
        public List<Register> Registers { get; } = new List<Register>();
    }
    public class Register
    {
        public string Name { get; set; } = string.Empty;
        public Boolean Hidden { get; set; }
        public Boolean Indicator { get; set; }
        public Datatype Datatype { get; set; }
        public string FlattenedType { get; set; } = string.Empty;
        public uint Offset { get; set; }
        public uint SizeInBits { get; set; }
        public uint Class { get; set; }
        public bool Internal { get; set; }
        public uint ID { get; set; }
        public bool Bidirectional { get; set; }
        public bool Synchronous { get; set; }
        public string MechanicalAction { get; set; }=string.Empty;
        public bool AccessMayTimeout { get; set; }
        public bool RegisterNode { get; set; }
        public NiFpga_FxpTypeInfo FxpTypeInfo;
        public uint Size { get; set; }
        public Datatype ArrayValueType { get; set; }
        public override string ToString() => Name;
    }
    public class Project
    {
        public string TargetClass { get; set; }= string.Empty;
        public bool AutoRunWhenDownloaded { get; set; }
        public List<DMA> DMA { get; } = new List<DMA>();
    }
    public class NiFpga
    {
        public int BaseAddressOnDevice { get; set; }
    }
    public class DMA
    {
        public string Name { get; set; } = string.Empty;
        public string BaseAddressTag { get; set; } = string.Empty;
        public uint ControlSet { get; set; }
        public Datatype Datatype { get; set; }
        public NiFpga_FxpTypeInfo FxpTypeInfo;
        public string Direction { get; set; } = string.Empty;
        public string Implementation { get; set; } = string.Empty;
        public int Number { get; set; }
        public UInt32 NumberOfElements { get; set; }
        public Boolean UserVisible { get; set; }
        public override string ToString() => Name;
    }
    public enum Datatype
    {
        [DataType("Boolean")]
        Boolean,
        [DataType("I8","EnumI8")]
        Int8,
        [DataType("U8","EnumU8")]
        Uint8,
        [DataType("I16","EnumI16")]
        Int16,
        [DataType("U16","EnumU16")]
        Uint16,
        [DataType("I32","EnumI32")]
        Int32,
        [DataType("U32","EnumU32")]
        Uint32,
        [DataType("I64","EnumI64")]
        Int64,
        [DataType("U64","EnumU64")]
        Uint64,
        [DataType("SGL")]
        Float,
        [DataType("DBL")]
        Double,
        [DataType("FXP")]
        FXP,
        [DataType("Array")]
        Array,
    }
    [AttributeUsage(AttributeTargets.Field)]
    internal class DataTypeAttribute:Attribute
    {
        private List<string> names = new List<string>();
        public IReadOnlyList<string> Name => names.AsReadOnly();
        public DataTypeAttribute(params string[] name)
        {
            if (name == null || name.Length == 0) return;
            names.AddRange(name);
        }
    }
}
