using HandyControl.Interactivity.Commands;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace FPGACoder.ViewModel
{
    public class MainViewModel:ViewModelBase<Model.MainModel>
    {
        private static string Path =  System.AppDomain.CurrentDomain.BaseDirectory+"Config.json";
        private string vIName = string.Empty;
        private DateTime lastTime;

        private MainViewModel()
        {
            if (System.IO.File.Exists(Path))
            {
                var model = Newtonsoft.Json.JsonConvert.DeserializeObject<FPGACoder.Model.MainModel>(System.IO.File.ReadAllText(Path));
                if (model != null)
                {
                    UpDateModel(model);
                }
            }
            TestName.Test.CreateFpga(new BaseCpuFxpConvert.BaseCpuFxpConvert());
        }
        static MainViewModel()
        {

        }

        public ICommand GenerateCommand => new DelegateCommand(Generate);
        private void Generate()
        {
            var stream = new StreamReader(Assembly.GetAssembly(this.GetType())?.GetManifestResourceStream("FPGACoder.Code.txt"));
            if (stream == null)
            {
                MessageBox.Show("资源读取错误");
                return;
            }
            string vv = stream.ReadToEnd();
            stream.Dispose();
            string v = string.Format(vv, NamespaceName, ClassName, string.Join("\r\n", Register.Select(x => x.PropertyString)), string.Join("\r\n", Project.DMA.Select(x => x.PropertyString)), $"设备:{Project.TargetClass}  顶层VI:{VIName}  bit文件生成时间:{LastTime}");
            for (int i = 0; i < Register.Count; i++)
            {
                Model.PropertyNames[Register[i].TargetName] = Register[i].PropertyName;
            }
            for (int i = 0; i < Project.DMA.Count; i++)
            {
                Model.PropertyNames[Project.DMA[i].TargetName] = Project.DMA[i].PropertyName;
            }
            System.IO.File.WriteAllText(Path, Newtonsoft.Json.JsonConvert.SerializeObject(Model));
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "c#代码|*.cs";
            var result = dialog.ShowDialog();
            if(result.HasValue && result.Value)
            {
                System.IO.File.WriteAllText(dialog.FileName, v);
            }
        }

        public ICommand OpenFileCommand => new DelegateCommand(OpenFile);
        private void OpenFile()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "Fpga固件|*.lvbitx";
            var result = dialog.ShowDialog();
            if(result.HasValue && result.Value)
            {
                var lvbitx = NIFPGA.lvbitx.Parse.ParseFile(dialog.FileName);
                Project.UpdateProject(lvbitx.Project);
                for(int i=0;i<Project.DMA.Count;i++)
                {
                    if (!Model.PropertyNames.ContainsKey(Project.DMA[i].TargetName)) continue;
                    Project.DMA[i].PropertyName = Model.PropertyNames[Project.DMA[i].TargetName];
                }
                Register.Clear();
                lvbitx.VI.Registers.ForEach(x => Register.Add(RegisterViewModel.GetRegisterViewModel(x,Model.PropertyNames.ContainsKey(x.Name)? Model.PropertyNames[x.Name]:"")));
                VIName = lvbitx.VI.Name;
                LastTime = System.IO.File.GetLastWriteTime(dialog.FileName);
            }
        }
        public DateTime LastTime { get => lastTime; set =>UpdateProperty(ref lastTime , value); }
        public string NamespaceName { get => Model.NamespaceName; set =>UpdateProperty(ref Model.NamespaceName, value); }
        public string ClassName { get => Model.ClassName; set =>UpdateProperty(ref Model.ClassName , value); }
        public ProjectViewModel Project { get; } = new ProjectViewModel();
        public string VIName { get => vIName; set =>UpdateProperty(ref vIName , value); }
        public static MainViewModel Instance { get; } = new MainViewModel();
        public ObservableCollection<RegisterViewModel> Register { get; } = new ObservableCollection<RegisterViewModel>();
    }

}
