using System;
using System.Windows;
using System.Windows.Controls;

namespace ScreenToGif.Controls
{
    ///<summary>
    ///A panel that organizes it's inner elements in a circular fashion.
    ///</summary>
    public class RadialPanel : Panel
    {
        /// <summary>
        /// Measure each children and give as much room as they want.
        /// </summary>
        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (UIElement elem in Children)
            {
                //Give Infinite size as the avaiable size for all the children.
                elem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            }

            return base.MeasureOverride(availableSize);
        }

        /// <summary>
        /// Arrange all children based on the geometric equations for the circle.
        /// </summary>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if (Children.Count == 0)
                return finalSize;

            var angle = 0d;

            //Degrees converted to Radian by multiplying with PI/180
            var incrementalAngularSpace = (360.0 / Children.Count) * (Math.PI / 180);

            //An approximate radii based on the avialable size , obviusly a better approach is needed here.
            var radiusX = finalSize.Width / 2.4;
            var radiusY = finalSize.Height / 2.4;

            foreach (UIElement elem in Children)
            {
                //Calculate the point on the circle for the element.
                var childPoint = new Point(Math.Cos(angle) * radiusX, -Math.Sin(angle) * radiusY);

                //Offsetting the point to the Avalable rectangular area which is FinalSize.
                var actualChildPoint = new Point(finalSize.Width / 2 + childPoint.X - elem.DesiredSize.Width / 2, finalSize.Height / 2 + childPoint.Y - elem.DesiredSize.Height / 2);

                //Call Arrange method on the child element by giving the calculated point as the placementPoint.
                elem.Arrange(new Rect(actualChildPoint.X, actualChildPoint.Y, elem.DesiredSize.Width, elem.DesiredSize.Height));

                //Calculate the new _angle for the next element.
                angle += incrementalAngularSpace;
            }

            return finalSize;
        }
    }
}