/// <summary>
		/// Copy constructor
		/// </summary>
		/// <param name="copyPlayer"></param>
		public CollectionPlayer(CollectionPlayer copyPlayer) : this()
		{
			coins = copyPlayer.coins;
			totalCoinsCollected = copyPlayer.totalCoinsCollected;
			stars = copyPlayer.stars;
			lastRestock = copyPlayer.lastRestock;
			inventory = new CollectionStorage(copyPlayer.inventory);
			journal = new CollectionJournal(copyPlayer.journal);
			foreverJournal = new CollectionJournal(copyPlayer.foreverJournal);
         loveList = new List<int>(copyPlayer.loveList);
		}
      public static int SellPrice(SpecialPoint item, CollectionPlayer player)
      {
         return (int)(IndividualSellPrice + ExtraSellPrice * (player.RareList.Select(x => CollectionManager.PointFrom1DIndex(x)).ToList().IndexOf(item) / (double)CollectionManager.TotalGridSpace));
//         double leastRare = CollectionGenerator.ItemRarity(CollectionManager.PointFrom1DIndex(player.RareList[0]), player);
//
//         return (int)(IndividualSellPrice + ExtraSellPrice * (1 - CollectionGenerator.ItemRarity(item, player) / leastRare));
      }
		/// <summary>
		/// Get the chance of getting a new item for a given player and a given multiplier, but in parallel
		/// </summary>
		/// <param name="player"></param>
		/// <param name="multiplier"></param>
		/// <returns></returns>
		public static double DrawChanceForPlayerParallel(CollectionPlayer player, int multiplier)
		{
			int newitems = 0;

			Parallel.For(0, CollectionManager.DrawChanceSimulations, () => new ParallelLocal { generator = new CollectionGenerator(), sum = 0 }, (i, loop, local) =>
			{
				if (!player.Journal.HasItem(local.generator.DrawItemForPlayer(player, multiplier)))
					local.sum++;

				return local;
			},

				partial => Interlocked.Add(ref newitems, partial.sum)
			);

			return (double)newitems / CollectionManager.DrawChanceSimulations;
		}
		/// <summary>
		/// Get the chance of getting a new item for a given player and a given multiplier
		/// </summary>
		/// <param name="player"></param>
		/// <param name="multiplier"></param>
		/// <returns></returns>
		public double DrawChanceForPlayer(CollectionPlayer player, int multiplier)
		{
			int newitems = 0;

			for (int i = 0; i < CollectionManager.DrawChanceSimulations; i++)
				if (!player.Journal.HasItem(DrawItemForPlayer(player, multiplier)))
					newitems++;

			return (double)newitems / CollectionManager.DrawChanceSimulations;
		}
		/// <summary>
		/// Based on the player and multiplier given, draw an item. This method does NOT add the item to the player; it just gives
		/// a random item based on the player. Basically a wrapper around GenerateItemIndex
		/// </summary>
		/// <param name="player"></param>
		/// <param name="multiplier"></param>
		/// <returns></returns>
		public SpecialPoint DrawItemForPlayer(CollectionPlayer player, int multiplier)
		{
			multiplier--;

			int newItem = GenerateItemIndex();

			List<int> seenPoints = new List<int>();
			seenPoints.Add(newItem);

			//Apply the rarity increase multiplier.
			for (int i = 0; i < multiplier * CollectionManager.MultiplyMultiplier; i++)
			{
				//Oh, but if it's a new item, just return it immediately
				if (!player.Journal.HasItem(CollectionManager.PointFrom1DIndex(player.RareList[newItem])))
					break;

				//While we've already generated the given item, keep on generating. This might have to go through like 1000 iterations, but whatever.
				while (seenPoints.Contains(newItem))
					newItem = GenerateItemIndex();

				seenPoints.Add(newItem);
			}

			return CollectionManager.PointFrom1DIndex(player.RareList[newItem]);
		}
      public static double ItemRarity(SpecialPoint item, CollectionPlayer player)
      {
         if (!CollectionManager.ValidPoint(item))
            return 0;
         
         int index = player.RareList.Select(x => CollectionManager.PointFrom1DIndex(x)).ToList().IndexOf(item);

         if(index < 0)
            return 0;

         double totalRarity = CumulativeRarity(CollectionManager.TotalGridSpace);

         return (CumulativeRarity(index + 1) - CumulativeRarity(index)) / totalRarity;
      }