using System.Linq;
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
using HandyControl.Tools;
using HandyControl.Tools.Extension;

namespace HandyControl.Controls
{
    public class Row : Panel
    {
        private ColLayoutStatus _layoutStatus;

        private double _maxChildDesiredHeight;

        private double _totalAutoWidth;

        public static readonly DependencyProperty GutterProperty = DependencyProperty.Register(
            "Gutter", typeof(double), typeof(Row), new PropertyMetadata(ValueBoxes.Double0Box, null, OnGutterCoerce), ValidateHelper.IsInRangeOfPosDoubleIncludeZero);

        private static object OnGutterCoerce(DependencyObject d, object basevalue) => ValidateHelper.IsInRangeOfPosDoubleIncludeZero(basevalue) ? basevalue : .0;

        public double Gutter
        {
            get => (double) GetValue(GutterProperty);
            set => SetValue(GutterProperty, value);
        }

        protected override Size MeasureOverride(Size constraint)
        {
            var totalCellCount = 0;
            var totalRowCount = 1;
            var gutterHalf = Gutter / 2;
            _totalAutoWidth = 0;

            foreach (var child in InternalChildren.OfType<Col>())
            {
                child.Margin = new Thickness(gutterHalf);
                child.Measure(constraint);
                var childDesiredSize = child.DesiredSize;

                if (_maxChildDesiredHeight < childDesiredSize.Height)
                {
                    _maxChildDesiredHeight = childDesiredSize.Height;
                }

                var cellCount = child.GetLayoutCellCount(_layoutStatus);
                totalCellCount += cellCount;

                if (totalCellCount > ColLayout.ColMaxCellCount)
                {
                    totalCellCount = cellCount;
                    totalRowCount++;
                }

                if (cellCount == 0 || child.IsFixed)
                {
                    _totalAutoWidth += childDesiredSize.Width;
                }
            }

            return new Size(0, _maxChildDesiredHeight * totalRowCount - Gutter);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            var totalCellCount = 0;
            var gutterHalf = Gutter / 2;
            var itemWidth = (finalSize.Width - _totalAutoWidth + Gutter) / ColLayout.ColMaxCellCount;
            var childBounds = new Rect(-gutterHalf, -gutterHalf, 0, _maxChildDesiredHeight);
            _layoutStatus = ColLayout.GetLayoutStatus(finalSize.Width);

            foreach (var child in InternalChildren.OfType<Col>())
            {
                var cellCount = child.GetLayoutCellCount(_layoutStatus);
                totalCellCount += cellCount;

                var childWidth = cellCount > 0 ? cellCount * itemWidth : child.DesiredSize.Width;

                childBounds.Width = childWidth;
                childBounds.X += child.Offset * itemWidth;
                if (totalCellCount > ColLayout.ColMaxCellCount)
                {
                    childBounds.X = -gutterHalf;
                    childBounds.Y += _maxChildDesiredHeight;
                    totalCellCount = cellCount;
                }

                child.Arrange(childBounds);
                childBounds.X += childWidth;
            }

            return finalSize;
        }
    }
}
