using ATS.Models;
using ATS.Tools;
using MahApps.Metro.Controls;
using MathNet.Numerics;
using Microsoft.Win32;
using Newtonsoft.Json;
using PropertyChanged;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace ATS.Windows
{
///
/// MainWindow.xaml 的交互逻辑
///
[AddINotifyPropertyChangedInterface]
public partial class MainWindow : MetroWindow
{
public static MainWindow Instance { get; set; }
private ProgramModel _program = new();
public ProgramModel Program
{
get
{
return _program;
}
set
{
_program.StepCollection.CollectionChanged -= StepCollectionIndexChanged;
_program = value;
_program.StepCollection.CollectionChanged += StepCollectionIndexChanged;
}
}
public UserModel User { get; set; } = new();
public string? CurrentFilePath { get; set; } = "";
public StepModel? SelectedStep { get; set; }
public MainWindow()
{
Instance = this;
InitializeComponent();
DataContext = this;
User = new()
{
UserName = "开发者",
UserAccount = "Developer",
Role = 2
};
}
public MainWindow(UserModel user)
{
Instance = this;
InitializeComponent();
DataContext = this;
User = user;
}
private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
{
Directory.CreateDirectory(SystemConfig.Instance.SystemPath);
Program = new();
}
#region 辅助方法
///
/// 根据序号重新对步骤进行排序
///
private void ReOrderProgramList()
{
for (int i = 0; i < Program.StepCollection.Count; i++)
{
Program.StepCollection[i].Index = i + 1;
}
}
#endregion
private void StepCollectionIndexChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Reset
|| e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Move)
{
ReOrderProgramList();
}
}
private void LogOut_Click(object sender, RoutedEventArgs e)
{
new Login().Show();
this.Close();
}
private void UserManage_Click(object sender, RoutedEventArgs e)
{
if (User.Role != 2)
{
MessageBox.Show("当前登录用户无权限");
return;
}
new UsersManage().ShowDialog();
}
private Stack _parentProgramStack = new();
private Stack _programPathStack = new(); // 用于显示标题路径
private Stack _currentSubProgramNameStack = new(); // 专门存储当前子程序的名称
private bool _isInSubProgramMode = false;
// 添加一个属性来获取当前程序名称(用于显示)
public string CurrentProgramDisplayName
{
get
{
if (_isInSubProgramMode && _currentSubProgramNameStack.Count > 0)
{
return _currentSubProgramNameStack.Peek();
}
else if (!string.IsNullOrEmpty(CurrentFilePath))
{
return System.IO.Path.GetFileName(CurrentFilePath);
}
return "NewProgram.ats"; // 默认名称
}
}
public void EnterSubProgramMode(ProgramModel subProgram, string subProgramName, StepModel parentStep)
{
// 保存当前状态
_parentProgramStack.Push(Program);
_programPathStack.Push(Title); // 保存当前标题/路径
_currentSubProgramNameStack.Push(subProgramName); // 保存当前子程序的名称
_parentStepStack.Push(parentStep); // 保存父步骤引用,用于保存时回写
// 进入子程序编辑模式 - 使用传入的 subProgram(确保它是副本)
Program = new ProgramModel(subProgram);
_isInSubProgramMode = true;
// 更新标题显示当前路径
string parentPath = _programPathStack.Count > 0 ? _programPathStack.Peek() : "主程序";
Title = $"{parentPath} > {subProgramName}";
// 通知 StepsManager 更新 Title 显示子程序名称
ATS.Views.StepsManager.Instance?.UpdateTitle(subProgramName);
}
public void ExitSubProgramMode()
{
if (_parentProgramStack.Count > 0)
{
// 先保存当前子程序的更改回父程序的对应步骤
SaveCurrentSubProgramBackToParent();
// 恢复父程序
Program = _parentProgramStack.Pop();
// 恢复其他状态
if (_programPathStack.Count > 0)
{
Title = _programPathStack.Pop();
}
else
{
Title = "ATS_MainWindow";
}
if (_currentSubProgramNameStack.Count > 0)
{
_currentSubProgramNameStack.Pop(); // 移除当前子程序名称
}
if (_parentStepStack.Count > 0)
{
_parentStepStack.Pop(); // 移除父步骤引用
}
_isInSubProgramMode = _parentProgramStack.Count > 0; // 根据栈是否为空判断是否还在子程序模式
// 通知 StepsManager 更新 Title(返回主程序或上一层子程序)
if (_isInSubProgramMode && _currentSubProgramNameStack.Count > 0)
{
// 如果还在子程序模式中(多层嵌套),显示上一层子程序名称
ATS.Views.StepsManager.Instance?.UpdateTitle(_currentSubProgramNameStack.Peek());
}
else
{
// 返回主程序
ATS.Views.StepsManager.Instance?.UpdateTitle();
}
}
}
// 需要一个方法来知道当前编辑的是哪个父步骤的子程序,以便保存
// 我们需要在进入子程序模式时也保存父步骤的引用
private Stack _parentStepStack = new(); // 添加这个栈
private void SaveCurrentSubProgramBackToParent()
{
if (_parentStepStack.Count > 0)
{
var parentStep = _parentStepStack.Peek();
if (parentStep.SubProgram != null)
{
// 将当前编辑的 Program (即子程序) 保存回父步骤的 SubProgram
// 注意:这里我们只更新 SubProgram 的内容,不改变其引用
// 如果 SubProgram 有 Name 等元数据,需要单独处理(但根据 ATS 文件结构,似乎没有)
parentStep.SubProgram = new ProgramModel(Program); // 创建一个新副本赋值回去
Log.Success($"用户 [ {User.UserName} ] 更新子程序 [ {parentStep.Name} ] ");
}
}
}
// 保持这些属性
public bool IsInSubProgramMode => _isInSubProgramMode;
public int SubProgramLevel => _parentProgramStack.Count; // 当前嵌套层级
}
}