using FairyGUI.Utils;
namespace FairyGUI
{
    /// 
    /// Gear is a connection between object and controller.
    /// 
    abstract public class GearBase
    {
        public static bool disableAllTweenEffect = false;
        protected GObject _owner;
        protected Controller _controller;
        protected GearTweenConfig _tweenConfig;
        public GearBase(GObject owner)
        {
            _owner = owner;
        }
        public void Dispose()
        {
            if (_tweenConfig != null && _tweenConfig._tweener != null)
            {
                _tweenConfig._tweener.Kill();
                _tweenConfig._tweener = null;
            }
        }
        /// 
        /// Controller object.
        /// 
        public Controller controller
        {
            get
            {
                return _controller;
            }
            set
            {
                if (value != _controller)
                {
                    _controller = value;
                    if (_controller != null)
                        Init();
                }
            }
        }
        public GearTweenConfig tweenConfig
        {
            get
            {
                if (_tweenConfig == null)
                    _tweenConfig = new GearTweenConfig();
                return _tweenConfig;
            }
        }
        public void Setup(ByteBuffer buffer)
        {
            _controller = _owner.parent.GetControllerAt(buffer.ReadShort());
            Init();
            int cnt = buffer.ReadShort();
            if (this is GearDisplay)
            {
                ((GearDisplay)this).pages = buffer.ReadSArray(cnt);
            }
            else if (this is GearDisplay2)
            {
                ((GearDisplay2)this).pages = buffer.ReadSArray(cnt);
            }
            else
            {
                for (int i = 0; i < cnt; i++)
                {
                    string page = buffer.ReadS();
                    if (page == null)
                        continue;
                    AddStatus(page, buffer);
                }
                if (buffer.ReadBool())
                    AddStatus(null, buffer);
            }
            if (buffer.ReadBool())
            {
                _tweenConfig = new GearTweenConfig();
                _tweenConfig.easeType = (EaseType)buffer.ReadByte();
                _tweenConfig.duration = buffer.ReadFloat();
                _tweenConfig.delay = buffer.ReadFloat();
            }
            if (buffer.version >= 2)
            {
                if (this is GearXY)
                {
                    if(buffer.ReadBool())
                    {
                        ((GearXY)this).positionsInPercent = true;
                        for (int i = 0; i < cnt; i++)
                        {
                            string page = buffer.ReadS();
                            if (page == null)
                                continue;
                            ((GearXY)this).AddExtStatus(page, buffer);
                        }
                        if (buffer.ReadBool())
                            ((GearXY)this).AddExtStatus(null, buffer);
                    }
                }
                else if (this is GearDisplay2)
                    ((GearDisplay2)this).condition = buffer.ReadByte();
            }
        }
        virtual public void UpdateFromRelations(float dx, float dy)
        {
        }
        abstract protected void AddStatus(string pageId, ByteBuffer buffer);
        abstract protected void Init();
        /// 
        /// Call when controller active page changed.
        /// 
        abstract public void Apply();
        /// 
        /// Call when object's properties changed.
        /// 
        abstract public void UpdateState();
    }
    public class GearTweenConfig
    {
        /// 
        /// Use tween to apply change.
        /// 
        public bool tween;
        /// 
        /// Ease type.
        /// 
        public EaseType easeType;
        /// 
        /// Tween duration in seconds.
        /// 
        public float duration;
        /// 
        /// Tween delay in seconds.
        /// 
        public float delay;
        internal uint _displayLockToken;
        internal GTweener _tweener;
        public GearTweenConfig()
        {
            tween = true;
            easeType = EaseType.QuadOut;
            duration = 0.3f;
            delay = 0;
        }
    }
}