using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows.Input; using System.Windows.Media.Media3D; using WpfEngineeringSketch.Commands; using WpfEngineeringSketch.Models.Scene; using WpfEngineeringSketch.Tools3D; namespace WpfEngineeringSketch.ViewModels { public class MainViewModel : ViewModelBase { private BlockType _selectedBlockType; private SceneObject? _selectedObject; private I3DTool _currentTool = null!; public ObservableCollection Objects { get; } = new ObservableCollection(); // Expose all block types for the ComboBox public IEnumerable BlockTypes { get; } = Enum.GetValues(); public BlockType SelectedBlockType { get => _selectedBlockType; set { if (SetProperty(ref _selectedBlockType, value)) { // Auto-switch to Place Tool for building types unless already path-building if ((value == BlockType.CMUWall || value == BlockType.Column || value == BlockType.Beam || value == BlockType.Connection) && !(CurrentTool is PathTool3D)) { CurrentTool = new PlaceTool3D(); } } } } public ObservableCollection SelectedObjects { get; } = new ObservableCollection(); public SceneObject? SelectedObject { get => _selectedObject; set => SetProperty(ref _selectedObject, value); } private bool _showSmartPlacementHints = true; public bool ShowSmartPlacementHints { get => _showSmartPlacementHints; set => SetProperty(ref _showSmartPlacementHints, value); } public I3DTool CurrentTool { get => _currentTool; set { if (_currentTool != value) { _currentTool?.Deactivate(this); _currentTool = value; _currentTool?.Activate(this); OnPropertyChanged(); } } } public ICommand AddBlockCommand { get; } public ICommand DeleteBlockCommand { get; } public ICommand SelectToolCommand { get; } public ICommand PathToolCommand { get; } public ICommand PlaceToolCommand { get; } public ICommand MoveToolCommand { get; } public ICommand AddWallOnGridCommand { get; } public MainViewModel() { AddBlockCommand = new RelayCommand(_ => AddBlock()); DeleteBlockCommand = new RelayCommand(_ => DeleteBlock()); AddWallOnGridCommand = new RelayCommand(_ => AddWallOnGrid()); SelectToolCommand = new RelayCommand(_ => CurrentTool = new SelectTool3D()); PathToolCommand = new RelayCommand(_ => CurrentTool = new PathTool3D()); PlaceToolCommand = new RelayCommand(_ => ExecutePlaceOrBuild()); MoveToolCommand = new RelayCommand(_ => CurrentTool = new MoveTool3D()); // Default tool CurrentTool = new SelectTool3D(); // Add a sample object Objects.Add(new SceneObject { Type = BlockType.Cube, Position = new Point3D(0, 0.5, 0) }); // Add sample grid lines // Line along X Objects.Add(new SceneObject { Type = BlockType.GridLine, Position = new Point3D(0, 0, 5), Rotation = new Vector3D(0, 0, 90), Scale = new Vector3D(1, 1, 1) }); // Line along Z Objects.Add(new SceneObject { Type = BlockType.GridLine, Position = new Point3D(5, 0, 0), Rotation = new Vector3D(90, 0, 0), Scale = new Vector3D(1, 1, 1) }); // Intersecting lines at origin Objects.Add(new SceneObject { Type = BlockType.GridLine, Position = new Point3D(0, 0, 0), Rotation = new Vector3D(0, 0, 90) }); Objects.Add(new SceneObject { Type = BlockType.GridLine, Position = new Point3D(0, 0, 0), Rotation = new Vector3D(90, 0, 0) }); } private void AddWallOnGrid() { foreach (var obj in SelectedObjects.ToList()) { if (obj.Type == BlockType.GridLine) { var wall = new SceneObject { Type = BlockType.CMUWall, Position = obj.Position, }; Objects.Add(wall); } } } private void AddBlock() { var newObj = new SceneObject { Type = SelectedBlockType, Position = new Point3D(0, 2, 0) }; Objects.Add(newObj); SelectedObject = newObj; } private void DeleteBlock() { if (SelectedObject != null) { Objects.Remove(SelectedObject); SelectedObject = null; } } private void ExecutePlaceOrBuild() { if (CurrentTool is PathTool3D && SelectedObjects.Any(o => o.Type == BlockType.GridLine)) { AddWallOnGrid(); foreach (var obj in SelectedObjects.ToList()) obj.IsSelected = false; SelectedObjects.Clear(); } else { CurrentTool = new PlaceTool3D(); } } } }