using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace Pilz.UI;

public class PaintingObjectListLayering
{


    public PaintingObjectList ObjectList { get; private set; }
    public Dictionary<int, Func<PaintingObject, bool>> Conditions { get; private set; } = new Dictionary<int, Func<PaintingObject, bool>>();

    /// <summary>
    /// Get the order function will checkout the conditions.
    /// </summary>
    /// <returns>Returns true, if conditions are aviable, otherwise false.</returns>
    public bool EnableConditions
    {
        get
        {
            return Conditions.Any();
        }
    }

    /// <summary>
    /// Create a new instance of object list layer managing.
    /// </summary>
    /// <param name="list"></param>
    public PaintingObjectListLayering(PaintingObjectList list)
    {
        ObjectList = list;
    }

    /// <summary>
    /// Order all objects using the conditions. If no conditions are setted, this method will do nothing.
    /// </summary>
    public void OrderAll()
    {
        if (EnableConditions)
            OrderAllPrivate();
    }

    private void OrderAllPrivate()
    {
        var list = ObjectList;
        var listOld = list.ToList();
        var toRemove = new List<PaintingObject>();

        // Disable raising events
        ObjectList.EnableRaisingEvents = false;

        // Clear list
        list.Clear();

        // Add ordered
        foreach (var kvp in Conditions.OrderBy(n => n.Key))
        {
            var func = kvp.Value;

            foreach (PaintingObject obj in listOld)
            {
                if (func(obj))
                {
                    // Add to list
                    list.Add(obj);

                    // Add to remove
                    toRemove.Add(obj);
                }
            }

            // Remove remembered objects
            foreach (PaintingObject obj in toRemove)
                listOld.Remove(obj);
            toRemove.Clear();
        }

        // Enable raising events
        ObjectList.EnableRaisingEvents = true;

        // Refresh
        ObjectList.MyParent?.Refresh();
    }

}