<commit_before>﻿using FlatRedBall.Glue.Managers;
using FlatRedBall.Glue.Plugins.ExportedImplementations;
using FlatRedBall.Glue.SaveClasses;
using System;
using System.Collections.Generic;
using System.Text;

namespace FlatRedBall.PlatformerPlugin.Generators
{
    public class PlatformerAnimationControllerGenerator : Singleton<PlatformerAnimationControllerGenerator>
    {
        string RelativeFileLocation => "Platformer/PlatformerAnimationController.Generated.cs";


        public void GenerateAndSave()
        {

            TaskManager.Self.Add(() =>
            {
                var contents = GenerateFileContents();

                var relativeDirectory = RelativeFileLocation;

                GlueCommands.Self.ProjectCommands.CreateAndAddCodeFile(relativeDirectory);

                var glueProjectDirectory = GlueState.Self.CurrentGlueProjectDirectory;

                if (!string.IsNullOrEmpty(glueProjectDirectory))
                {
                    var fullFile = GlueState.Self.CurrentGlueProjectDirectory + relativeDirectory;

                    try
                    {
                        GlueCommands.Self.TryMultipleTimes(() =>
                            System.IO.File.WriteAllText(fullFile, contents));
                    }
                    catch (Exception e)
                    {
                        GlueCommands.Self.PrintError(e.ToString());
                    }
                }

            }, "Adding PlatformerAnimationConfiguration.Generated.cs to the project");


        }

