using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Input; using Ookii.Dialogs.Wpf; using System.Collections.ObjectModel; using System.Windows.Media; using System.Windows.Media.Imaging; using static System.Runtime.InteropServices.JavaScript.JSType; using System.Windows.Threading; using CtrEditor.ObjetosSim; using CtrEditor.Siemens; using System.IO; // using System.Windows.Forms; using System.Text.Json.Serialization; using System.Text.Json; using Newtonsoft.Json; using System.Windows.Data; using System.Windows; using static System.Resources.ResXFileRef; using CtrEditor.Convertidores; using CtrEditor.Simulacion; namespace CtrEditor { public class MainViewModel : INotifyPropertyChanged { public DatosDeTrabajo datosDeTrabajo { get; } public ObservableCollection listaImagenes { get; private set; } // Publicación de las claves del diccionario public ObservableCollection ListaOsBase { get; } = new ObservableCollection(); private ObservableCollection _objetosSimulables = new ObservableCollection(); public PLCViewModel _plcViewModelData; public SimulationManagerFP simulationManager = new SimulationManagerFP(); private readonly DispatcherTimer _timerSimulacion; public ICommand StartSimulationCommand { get; } public ICommand StopSimulationCommand { get; } public ICommand ItemDoubleClickCommand { get; private set; } // Evento que se dispara cuando se selecciona una nueva imagen public event EventHandler ImageSelected; public event EventHandler TickSimulacion; public event Action OnUserControlSelected; public MainViewModel() { OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory); datosDeTrabajo = new DatosDeTrabajo(); // Inicializa el PLCViewModel _plcViewModelData = new PLCViewModel(); InitializeTipoSimulableList(); ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick); _timerSimulacion = new DispatcherTimer(); _timerSimulacion.Interval = TimeSpan.FromMilliseconds(16); // ajusta el intervalo según sea necesario _timerSimulacion.Tick += OnTickSimulacion; StartSimulationCommand = new RelayCommand(StartSimulation); StopSimulationCommand = new RelayCommand(StopSimulation); } public void LoadInitialData() { // Suponiendo que "SelectedImage" es una propiedad que al establecerse dispara "ImageSelected" directorioTrabajo = EstadoPersistente.Instance.directorio; } private TipoSimulable _selectedItem = null; public TipoSimulable SelectedItem { get => _selectedItem; set { if (_selectedItem != value) { _selectedItem = value; OnPropertyChanged(nameof(SelectedItem)); // Notificar que la propiedad ha cambiado } } } private void ExecuteDoubleClick(object parameter) { if (parameter is TipoSimulable tipoSimulable) { // Crear una nueva instancia del osBase correspondiente osBase? newosBase = UserControlFactory.GetInstanceForType(tipoSimulable.Tipo); if (newosBase != null) { if (CrearUsercontrol(newosBase)) // Añadir el nuevo osBase a la colección de objetos simulables ObjetosSimulables.Add(newosBase); } } } private void InitializeTipoSimulableList() { var baseType = typeof(osBase); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(assembly => assembly.GetTypes()) .Where(type => type.IsSubclassOf(baseType) && !type.IsAbstract); foreach (var type in types) { ListaOsBase.Add(new TipoSimulable { Nombre = type.Name, Tipo = type }); } } private void StartSimulation() { foreach (var objetoSimulable in ObjetosSimulables) objetoSimulable.UpdateGeometryStart(); simulationManager.Debug_DrawInitialBodies(); _timerSimulacion.Start(); simulationManager.stopwatch.Start(); } private void StopSimulation() { _timerSimulacion.Stop(); simulationManager.stopwatch.Stop(); } private void OnTickSimulacion(object sender, EventArgs e) { foreach (var objetoSimulable in ObjetosSimulables) { if (_plcViewModelData.IsConnected) objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface); objetoSimulable.UpdateGeometryStep(); } simulationManager.Step(); foreach (var objetoSimulable in ObjetosSimulables) objetoSimulable.UpdateControl(); } //protected virtual void OnTickSimulacion(TickSimulacionEventArgs e) //{ // TickSimulacion?.Invoke(this, e); //} public string directorioTrabajo { get => EstadoPersistente.Instance.directorio; set { if (value != null) { EstadoPersistente.Instance.directorio = value; // Actualizar el estado persistente EstadoPersistente.Instance.GuardarEstado(); // Guardar el estado actualizado datosDeTrabajo.CargarImagenes(); listaImagenes = new ObservableCollection(datosDeTrabajo.Imagenes.Keys); // Actualizar claves SelectedImage = null; if (listaImagenes.FirstOrDefault() != null) SelectedImage = listaImagenes.FirstOrDefault(); OnPropertyChanged(nameof(directorioTrabajo)); // Notificar el cambio de propiedad OnPropertyChanged(nameof(listaImagenes)); // Notificar que la lista de imágenes ha cambiado } } } public PLCViewModel PLCViewModel { get { return _plcViewModelData; } set { _plcViewModelData = value; OnPropertyChanged(nameof(PLCViewModel)); } } private string _selectedImage = null; public string SelectedImage { get => _selectedImage; set { if (_selectedImage != value && value != null) { StopSimulation(); SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen _selectedImage = value; ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]); // Dispara el evento con la nueva ruta de imagen LoadStateObjetosSimulables(); } _selectedImage = value; OnPropertyChanged(nameof(SelectedImage)); } } private osBase _selectedItemOsList; public osBase SelectedItemOsList { get => _selectedItemOsList; set { if (_selectedItemOsList != value) { _selectedItemOsList = value; OnPropertyChanged(nameof(SelectedItemOsList)); } } } public ICommand OpenWorkDirectoryCommand { get; } private void OpenWorkDirectory() { var dialog = new VistaFolderBrowserDialog(); if (dialog.ShowDialog() == true) // Mostrar el diálogo y comprobar si el resultado es positivo { directorioTrabajo = dialog.SelectedPath; // Actualizar la propiedad que también actualiza el estado persistente } } // // Lista de osBase // public ObservableCollection ObjetosSimulables { get => _objetosSimulables; set { if (_objetosSimulables != value) { _objetosSimulables = value; OnPropertyChanged(nameof(ObjetosSimulables)); } } } public void SaveStateObjetosSimulables() { if (_selectedImage != null) { var settings = new JsonSerializerSettings { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.Auto }; foreach (var obj in ObjetosSimulables) { obj.VisualRepresentation = null; obj.simulationManager = null; } // Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter var dataToSerialize = new SimulationData { ObjetosSimulables = ObjetosSimulables, UnitConverter = PixelToMeter.Instance.calc, PLC_ConnectionData = PLCViewModel }; var serializedData = JsonConvert.SerializeObject(dataToSerialize, settings); File.WriteAllText(datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"), serializedData); } } public void LoadStateObjetosSimulables() { try { ObjetosSimulables.Clear(); simulationManager.Clear(); if (_selectedImage != null) { string jsonPath = datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"); if (File.Exists(jsonPath)) { string jsonString = File.ReadAllText(jsonPath); var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, ObjectCreationHandling = ObjectCreationHandling.Replace, PreserveReferencesHandling = PreserveReferencesHandling.Objects, ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; var simulationData = JsonConvert.DeserializeObject(jsonString, settings); if (simulationData != null) { if (simulationData.ObjetosSimulables is not null) ObjetosSimulables = simulationData.ObjetosSimulables; if (simulationData.PLC_ConnectionData is not null) PLCViewModel = simulationData.PLC_ConnectionData; else PLCViewModel = new PLCViewModel(); PixelToMeter.Instance.calc = simulationData.UnitConverter; // Recorrer la colección de objetos simulables foreach (var objetoSimulable in ObjetosSimulables) CrearUsercontrol(objetoSimulable); } } } } catch { /* Consider logging the error or handling it appropriately */ } } private bool CrearUsercontrol(osBase osObjeto) { Type tipoObjeto = osObjeto.GetType(); // Obtén el UserControl correspondiente para el tipo de objeto UserControl? userControl = UserControlFactory.GetControlForType(tipoObjeto); if (userControl != null) { // Asignar los datos al UserControl UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager); OnUserControlSelected?.Invoke(userControl); return true; } return false; } // Implementación de INotifyPropertyChanged... public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class SimulationData { public ObservableCollection ObjetosSimulables { get; set; } public UnitConverter UnitConverter { get; set; } public PLCViewModel PLC_ConnectionData { get; set; } } public class TipoSimulable { public string Nombre { get; set; } public Type Tipo { get; set; } } public class TickSimulacionEventArgs : EventArgs { // Aquí puedes agregar propiedades o campos para pasar información adicional // en el evento TickSimulacion } }