<commit_before>﻿using FlatRedBall.Glue.CodeGeneration;
using FlatRedBall.Glue.CodeGeneration.CodeBuilder;
using FlatRedBall.Glue.SaveClasses;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using TiledPluginCore.ViewModels;
using TileGraphicsPlugin;
using TileGraphicsPlugin.CodeGeneration;

namespace TiledPluginCore.CodeGeneration
{
    class TileNodeNetworkCodeGenerator : ElementComponentCodeGenerator
    {
        public override ICodeBlock GenerateInitializeLate(ICodeBlock codeBlock, IElement element)
        {
            NamedObjectSave[] tileNodeNetworksCollections = GetAllTileNodeNetworkNamedObjectsInElement(element);

            foreach (var tileShapeCollection in tileNodeNetworksCollections)
            {
                GenerateCodeFor(tileShapeCollection, codeBlock);
            }

            return codeBlock;
        }

        static NamedObjectSave[] GetAllTileNodeNetworkNamedObjectsInElement(IElement element)
        {
            return element
                .AllNamedObjects
                .Where(item => item.GetAssetTypeInfo() == AssetTypeInfoAdder.Self.TileNodeNetworkAssetTypeInfo)
                .ToArray();
        }

        public override ICodeBlock GenerateAddToManagers(ICodeBlock codeBlock, IElement element)
        {
            NamedObjectSave[] tileNodeNetworks = GetAllTileNodeNetworkNamedObjectsInElement(element);



            foreach (var nodeNetwork in tileNodeNetworks)
            {
                T Get<T>(string name)
                {
                    return nodeNetwork.Properties.GetValue<T>(name);
                }

                var creationOptions = Get<TileNodeNetworkCreationOptions>(
                    nameof(TileNodeNetworkPropertiesViewModel.NetworkCreationOptions));

                var variable = nodeNetwork.GetCustomVariable("Visible");

                bool filledInHere = 
                    creationOptions == TileNodeNetworkCreationOptions.FillCompletely ||
                    creationOptions == TileNodeNetworkCreationOptions.Empty;

                if (variable != null && variable.Value is bool && ((bool)variable.Value) == true &&
                    filledInHere)
                {
                    codeBlock.Line($"{nodeNetwork.FieldName}.Visible = true;");
                    //codeBlock.Line($"{nodeNetwork.FieldName}.AddToLayer(null);");
                    // todo - make it visible here!
                    //throw new NotImplementedException();
                }

            }

            return codeBlock;
        }

        public static string GenerateConstructorFor(NamedObjectSave namedObjectSave)
        {
            T Get<T>(string name)
            {
                return namedObjectSave.Properties.GetValue<T>(name);
            }
            string FloatString(float value) => value.ToString(CultureInfo.InvariantCulture) + "f";

            var creationOptions = Get<TileNodeNetworkCreationOptions>(
                nameof(TileNodeNetworkPropertiesViewModel.NetworkCreationOptions));

            bool comesFromLayer = creationOptions == TileNodeNetworkCreationOptions.FromLayer;

            var instanceName = namedObjectSave.FieldName;
            var mapName = Get<string>(nameof(TileNodeNetworkPropertiesViewModel.SourceTmxName));
            var fourOrEight = Get<FlatRedBall.AI.Pathfinding.DirectionalType>(nameof(TileNodeNetworkPropertiesViewModel.DirectionalType));

            string toReturn = null;

            switch(creationOptions)
            {
                case TileNodeNetworkCreationOptions.FillCompletely:

                    var tileSize = Get<float>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkTileSize));
                    var tileSizeString = FloatString(tileSize);

