using System.Runtime.CompilerServices;
using System.Xml;
using Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Origin;
using Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Parent;
using Hawkeye.VisionBuilder.Workflow.Links;

using OpenCvSharp;

namespace Hawkeye.VisionBuilder.Workflow.Datatypes.Elements.Rectangle;

public class RectangleElement : IGraphicsElement
{
    
    public bool Editable { get; set; }
    public bool IsGood { get; set; }
    
    public Vector2 Location { get; set; }
    public Vector2 Offset { get; set; }
    
    public Vector2 Size { get; set; }

    public void Draw(ICanvas canvas)
    {
        
        canvas.DrawRectangle(Offset+Location, Size,IsGood);
        canvas.DrawNode(Offset+Location);
        canvas.DrawNode(Offset+Location + Size);
        
    }

    public void FillMat(Mat mat)
    {
        var location = Offset + Location;
        Cv2.Rectangle(mat,
            new Rect((int)location.X, (int)location.Y, (int)Size.X,
                (int)Size.Y),
            Scalar.White, -1);
    }


    public INode? GetNode(Vector2 position,float thDistance)
    {
        if ((Location + Offset - position).Length()< thDistance)
        {
            return new RectangleAnchorNode(this);
        }
        if((Size + Location+Offset - position).Length() < thDistance)
        {
            return new RectangleSizeNode(this);
        }

        return null;
    }

    public void SetPivot(Vector2 pivot)
    {
        Location += Offset;
        Offset =pivot;
        Location-=Offset;
    }

    public void MovePivot(Vector2 pivot)
    {
        Offset = pivot;
    }

    public RectangleElement()
    {
        
    }


    public void Save(BinaryWriter bw)
    {
        bw.Write(Editable);
        bw.Write(IsGood);
        bw.Write(Location.X);
        bw.Write(Location.Y);
        bw.Write(Offset.X);
        bw.Write(Offset.Y);
        bw.Write(Size.X);
        bw.Write(Size.Y);
    }

    public void Load(BinaryReader br)
    {
        Editable = br.ReadBoolean();
        IsGood = br.ReadBoolean();
        Location = new Vector2(br.ReadSingle(), br.ReadSingle());
        Offset = new Vector2(br.ReadSingle(), br.ReadSingle());
        Size = new Vector2(br.ReadSingle(), br.ReadSingle());
    }

    public void SaveXML(XmlWriter writer)
    {
        writer.WriteStartElement("Editable");
        writer.WriteString(Editable.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("IsGood");
        writer.WriteString(IsGood.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("LocationX");
        writer.WriteString(Location.X.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("LocationY");
        writer.WriteString(Location.Y.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("OffsetX");
        writer.WriteString(Offset.X.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("OffsetY");
        writer.WriteString(Offset.Y.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("SizeX");
        writer.WriteString(Size.X.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("SizeY");
        writer.WriteString(Size.Y.ToString());
        writer.WriteEndElement();
    }

    public void LoadXML(XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element && reader.Name == "Editable")
            {
                Editable = bool.Parse(reader.ReadElementContentAsString());
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "IsGood")
            {
                IsGood = bool.Parse(reader.ReadElementContentAsString());
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "LocationX")
            {
                var x = float.Parse(reader.ReadElementContentAsString());
                Location = new Vector2(x, Location.Y);
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "LocationY")
            {
                var y = float.Parse(reader.ReadElementContentAsString());
                Location = new Vector2(Location.X, y);
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "OffsetX")
            {
                var x = float.Parse(reader.ReadElementContentAsString());
                Offset = new Vector2(x, Offset.Y);
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "OffsetY")
            {
                var y = float.Parse(reader.ReadElementContentAsString());
                Offset = new Vector2(Offset.X, y);
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "SizeX")
            {
                var x = float.Parse(reader.ReadElementContentAsString());
                Size = new Vector2(x, Size.Y);
            }
            else if (reader.NodeType == XmlNodeType.Element && reader.Name == "SizeY")
            {
                var y = float.Parse(reader.ReadElementContentAsString());
                Size = new Vector2(Size.X, y);
            }
            else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "RectangleElement")
            {
                break;
            }
        }
    }
}