using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Xml.Serialization;

namespace QC.QMine.QMineInterface;

[Serializable]
public class BindableObject : INotifyPropertyChanged, IObjectChanged
{
	private bool hasObjectChanged;

	private List<IObjectChanged> children = new List<IObjectChanged>();

	[XmlIgnore]
	public IObjectChanged Parent { get; set; }

	[XmlIgnore]
	public bool HasObjectChanged
	{
		get
		{
			return hasObjectChanged;
		}
		set
		{
			if (hasObjectChanged != value)
			{
				hasObjectChanged = value;
				if (this.PropertyChanged != null)
				{
					this.PropertyChanged(this, new PropertyChangedEventArgs("HasObjectChanged"));
				}
			}
		}
	}

	[XmlIgnore]
	public List<IObjectChanged> Children
	{
		get
		{
			return children;
		}
		set
		{
			children = value;
		}
	}

	[field: NonSerialized]
	public event PropertyChangedEventHandler PropertyChanged;

	[field: NonSerialized]
	public event Action<string> ObjectChanged;

	protected virtual void OnPropertyChanged(string propertyName)
	{
		if (VerifyProperty(propertyName))
		{
			PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
			if (propertyChanged != null)
			{
				PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
				Changed(propertyName);
				propertyChanged(this, e);
			}
		}
	}

	private bool VerifyProperty(string propertyName)
	{
		bool flag = false;
		Type type = GetType();
		PropertyInfo property = type.GetProperty(propertyName);
		if (property == null)
		{
			return false;
		}
		return true;
	}

	public virtual void Changed(string changedFieldName)
	{
		HasObjectChanged = true;
		if (this.ObjectChanged != null)
		{
			this.ObjectChanged(changedFieldName);
		}
		if (Parent != null)
		{
			Parent.Changed(changedFieldName);
		}
	}

	public virtual void EstablishParentChildRelationOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
	{
		if (e.Action == NotifyCollectionChangedAction.Add)
		{
			foreach (IObjectChanged newItem in e.NewItems)
			{
				SetParentAndChildRelation(newItem, this);
			}
		}
		if (e.Action != NotifyCollectionChangedAction.Remove)
		{
			return;
		}
		foreach (IObjectChanged oldItem in e.OldItems)
		{
			Children.Remove(oldItem);
		}
	}

	public virtual void EstablishParentChildRelationship()
	{
	}

	protected void SetParentAndChildRelation(IObjectChanged obj, IObjectChanged parent)
	{
		obj.Parent = parent;
		parent.Children.Add(obj);
		obj.EstablishParentChildRelationship();
	}

	public void ResetChange()
	{
		HasObjectChanged = false;
		if (Children == null)
		{
			return;
		}
		foreach (IObjectChanged child in Children)
		{
			child.ResetChange();
		}
	}
}
