var DiceRoller = {};
(function (self) {

	var VERSION = "2.1.0";

	self.view;

	self.dice = [];

	self.diceTypes = {
		simpleDie: {
			id: "simpleDie",
		},
		starwarsFFG: {
			id: "starwarsFFG",
			symbols: {
				success: "Q",
				failure: "R",

				triumph: "E",
				advantage: "W",
				threat: "T",
				despair: "Y",

				dark: "I",
				light: "U",
				light_dark: "O",
			}
		}
	};

	var starwarsSymbols = self.diceTypes.starwarsFFG.symbols

	self.init = function () {
		var that = this;

		var simpleDice = [2, 4, 6, 8, 10, 12, 20, 100];
		for (var x = 0; x < simpleDice.length; x++) {
			var simpleDieId = "d" + simpleDice[x];
			self.dice.push({
				id: simpleDieId,
				dieType: self.diceTypes.simpleDie.id,
				label: simpleDieId,
				sides: simpleDice[x],
				min: 1,
				max: simpleDice[x]
			});
		}
		var starwarsFFGDiceLabels = ["boost", "setback", "ability", "difficulty", "proficiency", "challenge", "force"];
		var starwarsFFGDice = [
			{
				id: "boost",
				sideCount: 6,
				sideFaces: [
					"", "",
					starwarsSymbols.advantage + starwarsSymbols.advantage, starwarsSymbols.advantage,
					starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.success
				]
			},
			{
				id: "setback",
				sideCount: 6,
				sideFaces: [
					"", "",
					starwarsSymbols.failure, starwarsSymbols.failure,
					starwarsSymbols.threat, starwarsSymbols.threat
				]
			},
			{
				id: "ability",
				sideCount: 8,
				sideFaces: [
					"", starwarsSymbols.success,
					starwarsSymbols.success, starwarsSymbols.success + starwarsSymbols.success,
					starwarsSymbols.advantage, starwarsSymbols.advantage,
					starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.advantage + starwarsSymbols.advantage
				]
			},
			{
				id: "difficulty",
				sideCount: 8,
				sideFaces: [
					"", starwarsSymbols.failure,
					starwarsSymbols.failure + starwarsSymbols.failure, starwarsSymbols.threat,
					starwarsSymbols.threat, starwarsSymbols.threat,
					starwarsSymbols.threat + starwarsSymbols.threat, starwarsSymbols.failure + starwarsSymbols.threat
				]
			},
			{
				id: "proficiency",
				sideCount: 12,
				sideFaces: [
					"", starwarsSymbols.success,
					starwarsSymbols.success, starwarsSymbols.success + starwarsSymbols.success,
					starwarsSymbols.success + starwarsSymbols.success, starwarsSymbols.advantage,
					starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.success + starwarsSymbols.advantage,
					starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.advantage + starwarsSymbols.advantage,
					starwarsSymbols.advantage + starwarsSymbols.advantage, starwarsSymbols.triumph
				]
			},
			{
				id: "challenge",
				sideCount: 12,
				sideFaces: [
					"", starwarsSymbols.failure,
					starwarsSymbols.failure, starwarsSymbols.failure + starwarsSymbols.failure,
					starwarsSymbols.failure + starwarsSymbols.failure, starwarsSymbols.threat,
					starwarsSymbols.threat, starwarsSymbols.failure + starwarsSymbols.threat,
					starwarsSymbols.failure + starwarsSymbols.threat, starwarsSymbols.threat + starwarsSymbols.threat,
					starwarsSymbols.threat + starwarsSymbols.threat, starwarsSymbols.despair
				]
			},
			{
				id: "force",
				sideCount: 12,
				sideFaces: [
					starwarsSymbols.dark, starwarsSymbols.dark,
					starwarsSymbols.dark, starwarsSymbols.dark,
					starwarsSymbols.dark, starwarsSymbols.dark,
					starwarsSymbols.dark + starwarsSymbols.dark, starwarsSymbols.light,
					starwarsSymbols.light, starwarsSymbols.light + starwarsSymbols.light,
					starwarsSymbols.light + starwarsSymbols.light, starwarsSymbols.light + starwarsSymbols.light
				]
			},

		];
		for (var x = 0; x < starwarsFFGDice.length; x++) {
			self.dice.push({
				id: starwarsFFGDice[x].id,
				dieType: self.diceTypes.starwarsFFG.id,
				label: starwarsFFGDice[x].id.capitalize(),
				sides: starwarsFFGDice[x].sideCount,
				min: 0,
				max: starwarsFFGDice[x].sideCount - 1,
				sideFaces: starwarsFFGDice[x].sideFaces
			});
		}

		self.view = new Ractive({
			el: "#site-content",
			append: true,
			template: "#dice-roller-template",
			decorators: {
			},
			data: {
				VERSION: VERSION,
				dicePool: [],
				dice: [],
				results: [],
				getDieDisplayData: function (dieId, result) {
					if (dieId == null)
						return;

					var dieData = _.find(self.dice, function (e) {
						return e.id == dieId;
					});

					var style = "";
					var label = dieData.label;

					if (dieData.dieType == self.diceTypes.simpleDie.id) {
						if (result != null) {
							style += " simple";
							if (result <= dieData.min)
								style += " negative";
							if (result >= dieData.max)
								style += " positive";

							label = dieData.label + ": <br />" + result;
						}
					}
					if (dieData.dieType == self.diceTypes.starwarsFFG.id) {
						style += self.diceTypes.starwarsFFG.id;
						if (result != null) {
							style += " no-select " + dieData.id
							label = dieData.sideFaces[result];
							if ((dieData.id == "boost" || dieData.id == "ability" || dieData.id == "difficulty") && label.length == 2)
								style += " duo";
						}
					}
					return {
						id: dieData.id,
						style: style,
						label: label
					};
				},
				getCompoundResult: function (result) {
					var simpleDieResult;
					var starwarsFFGDieResults;
					var starwarsFFGDieFinalResult;

					_.each(result.keys, function (dieId) {
						var dieData = _.find(self.dice, function (e) {
							return e.id == dieId;
						});

						if (dieData == null)
							return;

						if (dieData.dieType == self.diceTypes.simpleDie.id) {
							if (simpleDieResult == null)
								simpleDieResult = 0;
							var dieResults = result[dieId];
							if (dieResults != null) {
								for (var x = 0; x < dieResults.length; x++) {
									simpleDieResult += dieResults[x];
								}
							}
						}

						if (dieData.dieType == self.diceTypes.starwarsFFG.id) {
							if (starwarsFFGDieResults == null)
								starwarsFFGDieResults = {};
							var resultValues = [];
							var dieResults = result[dieId];
							for (var x = 0; x < dieResults.length; x++) {
								resultValues += dieData.sideFaces[dieResults[x]].split();
							}
							for (var x = 0; x < resultValues.length; x++) {
								var resultValue = resultValues[x];
								if (starwarsFFGDieResults[resultValue] == null)
									starwarsFFGDieResults[resultValue] = 0;
								starwarsFFGDieResults[resultValue]++;
							}
						}
					});

					if (starwarsFFGDieResults != null) {
						starwarsFFGDieFinalResult = "";

						//Success/Triumph vs Failure/Despair
						var successResult = starwarsFFGDieResults[starwarsSymbols.success] || 0;
						var triumphResult = starwarsFFGDieResults[starwarsSymbols.triumph] || 0;
						successResult += triumphResult;

						var failureResult = starwarsFFGDieResults[starwarsSymbols.failure] || 0;
						var despairResult = starwarsFFGDieResults[starwarsSymbols.despair] || 0;
						failureResult += despairResult;

						var vsResult = successResult - failureResult;
						if (vsResult != 0) {
							var absResult = Math.abs(vsResult);
							starwarsFFGDieFinalResult += absResult.toString() + " ";
							if (vsResult > 0)
								starwarsFFGDieFinalResult += "Success" + (triumphResult > 0 ? " (with Triumph); " : "; ");
							if (vsResult < 0)
								starwarsFFGDieFinalResult += "Failure" + (despairResult > 0 ? " (with Despair); " : "; ");
						}

						// Triumph and Despair
						if (triumphResult > 0)
							starwarsFFGDieFinalResult += triumphResult + " Triumph; ";
						if (despairResult > 0)
							starwarsFFGDieFinalResult += despairResult + " Despair; ";

						//Advantage Vs Threat
						var advantageResult = starwarsFFGDieResults[starwarsSymbols.advantage] || 0;
						var threatResult = starwarsFFGDieResults[starwarsSymbols.threat] || 0;

						var vsResult = advantageResult - threatResult;
						if (vsResult != 0) {
							var absResult = Math.abs(vsResult);
							starwarsFFGDieFinalResult += absResult.toString() + " ";
							if (vsResult > 0)
								starwarsFFGDieFinalResult += " Advantage; ";
							if (vsResult < 0)
								starwarsFFGDieFinalResult += " Threat; ";
						}

						var darkResult = starwarsFFGDieResults[starwarsSymbols.dark] || 0;
						if (darkResult)
							starwarsFFGDieFinalResult += darkResult + " Dark Side; ";

						var lightResult = starwarsFFGDieResults[starwarsSymbols.light] || 0;
						if (lightResult)
							starwarsFFGDieFinalResult += lightResult + " Light Side; ";

						if (starwarsFFGDieFinalResult.length == 0)
							starwarsFFGDieFinalResult = "Nil ";
					}

					return (starwarsFFGDieFinalResult == null ? "" : starwarsFFGDieFinalResult) + (simpleDieResult == null ? "" : simpleDieResult);
				}
			},
			oninit: function () {
				var view = this;

				ga("send", {
					hitType: "event",
					eventCategory: "dice-roller",
					eventAction: "version",
					eventLabel: VERSION
				});

				view.set("dice", self.dice);

				this.on({
					addToDicePool: function (event, dieId) {
						var dicePool = view.get("dicePool");
						var currentDiceData = _.find(dicePool, function (e) {
							return e.id == dieId;
						});

						if (!!currentDiceData) {
							currentDiceData.amount++;
						} else {
							var diceData = _.find(self.dice, function (e) {
								return e.id == dieId;
							});
							dicePool.push($.extend(diceData, {
								amount: 1
							}));
						}

						view.update();
					},
					removeFromDicePool: function (event, dieId) {
						var dicePool = view.get("dicePool");

						var currentDiceData = _.find(dicePool, function (e) {
							return e.id == dieId;
						});

						if (!!currentDiceData) {
							currentDiceData.amount--;
						}

						if (currentDiceData.amount <= 0) {
							dicePool.remove(currentDiceData);
						}

						view.update();
					},
					rollPool: function (event) {
						var dicePool = view.get("dicePool").slice();

						if (dicePool.length == 0)
							return;

						var result = {
							keys: [],
							timestamp: (new Date()).toLocaleTimeString()
						};
						var dieTypesUsed = [];
						for (var x = 0; x < dicePool.length; x++) {
							(function (result) {
								var dieData = dicePool[x];

								if (!_.has(dieTypesUsed, dieData.dieType))
									dieTypesUsed.push(dieData.dieType);

								result.keys.push(dieData.id);
								RandomChad.rollDice(dieData.sides, dieData.amount, function (resultArray) {
									result[dieData.id] = [];
									for (var x = 0; x < resultArray.length; x++) {
										result[dieData.id].push(resultArray[x] + (dieData.min - 1));
									}
									view.update();
								});
							})(result);
						}

						view.unshift("results", result);
						for (var x = 0; x < dieTypesUsed.length; x++) {
							ga("send", {
								hitType: "event",
								eventCategory: "dice-roller",
								eventAction: "dieTypeUsed",
								eventLabel: dieTypesUsed[x]
							});
						}
					},
					resetPool: function (event) {
						view.set("dicePool", []);
						ga("send", {
							hitType: "event",
							eventCategory: "dice-roller",
							eventAction: "resetPool"
						});
					},
					clearResults: function (event) {
						view.set("results", []);
						ga("send", {
							hitType: "event",
							eventCategory: "dice-roller",
							eventAction: "clearResults"
						});
					},
					copyResult: function (event) {

						ga("send", {
							hitType: "event",
							eventCategory: "dice-roller",
							eventAction: "reset"
						});
					}
				});
			},
			onrender: function () {
				var view = this;
			}
		});
	};
})(DiceRoller);
RollAdvantage.InitRegister.push(DiceRoller.init);
var RandomChad = {};
(function (self) {
	//https://api.random.org/json-rpc/1/basic
	//https://api.random.org/json-rpc/1/invoke

	var diceCache = {};

	function dieResultHandler(resultArray, die, amount, callback) {
		if (diceCache[die]) {
			diceCache[die] = diceCache[die].concat(resultArray);
		} else {
			diceCache[die] = resultArray;
		}
		if (callback) {
			var returnResult = diceCache[die].slice(0, amount);
			diceCache[die] = diceCache[die].slice(amount, diceCache.length);
			callback(returnResult);
		}
	}

	self.rollDice = function (die, amount, callback) {
		die = die ? die : 20;
		amount = amount ? amount : 1;

		if (!diceCache[die] || diceCache[die].length < amount) {
			var options = {
				"jsonrpc": "2.0",
				"method": "generateIntegers",
				"params": {
					"apiKey": "8272a582-c84c-494d-82c5-a8bb6aa62059",
					"n": amount + 10,
					"min": 1,
					"max": die,
					"replacement": true
				},
				"id": die
			};

			$.post("https://api.random.org/json-rpc/2/invoke", JSON.stringify(options), function (response) {
				dieResultHandler(response.result.random.data, die, amount, callback);
			}, "json")
				.fail(function (jqXHR, textStatus, error) {
					console.log("Post error: " + error);
					console.log("Random.Org could not be reached.");
					var results = [];
					for (var x = 0; x < amount; x++) {
						results.push(generateInt(1, die));
					}
					dieResultHandler(results, die, amount, callback);
				});

		} else {
			var returnResult = diceCache[die].slice(0, amount);
			diceCache[die] = diceCache[die].slice(amount, diceCache.length);
			callback(returnResult);
		}
	};

	function generateInt(min, max) {
		min = Math.ceil(min);
		max = Math.floor(max);
		return Math.floor(Math.random() * (max - min + 1)) + min;
	}

	self.rollD2 = function (amount, callback) {
		self.rollDice(2, amount, callback);
	};

	self.rollD4 = function (amount, callback) {
		self.rollDice(4, amount, callback);
	};

	self.rollD6 = function (amount, callback) {
		self.rollDice(6, amount, callback);
	};

	self.rollD8 = function (amount, callback) {
		self.rollDice(8, amount, callback);
	};

	self.rollD10 = function (amount, callback) {
		self.rollDice(10, amount, callback);
	};

	self.rollD12 = function (amount, callback) {
		self.rollDice(12, amount, callback);
	};

	self.rollD20 = function (amount, callback) {
		self.rollDice(20, amount, callback);
	};

	self.rollD100 = function (amount, callback) {
		self.rollDice(100, amount, callback);
	};

})(RandomChad);


