00001 using System; 00002 using System.IO; 00003 using System.Windows; 00004 using System.Windows.Threading; 00005 using Microsoft.Win32; 00006 using SpaceFlight.Simulation; 00007 00008 using System.Linq; 00009 00010 namespace SpaceFlight.GUI 00011 { 00012 public partial class MainWindow : Window 00013 { 00014 private DispatcherTimer timer; 00015 private TestCase testCase; 00016 private IShipController aiController; 00017 private IShipController controller; 00018 private DateTime simulationStart; 00019 00020 public MainWindow() 00021 { 00022 InitializeComponent(); 00023 00024 timer = new DispatcherTimer(); 00025 timer.Interval = TimeSpan.FromMilliseconds(40); 00026 timer.Tick += Timer_Tick; 00027 } 00028 00029 void Timer_Tick(object sender, EventArgs e) 00030 { 00031 int targetSteps = (int)((DateTime.Now - simulationStart).TotalMilliseconds / 40); 00032 testCase.Simulate(controller, targetSteps - testCase.TimeSteps); 00033 if (!testCase.IsActive) 00034 { 00035 StopSimulation(); 00036 } 00037 Time.Text = String.Format("Time: {0} s", testCase.TimeSteps / 25.0); 00038 Waypoints.Text = String.Format("Waypoints: {0} / {1}", testCase.TargetWaypoint, testCase.Waypoints.Count); 00039 View.InvalidateVisual(); 00040 } 00041 00042 private void LoadButton_Click(object sender, RoutedEventArgs e) 00043 { 00044 var dialog = new OpenFileDialog(); 00045 dialog.Filter = "Test case files|*.txt"; 00046 dialog.InitialDirectory = Directory.GetCurrentDirectory(); 00047 if (dialog.ShowDialog() == true) 00048 { 00049 try 00050 { 00051 SetTestCase(TestCase.Load(dialog.FileName)); 00052 SaveButton.IsEnabled = true; 00053 StartButton.IsEnabled = controller != null; 00054 } 00055 catch (Exception) 00056 { 00057 MessageBox.Show("Error loading test case.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 00058 } 00059 } 00060 } 00061 00062 private void RandomButton_Click(object sender, RoutedEventArgs e) 00063 { 00064 int numPlanets, numWaypoints; 00065 if (!int.TryParse(RandomPlanets.Text, out numPlanets) || numPlanets < 0) 00066 { 00067 MessageBox.Show("Invalid number of planets.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 00068 return; 00069 } 00070 if (!int.TryParse(RandomWaypoints.Text, out numWaypoints) || numWaypoints < 1) 00071 { 00072 MessageBox.Show("Invalid number of waypoints.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 00073 return; 00074 } 00075 SetTestCase(TestCase.CreateRandom(numPlanets, numWaypoints)); 00076 SaveButton.IsEnabled = true; 00077 StartButton.IsEnabled = controller != null; 00078 } 00079 00080 private void SetTestCase(TestCase testCase) 00081 { 00082 testCase.Reset(); 00083 testCase.TraceMovement = TraceMovement.IsChecked == true; 00084 this.testCase = testCase; 00085 View.TestCase = testCase; 00086 View.InvalidateVisual(); 00087 Time.Text = string.Empty; 00088 Waypoints.Text = string.Empty; 00089 } 00090 00091 private void SaveButton_Click(object sender, RoutedEventArgs e) 00092 { 00093 var dialog = new SaveFileDialog(); 00094 dialog.InitialDirectory = Directory.GetCurrentDirectory(); 00095 dialog.Filter = "Test case files|*.txt"; 00096 if (dialog.ShowDialog() == true) 00097 { 00098 try 00099 { 00100 TestCase.Save(testCase, dialog.FileName); 00101 } 00102 catch (Exception) 00103 { 00104 MessageBox.Show("Error saving test case.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 00105 } 00106 } 00107 } 00108 00109 private void ManualFlight_Click(object sender, RoutedEventArgs e) 00110 { 00111 if (ManualFlight.IsChecked != true) 00112 { 00113 LoadAI.IsEnabled = true; 00114 controller = aiController; 00115 } 00116 else 00117 { 00118 LoadAI.IsEnabled = false; 00119 controller = new MouseShipController(View); 00120 } 00121 StartButton.IsEnabled = testCase != null && controller != null; 00122 } 00123 00124 private void LoadAI_Click(object sender, RoutedEventArgs e) 00125 { 00126 var dialog = new OpenFileDialog(); 00127 dialog.InitialDirectory = Directory.GetCurrentDirectory(); 00128 if (dialog.ShowDialog() == true) 00129 { 00130 using (var stream = new StreamReader(dialog.FileName)) 00131 { 00132 try 00133 { 00134 aiController = new AiShipController(stream.ReadToEnd()); 00135 controller = aiController; 00136 } 00137 catch 00138 { 00139 MessageBox.Show("Error loading AI.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 00140 } 00141 } 00142 } 00143 StartButton.IsEnabled = testCase != null; 00144 } 00145 00146 private void TraceMovement_Click(object sender, RoutedEventArgs e) 00147 { 00148 if (testCase != null) 00149 { 00150 testCase.TraceMovement = TraceMovement.IsChecked == true; 00151 } 00152 } 00153 00154 private void StartButton_Click(object sender, RoutedEventArgs e) 00155 { 00156 LoadButton.IsEnabled = false; 00157 RandomButton.IsEnabled = false; 00158 SaveButton.IsEnabled = false; 00159 ManualFlight.IsEnabled = false; 00160 LoadAI.IsEnabled = false; 00161 TraceMovement.IsEnabled = false; 00162 00163 StartButton.Visibility = Visibility.Collapsed; 00164 StopButton.Visibility = Visibility.Visible; 00165 00166 testCase.Reset(); 00167 simulationStart = DateTime.Now; 00168 timer.Start(); 00169 } 00170 00171 private void StopButton_Click(object sender, RoutedEventArgs e) 00172 { 00173 StopSimulation(); 00174 } 00175 00176 private void StopSimulation() 00177 { 00178 timer.Stop(); 00179 00180 LoadButton.IsEnabled = true; 00181 RandomButton.IsEnabled = true; 00182 SaveButton.IsEnabled = true; 00183 ManualFlight.IsEnabled = true; 00184 LoadAI.IsEnabled = ManualFlight.IsChecked != true; 00185 TraceMovement.IsEnabled = true; 00186 00187 StopButton.Visibility = Visibility.Collapsed; 00188 StartButton.Visibility = Visibility.Visible; 00189 } 00190 } 00191 }