                    var leftFill = Get<float>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillLeft));
                    var leftFillString = FloatString(leftFill);


                    var widthFill = Get<int>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillWidth));
                    var heightFill = Get<int>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillHeight));

                    var topFill = Get<float>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillTop));

                    // heightFill - 1, because if it's just 1 cell high, we use the value as-is. Then each additional moves the bottom left by 1
                    var bottomFillString = FloatString(topFill - (heightFill-1) * tileSize);

                    toReturn = $"{instanceName} = new FlatRedBall.AI.Pathfinding.TileNodeNetwork({leftFillString}, {bottomFillString}, {tileSizeString}, {widthFill}, {heightFill}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight});";
                    break;
                case TileNodeNetworkCreationOptions.FromType:
                    var typeName = Get<string>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkTileTypeName));

                    if (!string.IsNullOrEmpty(typeName))
                    {
                        toReturn = $"{instanceName} = FlatRedBall.AI.Pathfinding.TileNodeNetworkCreator.CreateFromTypes({mapName}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight}, new string[]{{ \"{typeName}\" }});";
                    }
                    else
                    {
                        toReturn = $"{instanceName} = new new FlatRedBall.AI.Pathfinding.TileNodeNetwork();";
                    }
                    break;
                case TileNodeNetworkCreationOptions.FromProperties:
                    var propertyName = Get<string>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkPropertyName));

                    if (!string.IsNullOrEmpty(propertyName))
                    {
                        toReturn = $"{instanceName} = FlatRedBall.AI.Pathfinding.TileNodeNetworkCreator.CreateFromTilesWithProperties({mapName}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight}, new string[]{{ \"{propertyName}\" }});";
                    }
                    else
                    {
                        toReturn = $"{instanceName} = new new FlatRedBall.AI.Pathfinding.TileNodeNetwork();";
                    }
                    break;<commit_msg>Implemented Empty TileNodeNetwork support in Glue.<commit_after>﻿using FlatRedBall.Glue.CodeGeneration;
using FlatRedBall.Glue.CodeGeneration.CodeBuilder;
using FlatRedBall.Glue.SaveClasses;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using TiledPluginCore.ViewModels;
using TileGraphicsPlugin;
using TileGraphicsPlugin.CodeGeneration;

namespace TiledPluginCore.CodeGeneration
{
    class TileNodeNetworkCodeGenerator : ElementComponentCodeGenerator
    {
        public override ICodeBlock GenerateInitializeLate(ICodeBlock codeBlock, IElement element)
        {
            NamedObjectSave[] tileNodeNetworksCollections = GetAllTileNodeNetworkNamedObjectsInElement(element);

            foreach (var tileShapeCollection in tileNodeNetworksCollections)
            {
                GenerateCodeFor(tileShapeCollection, codeBlock);
            }

            return codeBlock;
        }

        static NamedObjectSave[] GetAllTileNodeNetworkNamedObjectsInElement(IElement element)
        {
            return element
                .AllNamedObjects
                .Where(item => item.GetAssetTypeInfo() == AssetTypeInfoAdder.Self.TileNodeNetworkAssetTypeInfo)
                .ToArray();
        }

        public override ICodeBlock GenerateAddToManagers(ICodeBlock codeBlock, IElement element)
        {
            NamedObjectSave[] tileNodeNetworks = GetAllTileNodeNetworkNamedObjectsInElement(element);



            foreach (var nodeNetwork in tileNodeNetworks)
            {
                T Get<T>(string name)
                {
                    return nodeNetwork.Properties.GetValue<T>(name);
                }

                var creationOptions = Get<TileNodeNetworkCreationOptions>(
                    nameof(TileNodeNetworkPropertiesViewModel.NetworkCreationOptions));

                var variable = nodeNetwork.GetCustomVariable("Visible");

                bool filledInHere = 
                    creationOptions == TileNodeNetworkCreationOptions.FillCompletely ||
                    creationOptions == TileNodeNetworkCreationOptions.Empty;

                if (variable != null && variable.Value is bool && ((bool)variable.Value) == true &&
                    filledInHere)
                {
                    codeBlock.Line($"{nodeNetwork.FieldName}.Visible = true;");
                    //codeBlock.Line($"{nodeNetwork.FieldName}.AddToLayer(null);");
                    // todo - make it visible here!
                    //throw new NotImplementedException();
                }

            }

            return codeBlock;
        }