        private string GenerateFileContents()
        {
            var toReturn =
@"


namespace " + GlueState.Self.ProjectNamespace + @".Entities
{
    public enum AnimationSpeedAssignment
    {
        ForceTo1,
        NoAssignment,
        BasedOnMultiplier
    }

    public class PlatformerAnimationConfiguration
    {
        public string AnimationName { get; set; }
        public bool HasLeftAndRight { get; set; } = true;

        public float? MinXVelocityAbsolute { get; set; }
        public float? MaxXVelocityAbsolute { get; set; }

        public float? MinYVelocity { get; set; }
        public float? MaxYVelocity { get; set; }

        public float? AbsoluteXVelocityAnimationSpeedMultiplier { get; set; }
        public float? AbsoluteYVelocityAnimationSpeedMultiplier { get; set; }

        public bool? OnGroundRequirement { get; set; }

        public string MovementName { get; set; }

        public AnimationSpeedAssignment AnimationSpeedAssignment { get; set; }

        public override string ToString()
        {
            return AnimationName;
        }
    }

    public class PlatformerAnimationController : FlatRedBall.Graphics.Animation.AnimationController
    {
        IPlatformer PlatformerEntity;
        public PlatformerAnimationController(IPlatformer platformerEntity)
        {
            PlatformerEntity = platformerEntity;
        }


        public void AddLayer(PlatformerAnimationConfiguration configuration)
        {
            var layer = this.AddLayer();
";

            if(GlueState.Self.CurrentGlueProject.FileVersion >= (int)GlueProjectSave.GluxVersions.AnimationLayerHasName)
            {
                toReturn +=
                    @"
            layer.Name = configuration.AnimationName;
";

            }

            toReturn +=
                @"
            layer.EveryFrameAction = () =>
            {
                bool shouldSet = true;
                var absoluteXVelocity = System.Math.Abs(PlatformerEntity.XVelocity);
                var yVelocity = PlatformerEntity.YVelocity;
                if(shouldSet && !string.IsNullOrEmpty( configuration.MovementName))
                {
                    shouldSet = configuration.MovementName == PlatformerEntity.CurrentMovementName;
                }

                shouldSet = shouldSet && (absoluteXVelocity < configuration.MinXVelocityAbsolute) == false;
                shouldSet = shouldSet && (yVelocity < configuration.MinYVelocity) == false;
                shouldSet = shouldSet && (absoluteXVelocity > configuration.MaxXVelocityAbsolute) == false;
                shouldSet = shouldSet && (yVelocity > configuration.MaxYVelocity) == false;

                shouldSet = shouldSet &&
                    (configuration.OnGroundRequirement == null || PlatformerEntity.IsOnGround == configuration.OnGroundRequirement);

                if (shouldSet)
                {
                    switch(configuration.AnimationSpeedAssignment)
                    {
                        case AnimationSpeedAssignment.ForceTo1:
                            {
                                var asSprite = this.AnimatedObject as FlatRedBall.Sprite;

                                asSprite.AnimationSpeed = 1;
                            }
                            break;
                        case AnimationSpeedAssignment.NoAssignment:
                            break;
                        case AnimationSpeedAssignment.BasedOnMultiplier:
                            {
                                var asSprite = this.AnimatedObject as FlatRedBall.Sprite;

                                if(configuration.AbsoluteXVelocityAnimationSpeedMultiplier != null)
                                {
                                    asSprite.AnimationSpeed = configuration.AbsoluteXVelocityAnimationSpeedMultiplier.Value *
                                        absoluteXVelocity;
                                }
                                else if(configuration.AbsoluteYVelocityAnimationSpeedMultiplier != null)
                                {<commit_msg>Added ability to specify additional predicates for animations.<commit_after>﻿using FlatRedBall.Glue.Managers;
using FlatRedBall.Glue.Plugins.ExportedImplementations;
using FlatRedBall.Glue.SaveClasses;
using System;
using System.Collections.Generic;
using System.Text;

namespace FlatRedBall.PlatformerPlugin.Generators
{
    public class PlatformerAnimationControllerGenerator : Singleton<PlatformerAnimationControllerGenerator>
    {
        string RelativeFileLocation => "Platformer/PlatformerAnimationController.Generated.cs";


        public void GenerateAndSave()
        {

            TaskManager.Self.Add(() =>
            {
                var contents = GenerateFileContents();

                var relativeDirectory = RelativeFileLocation;

                GlueCommands.Self.ProjectCommands.CreateAndAddCodeFile(relativeDirectory);

                var glueProjectDirectory = GlueState.Self.CurrentGlueProjectDirectory;

                if (!string.IsNullOrEmpty(glueProjectDirectory))
                {
                    var fullFile = GlueState.Self.CurrentGlueProjectDirectory + relativeDirectory;

                    try
                    {
                        GlueCommands.Self.TryMultipleTimes(() =>
                            System.IO.File.WriteAllText(fullFile, contents));
                    }
                    catch (Exception e)
                    {
                        GlueCommands.Self.PrintError(e.ToString());
                    }
                }

            }, "Adding PlatformerAnimationConfiguration.Generated.cs to the project");


        }

        private string GenerateFileContents()
        {
            var toReturn =
@"
using System.Linq;

namespace " + GlueState.Self.ProjectNamespace + @".Entities
{
    public enum AnimationSpeedAssignment
    {
        ForceTo1,
        NoAssignment,
        BasedOnMultiplier
    }

    public class PlatformerAnimationConfiguration
    {
        public string AnimationName { get; set; }
        public bool HasLeftAndRight { get; set; } = true;

        public float? MinXVelocityAbsolute { get; set; }
        public float? MaxXVelocityAbsolute { get; set; }

        public float? MinYVelocity { get; set; }
        public float? MaxYVelocity { get; set; }

        public float? AbsoluteXVelocityAnimationSpeedMultiplier { get; set; }
        public float? AbsoluteYVelocityAnimationSpeedMultiplier { get; set; }

        public bool? OnGroundRequirement { get; set; }

        public string MovementName { get; set; }

        public AnimationSpeedAssignment AnimationSpeedAssignment { get; set; }

        public System.Func<bool> AdditionalPredicate;

        public override string ToString()
        {
            return AnimationName;
        }
    }

    public class PlatformerAnimationController : FlatRedBall.Graphics.Animation.AnimationController
    {
        IPlatformer PlatformerEntity;

        System.Collections.Generic.List<PlatformerAnimationConfiguration> platformerAnimationConfigurations;
        public System.Collections.ObjectModel.ReadOnlyCollection<PlatformerAnimationConfiguration> Configurations { get; private set; }

        public PlatformerAnimationController(IPlatformer platformerEntity)
        {
            PlatformerEntity = platformerEntity;
            platformerAnimationConfigurations = new System.Collections.Generic.List<PlatformerAnimationConfiguration>();
            Configurations = new System.Collections.ObjectModel.ReadOnlyCollection<PlatformerAnimationConfiguration>(platformerAnimationConfigurations);
        }

        public PlatformerAnimationConfiguration GetConfiguration(string animationName) =>
                    Configurations.First(item => item.AnimationName == animationName);

        public void AddLayer(PlatformerAnimationConfiguration configuration)
        {
            var layer = this.AddLayer();

            platformerAnimationConfigurations.Add(configuration);

";

            if(GlueState.Self.CurrentGlueProject.FileVersion >= (int)GlueProjectSave.GluxVersions.AnimationLayerHasName)
            {
                toReturn +=
                    @"
            layer.Name = configuration.AnimationName;
";

            }

            toReturn +=
                @"
            layer.EveryFrameAction = () =>
            {
                bool shouldSet = true;
                var absoluteXVelocity = System.Math.Abs(PlatformerEntity.XVelocity);
                var yVelocity = PlatformerEntity.YVelocity;
                if(shouldSet && !string.IsNullOrEmpty( configuration.MovementName))
                {
                    shouldSet = configuration.MovementName == PlatformerEntity.CurrentMovementName;
                }

                shouldSet = shouldSet && (absoluteXVelocity < configuration.MinXVelocityAbsolute) == false;
                shouldSet = shouldSet && (yVelocity < configuration.MinYVelocity) == false;
                shouldSet = shouldSet && (absoluteXVelocity > configuration.MaxXVelocityAbsolute) == false;
                shouldSet = shouldSet && (yVelocity > configuration.MaxYVelocity) == false;

                shouldSet = shouldSet &&
                    (configuration.OnGroundRequirement == null || PlatformerEntity.IsOnGround == configuration.OnGroundRequirement);

                if(shouldSet && configuration.AdditionalPredicate != null)
                {
                    shouldSet = configuration.AdditionalPredicate();
                }

                if (shouldSet)
                {
                    switch(configuration.AnimationSpeedAssignment)
                    {
                        case AnimationSpeedAssignment.ForceTo1:
                            {
                                var asSprite = this.AnimatedObject as FlatRedBall.Sprite;

                                asSprite.AnimationSpeed = 1;
                            }
                            break;
                        case AnimationSpeedAssignment.NoAssignment:
                            break;
                        case AnimationSpeedAssignment.BasedOnMultiplier:
                            {
                                var asSprite = this.AnimatedObject as FlatRedBall.Sprite;

                                if(configuration.AbsoluteXVelocityAnimationSpeedMultiplier != null)
                                {
                                    asSprite.AnimationSpeed = configuration.AbsoluteXVelocityAnimationSpeedMultiplier.Value *
                                        absoluteXVelocity;
                                }
                                else if(configuration.AbsoluteYVelocityAnimationSpeedMultiplier != null)
                                {
{'fraction_non_alphanumeric': 0.06723844971275993, 'fraction_numerical': 0.00048547617121126303, 'mean_word_length': 1.7681970884658456, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4336492', 'n_tokens_mistral': 2864, 'n_tokens_neox': 2694, 'n_words': 499}