using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using Eina;
#if EFL_BETA
namespace Efl {
///
/// Generic helper class to ease manual implementation of C# models.
///
/// It provides an expanded API like async helpers to get children.
///
/// For MVVM-based models, provides a simpler API.
///
/// The type of the child model. It is the type used when adding/removing/getting items to this
/// model.
public class GenericModel : Efl.Object, Efl.IModel
{
private Efl.IModel model;
/// Creates a new model wrapping model.
/// The model to be wrapped.
/// The parent of the model.
public GenericModel (Efl.IModel model, Efl.Object parent = null) : base(parent)
{
this.model = model;
}
/// The list of properties available in the wrapped model.
public IEnumerable Properties
{
get { return GetProperties(); }
}
/// The number of children in the wrapped model.
public uint ChildrenCount
{
get { return GetChildrenCount(); }
}
/// The list of properties available in the wrapped model.
/// The list of properties in the model.
public IEnumerable GetProperties()
{
return model.GetProperties();
}
/// Gets the value of the given property in the wrapped model.
/// The property of the model.
/// The value of the property.
public Eina.Value GetProperty(System.String property)
{
return model.GetProperty(property);
}
/// Sets the value of the given property in the given model.
/// The property of the model.
/// The value of the property.
/// An that resolves when the property has
/// been set or reports an error if it could not be set.
public Eina.Future SetProperty(System.String property, Eina.Value value)
{
return model.SetProperty(property, value);
}
/// Returns the number of children in the wrapped model.
/// The number of children.
public uint GetChildrenCount()
{
return model.GetChildrenCount();
}
/// Returns an that will resolve when the property is ready to be read.
/// The property of the model.
/// An that resolves when the property is ready.
public Eina.Future GetPropertyReady(System.String property)
{
return model.GetPropertyReady(property);
}
/// Gets a number of children from the wrapped model.
/// The start of the range.
/// The size of the range.
/// An that resolves to an
/// of children models.
public Eina.Future GetChildrenSlice(uint start, uint count)
{
return model.GetChildrenSlice(start, count);
}
/// Adds a new object to the wrapper model.
/// The object to get the properties from.
public void Add(T o)
{
Efl.IModel child = (Efl.IModel)this.AddChild();
ModelHelper.SetProperties(o, child);
}
/// Adds a new child to the model and returns it.
/// The object to be wrapped.
public Efl.Object AddChild()
{
return model.AddChild();
}
/// Deletes the given child from the wrapped model.
/// The child to be deleted.
public void DelChild( Efl.Object child)
{
model.DelChild(child);
}
/// Gets the element at the specified index.
/// The position of the element.
/// Token to notify the async operation of external request to cancel.
async public System.Threading.Tasks.Task GetAtAsync(uint index)
{
using (Eina.Value v = await GetChildrenSliceAsync(index, 1).ConfigureAwait(false))
{
if (v.GetValueType().IsContainer())
{
var child = (Efl.IModel)v[0];
T obj = (T)Activator.CreateInstance(typeof(T), Array.Empty