// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System.Drawing;

namespace System.Windows.Forms.Design;

/// <summary>
///  This class handles all design time behavior for the group box class. Group
///  boxes may contain sub-components and therefore use the frame designer.
/// </summary>
internal class GroupBoxDesigner : ParentControlDesigner
{
    private InheritanceUI _inheritanceUI;

    /// <summary>
    ///  Determines the default location for a control added to this designer.
    ///  it is usually (0,0), but may be modified if the container has special borders, etc.
    /// </summary>
    protected override Point DefaultControlLocation
    {
        get
        {
            GroupBox gb = (GroupBox)Control;
            return new Point(gb.DisplayRectangle.X, gb.DisplayRectangle.Y);
        }
    }

#if TESTVALUEUI
    /// <summary>
    ///  Initializes the designer with the given component. The designer can
    ///  get the component's site and request services from it in this call.
    /// </summary>
    public override void Initialize(IComponent component) {
        base.Initialize(component);
        
        AutoResizeHandles = true;
        
        IPropertyValueUIService pvUISvc = (IPropertyValueUIService)component.Site.GetService(typeof(IPropertyValueUIService));
        
        if (pvUISvc != null) {
            pvUISvc.AddPropertyValueUIHandler(new PropertyValueUIHandler(this.OnGetUIValueItem));
        }
    }
    
    private void OnGetUIValueItem(object component, PropertyDescriptor propDesc, ArrayList valueUIItemList){
    
        if (propDesc.PropertyType == typeof(string)) {
            Bitmap bmp = new(typeof(GroupBoxDesigner), "BoundProperty.bmp");
            bmp.MakeTransparent();
            valueUIItemList.Add(new LocalUIItem(bmp, new PropertyValueUIItemInvokeHandler(this.OnPropertyValueUIItemInvoke), "Data Can"));
            
            //bmp = new Bitmap("BoundProperty.bmp");
            valueUIItemList.Add(new LocalUIItem(bmp, new PropertyValueUIItemInvokeHandler(this.OnPropertyValueUIItemInvoke), "Little Button"));
        }
        
        
    }

    private void OnPropertyValueUIItemInvoke(ITypeDescriptorContext context, PropertyDescriptor descriptor, PropertyValueUIItem invokedItem) {
        Debug.Fail("propertyuivalue '" + invokedItem.ToolTip + "' invoked");
    }
    
#endif

    /// <summary>
    ///  We override this because even though we still want to
    ///  offset our grid for our display rectangle, we still want
    ///  to align to our parent's grid - so we don't look funny
    /// </summary>
    protected override void OnPaintAdornments(PaintEventArgs pe)
    {
        if (DrawGrid)
        {
            Control control = Control;
            Rectangle rectangle = Control.DisplayRectangle;

            rectangle.Width++; // gpr: FillRectangle with a TextureBrush comes up one pixel short
            rectangle.Height++;
            ControlPaint.DrawGrid(pe.Graphics, rectangle, GridSize, control.BackColor);
        }

        // If this control is being inherited, paint it
        //
        if (Inherited)
        {
            _inheritanceUI ??= (InheritanceUI)GetService(typeof(InheritanceUI));

            if (_inheritanceUI is not null)
            {
                pe.Graphics.DrawImage(InheritanceUI.InheritanceGlyph, 0, 0);
            }
        }
    }

    /// <summary>
    ///  We override our base class's WndProc here because
    ///  the group box always returns HTTRANSPARENT. This
    ///  causes the mouse to go "through" the group box, but
    ///  that's not what we want at design time.
    /// </summary>
    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case (int)PInvokeCore.WM_NCHITTEST:
                // The group box always fires HTTRANSPARENT, which causes the message to go to our parent. We want
                // the group box's designer to get these messages, however, so change this.
                base.WndProc(ref m);

                if (m.ResultInternal == PInvoke.HTTRANSPARENT)
                {
                    m.ResultInternal = (LRESULT)(nint)PInvoke.HTCLIENT;
                }

                break;

            default:
                base.WndProc(ref m);
                break;
        }
    }

#if TESTVALUEUI
    
    internal class LocalUIItem : PropertyValueUIItem {
        private string itemName;
        
        public LocalUIItem(Image img, PropertyValueUIItemInvokeHandler handler, string itemName) : base(img, handler, itemName) {
            this.itemName = itemName;
        }
    }
#endif
}
