// BK namespace
var BK = BK || {};
BK.menuNutritionModel = {};

// Nutirition sotals
BK.menuNutritionModel.nutritionTotals = function() {
	this.Weight = 0;
	this.Calories = 0;
	this.Fat = 0;
	this['Saturated Fat'] = 0;
	this['Trans Fat'] = 0;
	this.Cholesterol = 0;
	this.Sodium = 0;
	this.Carbohydrates = 0;
	this.Sugar = 0;
	this.Protein = 0;
}

// Allergen
BK.menuNutritionModel.allergen = function(data) {
	this.id = data.attr('ID')
	this.displayTitle = data.children('MenuMetaData').children('DisplayTitle').text();
}

// Nutrition item
BK.menuNutritionModel.nutritionItem = function(data) {
	this.name = data.children('Name').text();
	this.amount = parseFloat(data.children('Amount').text());
	this.measure;
	
	switch(data.children('Measure').text()) {
		case 'Grams':
			this.measure = 'g';
			break;
		case 'Milligrams':
			this.measure = 'mg';
			break;
		default:
			this.measure = '';
	}
}

// Ingredient
BK.menuNutritionModel.ingredient = function(data) {
	var ingredient = data.children('Ingredient');
	var metaData = ingredient.children('MenuMetaData');

	this.id = ingredient.attr('ID');
	this.iconOrder = ingredient.attr('IconOrder');
	this.displayTitle = metaData.children('DisplayTitle').text();
	this.defaultQuantity = parseFloat(data.find('DefaultQuantity').text());
	this.minQuantity = parseFloat(data.find('MinQuantity').text());
	this.maxQuantity = parseFloat(data.find('MaxQuantity').text());
	this.currentQuantity = this.defaultQuantity;
	this.allergens = [];
	this.nutritionItems = {};

	var self = this;
	ingredient.children('Allergens').children('Allergen').each(function() {
		self.allergens.push(new BK.menuNutritionModel.allergen($(this)));
	});

	data.children('NutritionItems').children('NutritionItem').each(function() {
		var ni = new BK.menuNutritionModel.nutritionItem($(this));
		self.nutritionItems[ni.name] = ni;
	});
}

BK.menuNutritionModel.ingredient.prototype = {
	add: function() {
		if (this.currentQuantity < this.maxQuantity) {
			this.currentQuantity++;
		}
	},

	subtract: function() {
		if (this.currentQuantity > this.minQuantity) {
			this.currentQuantity--;
		}
	}
}

// Menu variation
BK.menuNutritionModel.variation = function(data) {
	this.title = data.attr('Title');
	this.abbreviation = data.attr('TitleAbbreviation');
	this.menuItemId = data.attr('MenuItemID');
}

// Menu item
BK.menuNutritionModel.CategoryItem = function (data) {
    this.id = data.attr('ID');
    this.title = data.children("DisplayTitle").text();
    this.detailsUrl = data.children("DetailsUrl").text();
    this.caloriesBadge = data.children("CaloriesBadge").text();
}

BK.menuNutritionModel.menuItem = function (data) {
    this.xmlUrl;
    this.rawXml;
    this.id = data.attr('ID');
    this.title = data.attr('Title');
    this.displayTitle = data.find('DisplayTitle:first').text();
    this.burgerBuilderEnabled = data.attr('BurgerBuilderEnabled');
    this.briefCaption = data.find('MenuMetaData BriefCaption:first').text();
    this.imagePath = data.find('MenuItemAltImagePath').text();
    this.defaultVariationMenuItemId = data.find('MenuItemVariations').attr('DefaultMenuItemID');
    this.defaultVariationMenuItemTitle = data.find('MenuItemVariations').attr('Title');
    this.ingredients = {};
    this.variations = [];
    this.LowerCalorieItemSuggestions = data.find('LowerCalorieItemSuggestions').text();
    this.LowerCalorieIngredientSuggestions = data.find('LowerCalorieIngredientSuggestions').text();
    this.isValueMeal = false;
    this.allergens = [];

    var self = this;
    data.children('Ingredients').children('IngredientPortion').each(function () {
        var ing = new BK.menuNutritionModel.ingredient($(this));
        self.ingredients[ing.id] = ing;
    });

    data.children('MenuItemVariations').children('MenuItemVariation').each(function () {
        self.variations.push(new BK.menuNutritionModel.variation($(this)));
    });

    data.children('NonIngredientSpecificAllergens').children('Allergen').each(function() {
        self.allergens.push(new BK.menuNutritionModel.allergen($(this)));
    });
}

