00001
00002 using System;
00003 using Foodolini.Activities;
00004 using Gtk;
00005 using Foodolini.BusinessLogic;
00006 using System.Collections.Generic;
00007
00008 namespace Foodolini.Activities.Cookbook
00009 {
00010
00014 [FoodoliniActivity("View recipe", true)]
00015 [System.ComponentModel.ToolboxItem(true)]
00016 public partial class RecipeViewer : Gtk.Bin, IActivity
00017 {
00018 private IOwner owner;
00019 private Recipe recipe;
00020 private Gdk.Pixbuf pxStarHide = Gdk.Pixbuf.LoadFromResource("StarHide.png");
00021 private Gdk.Pixbuf pxStar = Gdk.Pixbuf.LoadFromResource("Star.png");
00022 private NodeStore ingredientStorage = new NodeStore(typeof(IngredientAdapter));
00023 private Dictionary<Ingredient, double> ingredientSave = new Dictionary<Ingredient, double>();
00024 private List<FoodItem> fooditemsStorage;
00025
00026 private Image star1;
00027 private Image star2;
00028 private Image star3;
00029 private Image star4;
00030 private Image star5;
00031 private Image imgRecipeBigVersion;
00032
00033
00037 public RecipeViewer()
00038 {
00039 this.Build();
00040 imgRecipeBigVersion = new Image();
00041
00042 fooditemsStorage = new List<FoodItem>(FoodItem.ListFoodItems());
00043
00044 this.Destroyed += HandleDestroyed;
00045
00046 star1 = new Image(pxStarHide);
00047 star2 = new Image(pxStarHide);
00048 star3 = new Image(pxStarHide);
00049 star4 = new Image(pxStarHide);
00050 star5 = new Image(pxStarHide);
00051 btnStar1.Image = star1;
00052 btnStar2.Image = star2;
00053 btnStar3.Image = star3;
00054 btnStar4.Image = star4;
00055 btnStar5.Image = star5;
00056 bxViewRecipe.ShowAll();
00057
00058
00059 btnConsume.Sensitive = false; btnStore.Sensitive = false;
00060 btnAdd2ShoppingList.Sensitive = false;
00061
00062
00063
00064 this.nvIngredients.NodeStore = this.ingredientStorage;
00065 this.nvIngredients.AppendColumn("Ingredients", new CellRendererText(), (tree_column, cell, node)=>{
00066 IngredientAdapter n = (IngredientAdapter)node;
00067 CellRendererText c = (CellRendererText)cell;
00068 c.Text = n.Name;
00069 });
00070 this.nvIngredients.AppendColumn("Quantity (g)", new CellRendererText(), (tree_colum, cell, node)=>{
00071 IngredientAdapter n = (IngredientAdapter)node;
00072 CellRendererText c = (CellRendererText)cell;
00073 c.Text = n.Quantity.ToString();
00074 });
00075 this.nvIngredients.AppendColumn("Storage", new CellRendererText(), (tree_colum, cell, node)=>{
00076 IngredientAdapter n = (IngredientAdapter)node;
00077 CellRendererText c = (CellRendererText)cell;
00078 c.Text = n.Storage;
00079 });
00080
00081 this.nvIngredients.AppendColumn("", new CellRendererText(), (tree_colum, cell, node)=>{
00082 IngredientAdapter n = (IngredientAdapter)node;
00083 CellRendererText c = (CellRendererText)cell;
00084 c.Text = n.Expiration;
00085 });
00086 }
00087
00088 public event EventHandler<RecipeEventArgs> OnRecipeViewed;
00089 public event EventHandler<RecipeEventArgs> OnRecipeEdited;
00090 public event EventHandler<RecipeEventArgs> OnRecipeDeleted;
00091
00092 private void CheckIngredients()
00093 {
00094 BusinessLogic.Settings.Instance.Save();
00095 double temp = 0;
00096 nvIngredients.NodeStore = null;
00097 foreach(IngredientAdapter node in ingredientStorage)
00098 {
00099 node.Quantity = ingredientSave[node.Ingredient] * sbMultiplier.Value;
00100 temp = -node.Quantity;
00101
00102 FoodItem fooditem = node.Ingredient.InStorage();
00103 if(fooditem != null)
00104 {
00105 temp = fooditem.Quantity - node.Quantity;
00106 if((fooditem.ExpirationDate - DateTime.Now).Days < 0)
00107 node.Expiration = "Expired";
00108 }
00109
00110 if (temp < 0)
00111 {
00112 node.Storage = (-temp).ToString() + " g missing";
00113 btnConsume.Sensitive = false; btnStore.Sensitive = false;
00114 }
00115 else if (temp == 0)
00116 {
00117 node.Storage = temp.ToString();
00118 btnConsume.Sensitive = true; btnStore.Sensitive = true;
00119 }
00120 else if(temp > 0)
00121 {
00122 node.Storage = temp.ToString() + " g remaining";
00123 btnConsume.Sensitive = true; btnStore.Sensitive = true;
00124 }
00125 }
00126 this.nvIngredients.NodeStore = this.ingredientStorage;
00127 bxViewRecipe.ShowAll();
00128 }
00129
00133 void HandleDestroyed(object sender, EventArgs e)
00134 {
00135 this.star1.Dispose();
00136 this.star2.Dispose();
00137 this.star3.Dispose();
00138 this.star4.Dispose();
00139 this.star5.Dispose();
00140 if(this.recipe.Picture != null)
00141 this.imgRecipe.Image.Dispose();
00142 if(imgRecipeBigVersion.Pixbuf != null)
00143 this.imgRecipeBigVersion.Dispose();
00144 }
00145
00149 protected virtual void OnDeleteRecipeClick (object sender, System.EventArgs e)
00150 {
00151 ConfirmDialog dialog = new ConfirmDialog("Delete recipe", "Are you sure you want to delete " + this.recipe.Title);
00152
00153 if (dialog.Run() == (int)ResponseType.Ok)
00154 {
00155 this.recipe.Delete();
00156 this.Destroy();
00157 if(OnRecipeDeleted != null)
00158 OnRecipeDeleted(this, new RecipeEventArgs(this.recipe));
00159 }
00160 dialog.Destroy();
00161 }
00162
00166 protected virtual void OnSbMultiplierChanged (object sender, System.EventArgs e)
00167 {
00168 CheckIngredients();
00169 }
00170
00175 protected virtual void RateRecipe(object sender, System.EventArgs e){
00176 int rating = 0;
00177
00178 switch(((Button)sender).Name){
00179 case "btnStar1":
00180 rating = 1;
00181 break;
00182 case "btnStar2":
00183 rating = 2;
00184 break;
00185 case "btnStar3":
00186 rating = 3;
00187 break;
00188 case "btnStar4":
00189 rating = 4;
00190 break;
00191 case "btnStar5":
00192 rating = 5;
00193 break;
00194 default:
00195 break;
00196 }
00197
00198 if(this.owner.CurrentUser != null)
00199 {
00200 this.recipe.Rate(this.owner.CurrentUser, rating);
00201 SetRating();
00202 lbAverageRating.Text = this.recipe.AverageRating.ToString("0.00");
00203 this.recipe.Save();
00204 }
00205 if(OnRecipeViewed != null)
00206 OnRecipeViewed(this, new RecipeEventArgs(this.recipe));
00207
00208 }
00209
00216 public void SetParamenters(Recipe recipe){
00217 this.recipe = recipe;
00218 SetRecipeDetails();
00219 SetRating();
00220 CheckUser();
00221
00222 }
00223
00227 private void SetRatingButtons(Gdk.Pixbuf px1, Gdk.Pixbuf px2, Gdk.Pixbuf px3, Gdk.Pixbuf px4, Gdk.Pixbuf px5){
00228
00229 star1.Pixbuf = px1;
00230 star2.Pixbuf = px2;
00231 star3.Pixbuf = px3;
00232 star4.Pixbuf = px4;
00233 star5.Pixbuf = px5;
00234 }
00235
00236 private void SetRating()
00237 {
00238 CheckUser();
00239 if (this.owner.CurrentUser != null)
00240 {
00241 if (this.recipe.Ratings.ContainsKey(this.owner.CurrentUser))
00242 {
00243 double rating = this.recipe.Ratings[this.owner.CurrentUser];
00244 if ( rating == 1)
00245 SetRatingButtons(pxStar,pxStarHide,pxStarHide,pxStarHide,pxStarHide);
00246 else if (rating == 2)
00247 SetRatingButtons(pxStar,pxStar,pxStarHide,pxStarHide,pxStarHide);
00248 else if (rating == 3)
00249 SetRatingButtons(pxStar,pxStar,pxStar,pxStarHide,pxStarHide);
00250 else if(rating == 4)
00251 SetRatingButtons(pxStar,pxStar,pxStar,pxStar,pxStarHide);
00252 else if(rating == 5)
00253 SetRatingButtons(pxStar,pxStar,pxStar,pxStar,pxStar);
00254 }
00255 else
00256 SetRatingButtons(pxStarHide,pxStarHide,pxStarHide,pxStarHide,pxStarHide);
00257 }
00258 else
00259 SetRatingButtons(pxStarHide,pxStarHide,pxStarHide,pxStarHide,pxStarHide);
00260 }
00261
00262 void OwnerhandleCurrentUserChanged (object sender, PersonEventArgs e)
00263 {
00264 SetRating();
00265 }
00266
00267 private void CheckUser()
00268 {
00269 if(this.owner.CurrentUser == null)
00270 {
00271 btnAdd2ShoppingList.Sensitive = false;
00272 btnStar1.Sensitive = false; btnStar2.Sensitive = false;
00273 btnStar3.Sensitive = false; btnStar4.Sensitive = false;
00274 btnStar5.Sensitive = false;
00275 }
00276 else
00277 {
00278 btnAdd2ShoppingList.Sensitive = true;
00279 btnStar1.Sensitive = true; btnStar2.Sensitive = true;
00280 btnStar3.Sensitive = true; btnStar4.Sensitive = true;
00281 btnStar5.Sensitive = true;
00282 }
00283 }
00284
00285 private Button imgRecipe = new Button();
00289 private void SetRecipeDetails(){
00290
00291 lbTitle.Markup = "<big><b>" + recipe.Title + "</b></big>";
00292 imgRecipe.TooltipText="Click for a larger picture of "+recipe.Title;
00293
00294 ingredientStorage.Clear();
00295 ingredientSave.Clear();
00296
00297 foreach(KeyValuePair<Ingredient, double> ingredient in this.recipe.Ingredients)
00298 {
00299 IngredientAdapter ia = new IngredientAdapter(ingredient.Key, ingredient.Value);
00300 this.ingredientStorage.AddNode(ia);
00301 this.ingredientSave.Add(ingredient.Key, ingredient.Value);
00302 }
00303
00304
00305 sbMultiplier.Value = this.recipe.Servings;
00306
00307 CheckIngredients();
00308
00309
00310 string recipeView = "";
00311 foreach(var direction in this.recipe.Directions)
00312 recipeView += direction + "\n";
00313 tvViewRecipe.Buffer.Text = recipeView;
00314
00315
00316 if(recipe.Picture != null)
00317 {
00318 Gdk.Pixbuf pxr = new Gdk.Pixbuf(recipe.Picture);
00319 pxr = pxr.ScaleSimple(100, 100, Gdk.InterpType.Bilinear);
00320 imgRecipe.Image = new Image(pxr);
00321 imgRecipe.Relief = ReliefStyle.None;
00322 imgRecipe.TooltipText = "Opens a bigger version.";
00323 imgRecipe.Clicked += ShowBigVersion;
00324 bxBottom.Add(imgRecipe);
00325 }
00326
00327
00328 lbAverageRating.Text = this.recipe.AverageRating.ToString("0.00");
00329 lbDifficulty.Text = this.recipe.Difficulty.ToString();
00330 TimeSpan preparationTime = this.recipe.PreparationTime;
00331
00332 string prepFormat = string.Empty;
00333
00334 if(preparationTime.Days != 0) {
00335 prepFormat += preparationTime.Days + " day";
00336
00337 if(preparationTime.Days > 1)
00338 prepFormat += "s";
00339
00340 if(preparationTime.Hours != 0 || preparationTime.Minutes != 0)
00341 prepFormat += ", ";
00342
00343 }
00344 if(preparationTime.Hours != 0) {
00345 prepFormat += preparationTime.Hours + " hour";
00346
00347 if(preparationTime.Hours > 1)
00348 prepFormat += "s";
00349
00350 if(preparationTime.Minutes != 0)
00351 prepFormat += ", ";
00352 }
00353 if(preparationTime.Minutes != 0) {
00354 prepFormat +=preparationTime.Minutes + " minute";
00355
00356 if(preparationTime.Minutes > 1)
00357 prepFormat += "s";
00358
00359 }
00360 lbTime.Text = prepFormat;
00361 }
00362
00363 Window w = new Window(WindowType.Toplevel);
00367 protected virtual void ShowBigVersion (object sender, System.EventArgs e)
00368 {
00369 w.Title = this.recipe.Title;
00370 Gdk.Pixbuf pxr = new Gdk.Pixbuf(recipe.Picture);
00371 pxr = pxr.ScaleSimple(500, 500, Gdk.InterpType.Bilinear);
00372 imgRecipeBigVersion.Pixbuf = pxr;
00373 w.Add(imgRecipeBigVersion);
00374 w.ShowAll();
00375 }
00376
00377 #region New activities
00382 protected virtual void OnConsumeClick (object sender, System.EventArgs e)
00383 {
00384 Dictionary<Person, double> users = new Dictionary<Person, double>();
00385 double leftover = 100;
00386 FoodItem foodItem = null;
00387 UserSelector dialog = new UserSelector();
00388 if (dialog.Run() == (int)ResponseType.Ok)
00389 {
00390 users = dialog.GetUsers();
00391
00392 foreach(KeyValuePair<Person, double> user in users)
00393 {
00394 leftover -= user.Value;
00395 foodItem = this.recipe.Cook(sbMultiplier.Value, user.Value );
00396 foodItem.Consume(user.Key);
00397 foodItem.Save();
00398 }
00399 if(leftover > 0)
00400 {
00401 foodItem = this.recipe.Cook(sbMultiplier.Value, leftover);
00402 foodItem.Save();
00403 }
00404 }
00405 dialog.Destroy();
00406
00407
00408 fooditemsStorage = new List<FoodItem>(FoodItem.ListFoodItems());
00409 }
00410
00411
00415 protected virtual void EditRecipe (object sender, System.EventArgs e)
00416 {
00417 RecipeEditor re = this.owner.PushActivity<RecipeEditor>();
00418 re.SetParamenters(this.recipe);
00419 re.OnRecipeEdited += HandleOnRecipeEdited;
00420
00421 }
00422
00426 void HandleOnRecipeEdited(object sender, RecipeEventArgs e)
00427 {
00428 this.recipe = e.Recipe;
00429 SetRecipeDetails();
00430 if(this.OnRecipeEdited != null)
00431 {
00432 this.OnRecipeEdited(this, new RecipeEventArgs(this.recipe));
00433 }
00434
00435 }
00436
00441 protected virtual void OnStoreClick (object sender, System.EventArgs e)
00442 {
00443 ConfirmDialog dialog = new ConfirmDialog("Store recipe", "Do you want to store food made\nfrom this recipe in your inventory?");
00444
00445 if (dialog.Run() == (int)ResponseType.Ok)
00446 {
00447 this.recipe.Cook(sbMultiplier.Value).Save();
00448 }
00449 dialog.Destroy();
00450 fooditemsStorage = new List<FoodItem>(FoodItem.ListFoodItems());
00451 SetRecipeDetails();
00452 }
00453
00454 #endregion
00455
00456 #region IActivity
00457 public void Register(IOwner owner){
00458 this.owner = owner;
00459 this.owner.CurrentUserChanged += OwnerhandleCurrentUserChanged;
00460 }
00461
00462 public void Unregister(){
00463 this.owner.CurrentUserChanged -= OwnerhandleCurrentUserChanged;
00464 this.owner = null;
00465 }
00466
00467 public Widget Widget{
00468 get{
00469 return this;
00470 }
00471 }
00472 #endregion
00473
00474 protected virtual void OnBtnRecipe2ShoppingListClicked (object sender, System.EventArgs e)
00475 {
00476 this.owner.AddRecipe(this.recipe, sbMultiplier.Value);
00477 this.owner.ToggleShoppingList(true);
00478 }
00479
00480 protected virtual void OnBtnCloseViewClicked (object sender, System.EventArgs e)
00481 {
00482 this.Destroy();
00483 }
00484
00485 }
00486 }