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

namespace CustomPanels
{
    public class FanCanvas : Panel
    {
        public static readonly DependencyProperty OrientationProperty =
          DependencyProperty.Register("Orientation", typeof(Orientation),
          typeof(FanCanvas), new FrameworkPropertyMetadata(Orientation.Horizontal,
          FrameworkPropertyMetadataOptions.AffectsArrange));

        public static readonly DependencyProperty SpacingProperty =
          DependencyProperty.Register("Spacing", typeof(double),
          typeof(FanCanvas), new FrameworkPropertyMetadata(10d,
          FrameworkPropertyMetadataOptions.AffectsArrange));

        public static readonly DependencyProperty AngleIncrementProperty =
          DependencyProperty.Register("AngleIncrement", typeof(double),
          typeof(FanCanvas), new FrameworkPropertyMetadata(10d,
          FrameworkPropertyMetadataOptions.AffectsArrange));

        public Orientation Orientation
        {
            get { return (Orientation)GetValue(OrientationProperty); }
            set { SetValue(OrientationProperty, value); }
        }

        public double Spacing
        {
            get { return (double)GetValue(SpacingProperty); }
            set { SetValue(SpacingProperty, value); }
        }

        public double AngleIncrement
        {
            get { return (double)GetValue(AngleIncrementProperty); }
            set { SetValue(AngleIncrementProperty, value); }
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (UIElement child in this.Children)
            {
                // Daj każdemu elementowi podrzędnemu tyle miejsca, ile chce.
                if (child != null)
                    child.Measure(new Size(Double.PositiveInfinity,
                                           Double.PositiveInfinity));
            }

            // Sam panel FanCanvas nie potrzebuje miejsca, tak samo jak SimpleCanvas.
            return new Size(0, 0);
        }


        protected override Size ArrangeOverride(Size finalSize)
        {
            // Wycentruj elementy podrzędne
            Point location = new Point(0,0);
            double angle = GetStartingAngle();

            foreach (UIElement child in this.Children)
            {
                if (child != null)
                {
                    // Nadaj elementowi podrzędnemu jego pożądaną wielkość.
                    child.Arrange(new Rect(location, child.DesiredSize));

                    // UWAGA: zastąp każdą metodę RenderTransform metodą, która
                    //          układa elementy podrzędne w kształt wachlarza.
                    child.RenderTransform = new RotateTransform(angle, child.RenderSize.Width / 2, child.RenderSize.Height);

                    // Zaktualizuj przesunięcie i kąt następnego elementu.
                    if (Orientation == Orientation.Vertical)
                        location.Y += Spacing;
                    else
                        location.X += Spacing;

                    angle += AngleIncrement;
                }
            }

            // Wypełnij całą przydzieloną przestrzeń.
            return finalSize;
        }

        double GetStartingAngle()
        {
            double angle;

            if (this.Children.Count % 2 != 0)
                // Nieparzyste, a więc środkowy element będzie mieć kąt == 0.
                angle = -AngleIncrement * (this.Children.Count / 2);
            else
                // Parzyste, a więc dwa środkowe elementy otrzymają po połowie AngleIncrement z obu stron kąta 0.
                angle = -AngleIncrement * (this.Children.Count / 2) + AngleIncrement / 2;

            // Jeśli orientacja jest pionowa, obróć o 90 stopni.
            if (Orientation == Orientation.Vertical)
                angle += 90;

            return angle;
        }
    }
}