BK.menuNutritionModel.menuItem.prototype = {
	findVariationId: function(title) {		
		// Find the varition with the given title
		for (var i = 0; i < this.variations.length; i++) {
			if (this.variations[i].title == title) {
				return this.variations[i].menuItemId;
			}
		}
		
		return 0;
	},

	getNutritionTotals: function() {
		var totals = new BK.menuNutritionModel.nutritionTotals();

		for (var i in this.ingredients) {
			var currentIng = this.ingredients[i];
			for (var n in currentIng.nutritionItems) {
				if (totals[n]) {
					totals[n] += currentIng.nutritionItems[n].amount * currentIng.currentQuantity;
				}
				else {
					totals[n] = currentIng.nutritionItems[n].amount * currentIng.currentQuantity;
				}
			}
		}

		var RoundDecimal = function(decValue, decNearest) {
			//var decRounded = decValue % decNearest;
			//return (decRounded < (decNearest / 2)) ? decValue - decRounded : decValue + (decNearest - decRounded);
			return Math.round(decValue * (1 / decNearest)) / (1 / decNearest);
		}

		// Round the totals
		/* CALORIES
		< 5 cal - express as 0
		≤50 cal - express to nearest 5 cal increment
		> 50 cal - express to nearest 10 cal increment
		*/
		if (totals.Calories < 5) {
			totals.Calories = 0;
		}
		else if (totals.Calories <= 50) {
			totals.Calories = RoundDecimal(totals.Calories, 5);
		}
		else {
			totals.Calories = RoundDecimal(totals.Calories, 10);
		}

		/* FAT
		< .5 g - express as 0
		< 5 g - express to nearest .5g increment
		≥5 g - express to nearest 1 g increment
		*/
		if (totals.Fat < .5) {
			totals.Fat = 0;
		}
		else if (totals.Fat < 5) {
			totals.Fat = RoundDecimal(totals.Fat, .5);
		}
		else {
			totals.Fat = RoundDecimal(totals.Fat, 1);
		}

		/* SATURATED FAT
		< .5 g - express as 0
		< 5 g - express to nearest .5g increment
		≥5 g - express to nearest 1 g increment
		*/
		if (totals['Saturated Fat'] < .5) {
			totals['Saturated Fat'] = 0;
		}
		else if (totals['Saturated Fat'] < 5) {
			totals['Saturated Fat'] = RoundDecimal(totals['Saturated Fat'], .5);
		}
		else {
			totals['Saturated Fat'] = RoundDecimal(totals['Saturated Fat'], 1);
		}

		/* TRANS FAT
		< .5 g - express as 0
		< 5 g - express to nearest .5g increment
		≥5 g - express to nearest 1 g increment
		*/
		if (totals['Trans Fat'] < .5) {
			totals['Trans Fat'] = 0;
		}
		else if (totals['Trans Fat'] < 5) {
			totals['Trans Fat'] = RoundDecimal(totals['Trans Fat'], .5);
		}
		else {
			totals['Trans Fat'] = RoundDecimal(totals['Trans Fat'], 1);
		}

		/* CHOLESTEROL
		< 2 mg - express as 0
		2 - 5 mg - express as "less than 5 mg"
		> 5 mg - express to nearest 5 mg increment
		*/
		if (totals.Cholesterol < 2) {
			totals.Cholesterol = 0;
		}
		else if (totals.Cholesterol >= 2 && totals.Cholesterol <= 5) {
			totals.Cholesterol = RoundDecimal(totals.Cholesterol, 1);
		}
		else {
			totals.Cholesterol = RoundDecimal(totals.Cholesterol, 5);
		}

		/* SODIUM
		< 5 mg - express as 0
		5 - 140 mg - express to nearest 5 mg increment
		> 140 mg - express to nearest 10 mg increment
		*/
		if (totals.Sodium < 5) {
			totals.Sodium = 0;
		}
		else if (totals.Sodium >= 5 && totals.Sodium.Amount <= 140) {
			totals.Sodium = RoundDecimal(totals.Sodium, 5);
		}
		else {
			totals.Sodium = RoundDecimal(totals.Sodium, 10);
		}

		/* CARBS
		< .5 g - express as 0
		< 1 g - express as "Contains less than 1 g" or "less than 1 g"
		≥1 g - express to nearest 1 g increment
		*/
		if (totals.Carbohydrates < .5) {
			totals.Carbohydrates = 0;
		}
		else if (totals.Carbohydrates < 1) {
			totals.Carbohydrates = RoundDecimal(totals.Carbohydrates, .1);
		}
		else {
			totals.Carbohydrates = RoundDecimal(totals.Carbohydrates, 1);
		}

		/* SUGAR
		< .5 g - express as 0 
		< 1 g - express as "Contains less than 1 g" or "less than 1 g"
		≥1 g - express to nearest 1 g increment
		*/
		if (totals.Sugar < .5) {
			totals.Sugar = 0;
		}
		else if (totals.Sugar < 1) {
			totals.Sugar = RoundDecimal(totals.Sugar, .1);
		} else {
			totals.Sugar = RoundDecimal(totals.Sugar, 1);
		}


		/* PROTEIN
		< .5 g - express as 0 
		< 1 g - express as "Contains less than 1 g" or "less than 1 g" or to 1 g if .5 g to < 1 g
		≥1 g - express to nearest 1 g increment
		*/
		if (totals.Protein < .5) {
			totals.Protein = 0;
		}
		else if (totals.Protein < 1) {
			totals.Protein = RoundDecimal(totals.Protein, .1);
		}
		else {
			totals.Protein = RoundDecimal(totals.Protein, 1);
		}

		return totals;
	},

	updateIngredients: function(idArray, quantityArray) {
		for (var i = 0; i < idArray.length; i++) {
			for (var ing in this.ingredients) {
				currentIng = this.ingredients[ing];
				if (currentIng.id == idArray[i]) {
					currentIng.currentQuantity = quantityArray[i];
					break;
				}
			}
		}
	},

	addIngredient: function(ingredientId) {
		this.ingredients[ingredientId].add();
	},

	subtractIngredient: function(ingredientId) {
		this.ingredients[ingredientId].subtract();
	}
}