        public static string GenerateConstructorFor(NamedObjectSave namedObjectSave)
        {
            T Get<T>(string name)
            {
                return namedObjectSave.Properties.GetValue<T>(name);
            }
            string FloatString(float value) => value.ToString(CultureInfo.InvariantCulture) + "f";

            var creationOptions = Get<TileNodeNetworkCreationOptions>(
                nameof(TileNodeNetworkPropertiesViewModel.NetworkCreationOptions));

            bool comesFromLayer = creationOptions == TileNodeNetworkCreationOptions.FromLayer;

            var instanceName = namedObjectSave.FieldName;
            var mapName = Get<string>(nameof(TileNodeNetworkPropertiesViewModel.SourceTmxName));
            var fourOrEight = Get<FlatRedBall.AI.Pathfinding.DirectionalType>(nameof(TileNodeNetworkPropertiesViewModel.DirectionalType));

            string toReturn = null;

            switch(creationOptions)
            {
                case TileNodeNetworkCreationOptions.Empty:
                    // assume this for now:
                    {
                        var tileSize = 16;
                        var numberOfXTiles = 32;
                        var numberOfYTiles = 32;

                        var tileSizeString = FloatString(tileSize);

                        var leftFill = tileSize/2.0f;
                        var leftFillString = FloatString(leftFill);



                        var topFill = 0 - tileSize / 2.0f;
                        // heightFill - 1, because if it's just 1 cell high, we use the value as-is. Then each additional moves the bottom left by 1
                        var bottomFillString = FloatString(topFill - (numberOfYTiles - 1) * tileSize);
                        toReturn = $"{instanceName} = new FlatRedBall.AI.Pathfinding.TileNodeNetwork({leftFillString}, {bottomFillString}, {tileSizeString}, {numberOfXTiles}, {numberOfYTiles}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight});";
                    }

                    break;
                case TileNodeNetworkCreationOptions.FillCompletely:
                    {
                        var tileSize = Get<float>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkTileSize));
                        var tileSizeString = FloatString(tileSize);

                        var leftFill = Get<float>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillLeft));
                        var leftFillString = FloatString(leftFill);


                        var widthFill = Get<int>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillWidth));
                        var heightFill = Get<int>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillHeight));

                        var topFill = Get<float>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkFillTop));

                        // heightFill - 1, because if it's just 1 cell high, we use the value as-is. Then each additional moves the bottom left by 1
                        var bottomFillString = FloatString(topFill - (heightFill-1) * tileSize);

                        toReturn = $"{instanceName} = new FlatRedBall.AI.Pathfinding.TileNodeNetwork({leftFillString}, {bottomFillString}, {tileSizeString}, {widthFill}, {heightFill}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight});";
                    }
                    break;
                case TileNodeNetworkCreationOptions.FromType:
                    var typeName = Get<string>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkTileTypeName));

                    if (!string.IsNullOrEmpty(typeName))
                    {
                        toReturn = $"{instanceName} = FlatRedBall.AI.Pathfinding.TileNodeNetworkCreator.CreateFromTypes({mapName}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight}, new string[]{{ \"{typeName}\" }});";
                    }
                    else
                    {
                        toReturn = $"{instanceName} = new new FlatRedBall.AI.Pathfinding.TileNodeNetwork();";
                    }
                    break;
                case TileNodeNetworkCreationOptions.FromProperties:
                    var propertyName = Get<string>(nameof(TileNodeNetworkPropertiesViewModel.NodeNetworkPropertyName));

                    if (!string.IsNullOrEmpty(propertyName))
                    {
                        toReturn = $"{instanceName} = FlatRedBall.AI.Pathfinding.TileNodeNetworkCreator.CreateFromTilesWithProperties({mapName}, FlatRedBall.AI.Pathfinding.DirectionalType.{fourOrEight}, new string[]{{ \"{propertyName}\" }});";
                    }
                    else
                    {
                        toReturn = $"{instanceName} = new new FlatRedBall.AI.Pathfinding.TileNodeNetwork();";
                    }
                    break;
{'fraction_non_alphanumeric': 0.08087701466531146, 'fraction_numerical': 0.0016698126905764484, 'mean_word_length': 2.110885275519422, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4337705', 'n_tokens_mistral': 3427, 'n_tokens_neox': 3110, 'n_words': 574}