using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FPGACoder.ViewModel
{
    public abstract class FPGAPropertyViewModel:ViewModelBase<Model.IModel>
    {
        private string propertyName = string.Empty;

        [AllowNull]
        public virtual string TargetName { get; }
        public virtual string PropertyName { get => propertyName; set => UpdateProperty(ref propertyName, value); }
        [AllowNull]
        public virtual string PropertyString { get; }
    }
    public class DMAViewModel:FPGAPropertyViewModel
    {
        NIFPGA.lvbitx.DMA dma;
        private DMAViewModel(NIFPGA.lvbitx.DMA dma)
        {
            this.dma = dma;
            PropertyName = dma.Name;
        }
        static DMAViewModel()
        {

        }
        public override string TargetName => dma.Name;
        public static DMAViewModel GetDMA(NIFPGA.lvbitx.DMA dma,string propertyname ="")
        {
            DMAViewModel vm = new DMAViewModel(dma);
            if(!string.IsNullOrEmpty(propertyname))
            {
                vm.PropertyName = propertyname;
            }
            return vm;
        }
        public override string PropertyString => GetPropertyString();
        private string GetPropertyString()
        {
            string direction = dma.Direction == "TargetToHost" ? "ReadFifo" : "WriteFifo";
            string protype = string.Empty;
            string proname = $"{(string.IsNullOrEmpty(PropertyName) ? TargetName : PropertyName)}";
            switch (dma.Datatype)
            {
                case NIFPGA.lvbitx.Datatype.Boolean:
                    protype = $"{direction}<bool>";
                    break;
                case NIFPGA.lvbitx.Datatype.Int8:
                    protype = $"{direction}<sbyte>";
                    break;
                case NIFPGA.lvbitx.Datatype.Double:
                    protype = $"{direction}<double>";
                    break;
                case NIFPGA.lvbitx.Datatype.Float:
                    protype = $"{direction}<float>";
                    break;
                case NIFPGA.lvbitx.Datatype.FXP:
                    protype = $"{(dma.Direction == "TargetToHost" ? "ReadFXPFifo" : "WriteFXPFifo")}";
                    break;
                case NIFPGA.lvbitx.Datatype.Int16:
                    protype = $"{direction}<short>";
                    break;
                case NIFPGA.lvbitx.Datatype.Int32:
                    protype = $"{direction}<int>";
                    break;
                case NIFPGA.lvbitx.Datatype.Int64:
                    protype = $"{direction}<long>";
                    break;
                case NIFPGA.lvbitx.Datatype.Uint16:
                    protype = $"{direction}<ushort>";
                    break;
                case NIFPGA.lvbitx.Datatype.Uint32:
                    protype = $"{direction}<uint>";
                    break;
                case NIFPGA.lvbitx.Datatype.Uint64:
                    protype = $"{direction}<ulong>";
                    break;
                case NIFPGA.lvbitx.Datatype.Uint8:
                    protype = $"{direction}<byte>";
                    break;
                default:
                    throw new Exception("类型错误");
            }
            string propertyString =  $"private {protype} _{proname};\r\n /// <summary> \r\n///{TargetName}\r\n/// </summary>\r\n[AllowNull]\r\npublic {protype} {proname} \r\n" + "{\r\nget{\r\nif(_"+proname+"==null)\r\n{\r\n_"+proname+$"=({protype})fpga.Fifos[\"{TargetName}\"];"+"\r\n}\r\nreturn _"+proname+";\r\n}\r\n}";
            return propertyString;
        }

    }
}