BK.menuNutritionModel.menuItem.load = function(detailsUrl, loadedCallback) {
	var mi;
	$.ajax({
		url: detailsUrl,
		datatype: 'xml',
		type: 'get',
		success: function(data) {
			mi = new BK.menuNutritionModel.menuItem($(data).find('MenuItem'));
		},
		complete: function(xhr, status) {
			mi.rawXml = xhr.responseText;
			mi.xmlUrl = detailsUrl;
			loadedCallback(mi);
		}
	});
}

// Value meal
BK.menuNutritionModel.valueMeal = function (data, loadedCallback) {
    this.baseItemUrl = '/cms' + CulturePrefix + 'cms_out/menu_nutrition/menu_items/';
    this.rawXml = '';
    this.xmlUrl = '';
    this.id = data.attr('ID');
    this.title = data.attr('Title');
    this.displayTitle = data.find('DisplayTitle:first').text();
    this.imagePath = data.find('MenuItemAltImagePath').text();
    this.sandwich = {};
    this.sideOptions = [];
    this.currentSide = 0;
    this.drinkOptions = [];
    this.currentDrink = 0;
    this.variations = [];
    this.LowerCalorieItemSuggestions = data.find('LowerCalorieItemSuggestions').text();
    this.LowerCalorieIngredientSuggestions = data.find('LowerCalorieIngredientSuggestions').text();

    var self = this;
    var sides = data.find('SideOptions Side');
    var drinks = data.find('DrinkOptions Drink');

    data.find('ValueMealVariations MenuItemVariation').each(function () {
        self.variations.push(new BK.menuNutritionModel.variation($(this)));
    });

    var completedItems = 0;
    var totalItems = sides.length + drinks.length + 1;

    var onItemLoaded = function () {
        completedItems++;
        if (completedItems == totalItems) {
            loadedCallback(self);
        }
    }

    BK.menuNutritionModel.menuItem.load(this.baseItemUrl + data.find('Sandwich').attr('MenuItemID') + '.xml', function (item) {
        item.isValueMeal = true;
        self.sandwich = item;
        onItemLoaded();
    });

    var defaultSideId = data.find('SideOptions').attr('DefaultMenuItemID');
    sides.each(function () {
        var id = $(this).attr('MenuItemID')
        BK.menuNutritionModel.menuItem.load(self.baseItemUrl + id + '.xml', function (item) {
            self.sideOptions[id] = item;

            if (id == defaultSideId) {
                self.currentSide = item;
            }

            onItemLoaded();
        });
    });

    var defaultDrinkId = data.find('DrinkOptions').attr('DefaultMenuItemID');
    drinks.each(function () {
        var id = $(this).attr('MenuItemID')
        BK.menuNutritionModel.menuItem.load(self.baseItemUrl + id + '.xml', function (item) {
            self.drinkOptions[id] = item;

            if (id == defaultDrinkId) {
                self.currentDrink = item;
            }

            onItemLoaded();
        });
    });
}

