public void Apply(LevelManipulator manipulator)
        {
            Reset(manipulator);

            SaveCurrentState(manipulator);
            RollAllRandomBubbles(manipulator);
        }
 public void Reset(LevelManipulator manipulator)
 {
     if (savedState != null)
     {
         ApplyTransformation(manipulator, b => b);
         savedState = null;
     }
 }
        private void RollAllRandomBubbles(LevelManipulator manipulator)
        {
            var rng     = new System.Random();
            var randoms = LevelConfiguration.CreateRandomizers(rng, manipulator.Randoms.ToArray());

            ApplyTransformation(manipulator, b =>
            {
                var modifier    = b.modifiers.First(m => m.type == BubbleModifierType.Random);
                var replacement = new BubbleData(b.X, b.Y, randoms[int.Parse(modifier.data)].GetValue());

                var modifiers = b.modifiers.Where(m => m.type != BubbleModifierType.Random).ToArray();
                if (modifiers.Length > 0)
                {
                    replacement.modifiers = modifiers;
                }

                return(replacement);
            });
        }
        private void ApplyTransformation(LevelManipulator manipulator, BubbleTransformation transformation)
        {
            var placer = new PlaceBubbleAction();

            manipulator.PushState();

            foreach (var bubble in savedState)
            {
                if (manipulator.Models.ContainsKey(bubble.Key))
                {
                    var replacement = transformation(bubble);

                    manipulator.Models[replacement.Key] = replacement;
                    manipulator.SetBubbleType(replacement.Type);
                    placer.Perform(manipulator, replacement.X, replacement.Y);
                }
            }

            manipulator.PopState();
        }
 private void SaveCurrentState(LevelManipulator manipulator)
 {
     savedState = manipulator.Models.Values
                  .Where(b => (b.modifiers != null) && (b.modifiers.Any(m => m.type == BubbleModifierType.Random)))
                  .ToList();
 }