-
Notifications
You must be signed in to change notification settings - Fork 0
/
MainWindow.xaml.cs
342 lines (298 loc) · 12.4 KB
/
MainWindow.xaml.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using System.IO;
using System.Windows.Media.Imaging;
namespace CookBook
{
/// <summary>
/// The main window of the application, which handles user interactions for managing recipes.
/// </summary>
public partial class MainWindow : Window
{
// Constants as per requirements
private const int MaxNumOfIngredients = 50;
private const int MaxNumOfRecipes = 200;
// Class-level variables
private Recipe currRecipe;
private readonly RecipeManager recipeManager;
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class and sets up the user interface.
/// </summary>
public MainWindow()
{
InitializeComponent();
// Initialize the recipe manager
recipeManager = new RecipeManager();
// Initialize current recipe
currRecipe = new Recipe(MaxNumOfIngredients);
// Populate the category combo box with enum values
cmbCategory.ItemsSource = Enum.GetValues(typeof(FoodCategory));
cmbCategory.SelectedIndex = 0;
// Set the ListBox's DisplayMemberPath to show recipe names
lstRecipes.DisplayMemberPath = "Name";
// Load existing recipes into the ListBox
RefreshRecipeList();
}
/// <summary>
/// Handles the click event for adding ingredients to the current recipe.
/// </summary>
private void AddIngredientsButton_Click(object sender, RoutedEventArgs e)
{
// Validate recipe name
if (string.IsNullOrWhiteSpace(txtRecipeName.Text))
{
MessageBox.Show("Please enter a recipe name first.", "Input Required",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// Update current recipe with form data
currRecipe.Name = txtRecipeName.Text;
currRecipe.Category = (FoodCategory)cmbCategory.SelectedItem;
// Create and show the ingredients form
var detailsForm = new FormRecipeDetails(currRecipe);
if (detailsForm.ShowDialog() == true)
{
// Update current recipe with the modified recipe from details form
currRecipe = detailsForm.Recipe;
}
}
/// <summary>
/// Handles category selection changes. This event is auto-handled by the ComboBox in the constructor.
/// </summary>
private void cmbCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
/// <summary>
/// Handles text changes in the recipe name field.
/// </summary>
private void txtRecipeName_TextChanged(object sender, TextChangedEventArgs e)
{
}
/// <summary>
/// Handles the click event for adding the current recipe to the recipe manager.
/// </summary>
private void AddRecipeButton_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(txtRecipeName.Text))
{
MessageBox.Show("Please enter a recipe name.", "Input Required",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (!currRecipe.HasIngredients())
{
MessageBox.Show("Please add ingredients to the recipe.", "Input Required",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (currRecipe.Id > 0)
{
// Update existing recipe
currRecipe.Name = txtRecipeName.Text;
currRecipe.Category = (FoodCategory)cmbCategory.SelectedItem;
currRecipe.Instructions = txtInstructions.Text;
if (recipeManager.UpdateRecipe(currRecipe))
{
MessageBox.Show("Recipe updated successfully.", "Success",
MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
MessageBox.Show("Failed to update the recipe.", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
else
{
// Add new recipe
currRecipe.Name = txtRecipeName.Text;
currRecipe.Category = (FoodCategory)cmbCategory.SelectedItem;
if (recipeManager.AddRecipe(currRecipe))
{
MessageBox.Show("Recipe added successfully.", "Success",
MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
MessageBox.Show("Cannot add more recipes. Maximum limit reached.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// Refresh the list and clear the form
RefreshRecipeList();
ClearForm();
currRecipe = new Recipe(MaxNumOfIngredients);
}
/// <summary>
/// Handles the selection change event for the recipe ListBox, updating the display with the selected recipe details.
/// </summary>
private void RecipeListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lstRecipes.SelectedIndex >= 0)
{
var selectedRecipe = recipeManager.GetRecipe(lstRecipes.SelectedIndex);
if (selectedRecipe != null)
{
// Update current recipe reference
currRecipe = new Recipe(selectedRecipe); // Use copy constructor to avoid modifying the original before confirmation
// Populate the form fields with the selected recipe's data
txtRecipeName.Text = currRecipe.Name;
cmbCategory.SelectedItem = currRecipe.Category;
// Load instructions and ingredients into the instructions TextBox
txtInstructions.Text = $"INGREDIENTS\n" +
$"{string.Join("\n", currRecipe.GetIngredients())}\n\n" +
$"INSTRUCTIONS\n" +
$"{currRecipe.Instructions}";
// Load the image if available
if (currRecipe.ImageData != null)
{
using (var ms = new MemoryStream(currRecipe.ImageData))
{
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
imgRecipeImage.Source = bitmap;
}
}
else
{
imgRecipeImage.Source = null; // Set to null if no image is present
}
}
}
}
/// <summary>
/// Handles the click event for changing the selected recipe in the ListBox.
/// </summary>
private void ChangeRecipe_Click(object sender, RoutedEventArgs e)
{
if (lstRecipes.SelectedIndex >= 0)
{
var selectedRecipeIndex = lstRecipes.SelectedIndex;
// Update current recipe with the modified data
if (string.IsNullOrWhiteSpace(txtRecipeName.Text))
{
MessageBox.Show("Recipe name cannot be empty.", "Input Required",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// Update the current recipe's properties
currRecipe.Name = txtRecipeName.Text;
currRecipe.Category = (FoodCategory)cmbCategory.SelectedItem;
currRecipe.Instructions = txtInstructions.Text; // This should contain only the instructions text
// Update the database
if (recipeManager.UpdateRecipe(currRecipe))
{
MessageBox.Show("Recipe updated successfully.", "Success",
MessageBoxButton.OK, MessageBoxImage.Information);
// Refresh the recipe list to reflect changes
RefreshRecipeList();
// Reselect the updated recipe in the ListBox
lstRecipes.SelectedIndex = selectedRecipeIndex;
}
else
{
MessageBox.Show("Failed to update the recipe.", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
}
}
else
{
MessageBox.Show("Please select a recipe to change.", "Selection Required",
MessageBoxButton.OK, MessageBoxImage.Information);
}
}
/// <summary>
/// Handles the click event for deleting the selected recipe from the ListBox.
/// </summary>
private void DeleteRecipe_Click(object sender, RoutedEventArgs e)
{
if (lstRecipes.SelectedIndex >= 0)
{
if (MessageBox.Show("Are you sure you want to delete this recipe?",
"Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
recipeManager.RemoveRecipe(lstRecipes.SelectedIndex);
RefreshRecipeList();
ClearForm();
}
}
else
{
MessageBox.Show("Please select a recipe to delete.", "Selection Required",
MessageBoxButton.OK, MessageBoxImage.Information);
}
}
/// <summary>
/// Handles the click event for clearing the form inputs.
/// </summary>
private void ClearInputButton_Click(object sender, RoutedEventArgs e)
{
ClearForm();
currRecipe = new Recipe(MaxNumOfIngredients);
}
/// <summary>
/// Handles the click event for adding an image to the recipe (currently not implemented).
/// </summary>
private void AddImageButton_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
openFileDialog.Filter = "Image files (*.png;*.jpeg;*.jpg)|*.png;*.jpeg;*.jpg|All files (*.*)|*.*";
if (openFileDialog.ShowDialog() == true)
{
string filePath = openFileDialog.FileName;
// Convert image to byte[]
currRecipe.ImageData = File.ReadAllBytes(filePath);
// Load the image into the UI element
imgRecipeImage.Source = new BitmapImage(new Uri(filePath));
}
}
/// <summary>
/// Clears the form input fields.
/// </summary>
private void ClearForm()
{
txtRecipeName.Clear();
cmbCategory.SelectedIndex = 0;
txtInstructions.Text = "Instructions will be displayed here...";
lstRecipes.SelectedIndex = -1;
}
/// <summary>
/// Refreshes the recipe list by reloading all recipes from the manager into the ListBox.
/// </summary>
private void RefreshRecipeList()
{
lstRecipes.Items.Clear();
int numOfRecipes = recipeManager.GetNumOfRecipes(); // Get the number of recipes from the database
for (int i = 0; i < numOfRecipes; i++)
{
var recipe = recipeManager.GetRecipe(i); // Retrieve each recipe by index
if (recipe != null)
{
lstRecipes.Items.Add(recipe);
}
}
}
}
/// <summary>
/// Enumeration representing different categories of food for recipes.
/// </summary>
public enum FoodCategory
{
Meat,
Pasta,
Pizza,
Fish,
Seafood,
Soups,
Stew,
Vegan,
Vegetarian,
Other
}
}