BK.menuNutritionModel.valueMeal.prototype = {
	getNutritionTotals: function() {
		var mealTotals = new BK.menuNutritionModel.nutritionTotals();

		function addTotals(itemTotals) {
			for (var n in itemTotals) {
				if (mealTotals[n]) {
					mealTotals[n] += itemTotals[n];
				}
				else {
					mealTotals[n] = itemTotals[n];
				}
			}
		}

		addTotals(this.sandwich.getNutritionTotals());
		addTotals(this.currentDrink.getNutritionTotals());
		addTotals(this.currentSide.getNutritionTotals());

		return mealTotals;
	},

	addIngredient: function(ingredientId) {
		this.sandwich.addIngredient(ingredientId);
	},

	subtractIngredient: function(ingredientId) {
		this.sandwich.subtractIngredient(ingredientId);
	},

	changeSide: function(sideId) {
		this.currentSide = this.sideOptions[sideId];
	},

	changeDrink: function(drinkId) {
		this.currentDrink = this.drinkOptions[drinkId];
	},

	resize: function(valueMealId, detailsUrl, loadedCallback) {
		var title = 0;
		for (var i = 0; i < this.variations.length; i++) {
			if (this.variations[i].menuItemId == valueMealId) {
				title = this.variations[i].title;
				break;
			}
		}

		if (title) {
			var self = this;

			var sideVariationId = this.currentSide.findVariationId(title);
			if (!sideVariationId) {
				sideVariationId = this.currentSide.id;
			}

			var drinkVariationId = this.currentDrink.findVariationId(title);
			if (!drinkVariationId) {
				drinkVariationId = this.currentDrink.id;
			}

			$.ajax({
				url: detailsUrl,
				datatype: 'xml',
				type: 'get',
				success: function(data) {
					var dataDoc = $(data);

					self.id = dataDoc.find('ValueMealItem').attr('ID');
					self.displayTitle = dataDoc.find('DisplayTitle:first').text();
					
					var sides = dataDoc.find('SideOptions Side');
					var drinks = dataDoc.find('DrinkOptions Drink');

					var completedItems = 0;
					var totalItems = sides.length + drinks.length;

					var onItemLoaded = function() {
						completedItems++;
						if (completedItems == totalItems) {
							loadedCallback(self);
						}
					}

					delete self.sideOptions;
					delete self.drinkOptions;

					self.sideOptions = [];
					self.drinkOptions = [];

					sides.each(function() {
						var id = $(this).attr('MenuItemID')
						BK.menuNutritionModel.menuItem.load(self.baseItemUrl + id + '.xml', function(item) {
							self.sideOptions[id] = item;

							if (id == sideVariationId) {
								self.currentSide = item;
							}

							onItemLoaded();
						});
					});

					drinks.each(function() {
						var id = $(this).attr('MenuItemID')
						BK.menuNutritionModel.menuItem.load(self.baseItemUrl + id + '.xml', function(item) {
							self.drinkOptions[id] = item;

							if (id == drinkVariationId) {
								self.currentDrink = item;
							}

							onItemLoaded();
						});
					});
				},
				complete: function(xhr, status) {
					this.rawXml = xhr.responseText;
					this.xmlUrl = detailsUrl;
				}
			});
		}
	}
}

