using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Events;
using Artemis.Core.Exceptions;
using Artemis.Core.Plugins.Models;
using SkiaSharp;
namespace Artemis.Core.Models.Profile.LayerProperties
{
///
/// Contains all the properties of the layer and provides easy access to the default properties.
///
public class LayerPropertyCollection : IEnumerable
{
private readonly Dictionary<(Guid, string), BaseLayerProperty> _properties;
internal LayerPropertyCollection(Layer layer)
{
_properties = new Dictionary<(Guid, string), BaseLayerProperty>();
Layer = layer;
CreateDefaultProperties();
}
///
/// Gets the layer these properties are applied on
///
public Layer Layer { get; }
///
public IEnumerator GetEnumerator()
{
return _properties.Values.GetEnumerator();
}
///
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
///
/// If found, returns the matching the provided ID
///
/// The type of the layer property
/// The plugin this property belongs to
///
///
public LayerProperty GetLayerPropertyById(PluginInfo pluginInfo, string id)
{
if (!_properties.ContainsKey((pluginInfo.Guid, id)))
return null;
var property = _properties[(pluginInfo.Guid, id)];
if (property.Type != typeof(T))
throw new ArtemisCoreException($"Property type mismatch. Expected property {property} to have type {typeof(T)} but it has {property.Type} instead.");
return (LayerProperty)_properties[(pluginInfo.Guid, id)];
}
///
/// Removes the provided layer property from the layer.
///
/// The type of value of the layer property
/// The property to remove from the layer
internal void RemoveLayerProperty(LayerProperty layerProperty)
{
RemoveLayerProperty((BaseLayerProperty) layerProperty);
}
///
/// Removes the provided layer property from the layer.
///
/// The property to remove from the layer
internal void RemoveLayerProperty(BaseLayerProperty layerProperty)
{
if (!_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id)))
throw new ArtemisCoreException($"Could not find a property with ID {layerProperty.Id}.");
var property = _properties[(layerProperty.PluginInfo.Guid, layerProperty.Id)];
property.Parent?.Children.Remove(property);
_properties.Remove((layerProperty.PluginInfo.Guid, layerProperty.Id));
OnLayerPropertyRemoved(new LayerPropertyEventArgs(property));
}
///
/// Adds the provided layer property and its children to the layer.
/// If found, the last stored base value and keyframes will be applied to the provided property.
///
/// The type of value of the layer property
/// The property to apply to the layer
/// True if an existing value was found and applied, otherwise false.
internal bool RegisterLayerProperty(LayerProperty layerProperty)
{
return RegisterLayerProperty((BaseLayerProperty) layerProperty);
}
///
/// Adds the provided layer property to the layer.
/// If found, the last stored base value and keyframes will be applied to the provided property.
///
/// The property to apply to the layer
/// True if an existing value was found and applied, otherwise false.
internal bool RegisterLayerProperty(BaseLayerProperty layerProperty)
{
if (_properties.ContainsKey((layerProperty.PluginInfo.Guid, layerProperty.Id)))
throw new ArtemisCoreException($"Duplicate property ID detected. Layer already contains a property with ID {layerProperty.Id}.");
var entity = Layer.LayerEntity.PropertyEntities.FirstOrDefault(p => p.Id == layerProperty.Id && p.ValueType == layerProperty.Type.Name);
// TODO: Catch serialization exceptions and log them
if (entity != null)
layerProperty.ApplyToProperty(entity);
_properties.Add((layerProperty.PluginInfo.Guid, layerProperty.Id), layerProperty);
OnLayerPropertyRegistered(new LayerPropertyEventArgs(layerProperty));
return entity != null;
}
#region Default properties
///
/// Gets the shape type property of the layer
///
public LayerProperty ShapeType { get; private set; }
///
/// Gets the fill type property of the layer
///
public LayerProperty FillType { get; private set; }
///
/// Gets the blend mode property of the layer
///
public LayerProperty BlendMode { get; private set; }
///
/// Gets the brush reference property of the layer
///
public LayerProperty BrushReference { get; private set; }
///
/// Gets the anchor point property of the layer
///
public LayerProperty AnchorPoint { get; private set; }
///
/// Gets the position of the layer
///
public LayerProperty Position { get; private set; }
///
/// Gets the size property of the layer
///
public LayerProperty Scale { get; private set; }
///
/// Gets the rotation property of the layer range 0 - 360
///
public LayerProperty Rotation { get; private set; }
///
/// Gets the opacity property of the layer range 0 - 100
///
public LayerProperty Opacity { get; private set; }
private void CreateDefaultProperties()
{
// Shape
var shape = new LayerProperty