using Avalonia;
using Avalonia.Controls;
using SPTInstaller.Behaviors;
using System.Linq;

namespace SPTInstaller.CustomControls;

public class DistributedSpacePanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        var children = Children;

        for (int i = 0; i < children.Count; i++)
        {
            // measure child objects so we can use their desired size in the arrange override
            var child = children[i];
            child.Measure(availableSize);
        }

        // we want to use all available space
        return availableSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        var children = Children;
        Rect rcChild = new Rect(finalSize);
        double previousChildSize = 0.0;

        // get child objects that don't want to span the entire control
        var nonSpanningChildren = children.Where(x => x.GetValue(SpanBehavior.SpanProperty) == false).ToList();

        // get the total height off all non-spanning child objects
        var totalChildHeight = nonSpanningChildren.Select(x => x.DesiredSize.Height).Sum();

        // remove the total child height from our controls final size and divide it by the total non-spanning child objects
        // except the last one, since it needs no space after it
        var spacing = (finalSize.Height - totalChildHeight) / (nonSpanningChildren.Count - 1);

        for (int i = 0; i < children.Count; i++)
        {
            var child = children[i];

            var spanChild = child.GetValue(SpanBehavior.SpanProperty);

            if (spanChild)
            {
                // move any spanning children to the top of the array to push them behind the other controls (visually)
                children.Move(i, 0);

                rcChild = rcChild.WithY(0)
                    .WithX(0)
                    .WithHeight(finalSize.Height)
                    .WithWidth(finalSize.Width);



                child.Arrange(rcChild);
                continue;
            };

            rcChild = rcChild.WithY(rcChild.Y + previousChildSize);
            previousChildSize = child.DesiredSize.Height;
            rcChild = rcChild.WithHeight(previousChildSize)
                .WithWidth(Math.Max(finalSize.Width, child.DesiredSize.Width));

            previousChildSize += spacing;

            child.Arrange(rcChild);
        }

        return finalSize;
    }
}