using System;
using System.Collections.Generic;
using System.Text;
using _ElementState = nft.core.structure.CatalogVariableCollection.ElementState;

namespace nft.core.structure {
    public delegate void CatalogVarCollectionElementEventHandler(CatalogVarCollectionElementEventArgs arg);

    /// <summary>
    /// CatalogVariableCollectionの要素としてICatalogVariableをホストするオブジェクト
    /// </summary>
    public class CatalogVarCollectionElement {
        protected string id;
        protected string name;
        protected ICatalogVariable var;
        protected IList<string> influences;
        protected bool bLoop, bRand, bAuto;

        public CatalogVarCollectionElement(string _id, string _name, bool loop = true, bool rand = true, bool auto = false)
            : this(_id, _name, null, loop, rand, auto) {
        }

        public CatalogVarCollectionElement(string _id, string _name, ICatalogVariable catvar, bool loop = true, bool rand = true, bool auto = false) {
            this.id = _id;
            this.name = _name;
            this.bLoop = loop;
            this.bRand = rand;
            this.bAuto = auto;
            this.var = catvar;
        }
        public bool AllowLoop { get { return bLoop; } }
        public bool AllowRandom { get { return bRand; } }
        public bool AllowAuto { get { return bAuto; } }

        public string ID { get { return id; } }
        public string Name { get { return name; } }
        public ICatalogVariable Variable { 
            get { return var; }
            set {
                if (var != value) {
                    UnsetProxyHandlers(var);
                    var = value;
                    SetProxyHandlers(var);
                    if (VariableModelChanged != null) {
                        VariableModelChanged(new CatalogVarCollectionElementEventArgs(this));
                    }
                }
            }
        }

        #region internal event handler management
        protected void SetProxyHandlers(ICatalogVariable var) {
            var.ValueChanged += VariableCurrentChangedProxy;
            var.OptionChanged += VariableOptionChangedProxy;
        }

        protected void UnsetProxyHandlers(ICatalogVariable var) {
            if (var != null) {
                var.ValueChanged -= VariableCurrentChangedProxy;
                var.OptionChanged -= VariableOptionChangedProxy;
            }
        }

        protected void VariableOptionChangedProxy(CatalogVariableEventArgs arg) {
            if (VariableOptionChanged != null) {
                VariableOptionChanged(new CatalogVarCollectionElementEventArgs(this, arg));
            }
        }

        protected void VariableCurrentChangedProxy(CatalogVariableEventArgs arg) {
            if (VariableCurrentChanged != null) {
                VariableCurrentChanged(new CatalogVarCollectionElementEventArgs(this, arg));
            }
        }
        #endregion

        public IList<string> InfluenceIDs { get { return influences; } }

        public event CatalogVarCollectionElementEventHandler VariableModelChanged;
        public event CatalogVarCollectionElementEventHandler VariableCurrentChanged;
        public event CatalogVarCollectionElementEventHandler VariableOptionChanged;
    }
    public class CatalogVarCollectionElementEventArgs : EventArgs {
        public readonly CatalogVarCollectionElement Source;
        public readonly CatalogVariableEventArgs OriginalEvent;
        public CatalogVarCollectionElementEventArgs(CatalogVarCollectionElement src, CatalogVariableEventArgs args) {
            this.Source = src;
            this.OriginalEvent = args;
        }
        public CatalogVarCollectionElementEventArgs(CatalogVarCollectionElement src) : this(src,null) {}
    }
}