// Meal
BK.menuNutritionModel.meal = function() {
	var lastIndexAdded = -1;
	var currentItemId = -1;
	var currentItem = {};
	var items = [];

	return {
		canAddItem: function() {
			if (currentItem.sandwich) {
				return items.length < 8;
			}
			else {
				return items.length < 10;
			}
		},

		addCurrentItem: function() {
			if (currentItem.sandwich) {
				this.addMenuItem($.extend(true, {}, currentItem.sandwich));
				this.addMenuItem($.extend(true, {}, currentItem.currentSide));
				this.addMenuItem($.extend(true, {}, currentItem.currentDrink));
				lastIndexAdded = items.length - 3;
			}
			else {
				this.addMenuItem($.extend(true, {}, currentItem));
				lastIndexAdded = items.length - 1;
			}
		},

		addMenuItem: function(menuItem) {
			items.push(menuItem);
		},

		getCurrentItem: function() {
			return currentItem;
		},

		setCurrentItem: function(item) {
			if (typeof item == 'object') {
				currentItemId = -1;
				currentItem = $.extend(true, {}, item);
			}
			else {
				currentItemId = item;
				currentItem = $.extend(true, {}, items[item]);
			}
		},

		updateCurrentItem: function() {
			delete items[currentItemId];
			items[currentItemId] = $.extend(true, {}, currentItem);
		},

		removeItem: function(itemId) {
			items.splice(itemId, 1);

			if (currentItemId > itemId) {
				currentItemId--;
			}

			if (lastIndexAdded > itemId) {
				lastIndexAdded--;
			}
		},

		getLastIndexAdded: function() {
			return lastIndexAdded;
		},

		clearLastIndexAdded: function() {
			lastIndexAdded = -1;
		},

		isCurrentItem: function(itemId) {
			return itemId == currentItemId;
		},

		getItems: function() {
			return items;
		},

		getItemsXml: function() {
			var menuItemList = '<flashMenuItemCombos>';
			for (var j = 0; j < items.length; j++) {
				var itm = items[j];

				// Build ingredient Xml
				var ingQtys = '<ingredientQtys>';
				for (var id in itm.ingredients) {
					ingQtys += '<ingredient Id="' + id + '" qty="' + itm.ingredients[id].currentQuantity + '"/>';
				}
				ingQtys += '</ingredientQtys>';

				menuItemList += '<flashMenuItemCombo><rawMenuItem>'
									+ itm.rawXml.replace('<?xml version="1.0" encoding="utf-8"?>', '')
									+ '</rawMenuItem>' + ingQtys + '</flashMenuItemCombo>';
			}

			menuItemList += '</flashMenuItemCombos>';

			return menuItemList;
		},

		getMealNutritionTotals: function() {
			var mealTotals = new BK.menuNutritionModel.nutritionTotals();

			for (var i in items) {
				var itemTotals = items[i].getNutritionTotals();
				for (var n in itemTotals) {
					if (mealTotals[n]) {
						mealTotals[n] += itemTotals[n];
					}
					else {
						mealTotals[n] = itemTotals[n];
					}
				}
			}

			return mealTotals;
		}
	}
} ();

// Load method
BK.menuNutritionModel.loadItem = function(detailsUrl, loadedCallback) {
	var item;
	var isValueMeal = false;
	$.ajax({
		url: detailsUrl,
		datatype: 'xml',
		type: 'get',
		success: function(data) {
			var dataDoc = $(data);
			if (dataDoc.find('ValueMealItem').length > 0) {
				isValueMeal = true;
				item = new BK.menuNutritionModel.valueMeal(dataDoc.find('ValueMealItem'), loadedCallback);
			}
			else {
				item = new BK.menuNutritionModel.menuItem(dataDoc.find('MenuItem'));
			}
		},
		complete: function(xhr, status) {
			item.rawXml = xhr.responseText;
			item.xmlUrl = detailsUrl;

			if (!isValueMeal) {
				loadedCallback(item);
			}
		}
	});
}

