﻿//----------------------------------------------------------------------------------
// GVRNavi | Garpix Virtual Reality Navigation
// Copyright (c) 2017 Garpix Ltd.
//
// Plugin Homepage: https://gvrnavi.garpix.com
// Author Homepage: https://garpix.com
// Support: support@garpix.com
// License: Asset Store Terms of Service and EULA
// License URI: See LICENSE file in the project root for full license information.
//----------------------------------------------------------------------------------

using UnityEngine;
using UnityEngine.UI;

namespace GVRNavi
{
    [RequireComponent(typeof(BoxCollider))]
    public class VRToggleGaze : VRObjectGaze, IVRColored
    {
        #region variables

        public VRObjectBoolEvent OnValueChanged;

        public Image imageRendererBackground, imageRendererForeground;
        public SpriteRenderer spriteRendererBackground, spriteRendererForeground;
        public Color colorUnchecked = Color.white, colorHoveredUnchecked = Color.white,
            colorHoveredChecked = Color.white, colorChecked = Color.white, colorForeground = Color.white;

        public bool Checked
        {
            get { return _state == VRToggleState.Checked || _state == VRToggleState.HoveredChecked; }
            set
            {
                switch(_state)
                {
                    case VRToggleState.Normal:
                        if (value)
                            state = VRToggleState.Checked;
                        break;
                    case VRToggleState.HoveredUnchecked:
                        if (value)
                            state = VRToggleState.HoveredChecked;
                        break;
                    case VRToggleState.HoveredChecked:
                        if (!value)
                            state = VRToggleState.HoveredUnchecked;
                        break;
                    case VRToggleState.Checked:
                        if (!value)
                            state = VRToggleState.Normal;
                        break;
                }
            }
        }
        protected bool Hovered
        {
            get { return _state == VRToggleState.HoveredChecked || _state == VRToggleState.HoveredUnchecked; }
            set
            {
                switch (_state)
                {
                    case VRToggleState.Normal:
                        if (value)
                            state = VRToggleState.HoveredUnchecked;
                        break;
                    case VRToggleState.HoveredUnchecked:
                        if (!value)
                            state = VRToggleState.Normal;
                        break;
                    case VRToggleState.HoveredChecked:
                        if (!value)
                            state = VRToggleState.Checked;
                        break;
                    case VRToggleState.Checked:
                        if (value)
                            state = VRToggleState.HoveredChecked;
                        break;
                }
            }
        }
        protected VRToggleState state
        {
            get { return _state; }
            set
            {
                if (_state != value)
                {
                    _state = value;
                    UpdateColor();
                }
            }
        }
        public VRTweenColor tweenColor
        {
            get
            {
                if (_tweenColor == null)
                {
                    _tweenColor = gameObject.GetComponent<VRTweenColor>();
                    if (_tweenColor == null)
                        _tweenColor = gameObject.AddComponent<VRTweenColor>();
                }
                return _tweenColor;
            }
        }

        [SerializeField]
        protected VRSpriteType _spriteType;
        protected VRToggleState _state;
        protected VRTweenColor _tweenColor;
        protected float _globalAlpha = 1f;
        private bool _changed = false;

        #endregion


        #region IGvrGazeResponder

        public override void OnGazeEnter()
        {
            base.OnGazeEnter();
            Hovered = true;
        }

        public override void OnGazeExit()
        {
            base.OnGazeExit();
            _changed = false;
            Hovered = false;
        }

        public override void OnGazeTrigger()
        {
            base.OnGazeTrigger();
            _changed = true;
            Checked = !Checked;
            if (OnValueChanged != null)
                OnValueChanged.Invoke(this, Checked);
        }

        #endregion IGvrGazeResponder

        #region IVRColored

        public void SetGlobalAlpha(float alpha)
        {
            _globalAlpha = alpha;
            UpdateColor();
        }

        #endregion IVRColored

        public virtual void UpdateColor()
        {
            SetBackgroundColor(Checked ? (Hovered && !_changed ? colorHoveredChecked : colorChecked) :
                    Hovered && !_changed ? colorHoveredUnchecked : colorUnchecked);
            SetForegroundColor(Checked ? colorForeground : new Color(colorForeground.r, colorForeground.g, colorForeground.b, 0f));
        }

        public virtual void SetBackgroundColor(Color color)
        {
            color.a *= _globalAlpha;
            SetColliderEnable(color.a > 0f);
            SetColor(imageRendererBackground, color);
            SetColor(spriteRendererBackground, color);
        }

        public virtual void SetForegroundColor(Color color)
        {
            color.a *= _globalAlpha;
            SetColor(imageRendererForeground, color);
            SetColor(spriteRendererForeground, color);
        }

        protected virtual void SetColor(SpriteRenderer spriteRenderer, Color color)
        {
            if (spriteRenderer == null)
                return;
            if (Application.isPlaying)
                tweenColor.StartColoring(spriteRenderer.color, color, 0.2f, spriteRenderer);
            else
                spriteRenderer.color = color;
        }

        protected virtual void SetColor(Image image, Color color)
        {
            if (image == null)
                return;
            if (Application.isPlaying)
                tweenColor.StartColoring(image.color, color, 0.2f, image);
            else
                image.color = color;
        }
    }
}