using System;
using System.Collections;
using System.Collections.Generic;
using RothenburgAR.Common;
using UnityEngine;

namespace RothenburgAR.UI
{
    public enum ViewName
    {
        ARView,
        SettingsView,
        TutorialView,
        CreditsView,
        LanguageSelectView,
        ColorSelectView,
        FontsizeSelectView,
        FullscreenModelView,
        UpdaterView
    }

    public class UIManager : Singleton<UIManager>
    {
        private ARViewBehaviour _ARViewBehaviour;
        public Camera UICamera;
        public Camera UIObjectCamera;

        public Boolean IsARViewVisible
        {
            get { return _currentView != null && _currentView.ViewName == ViewName.ARView; }
        }

        public ARViewBehaviour ARViewBehaviour
        {
            get
            {
                if (_currentView.ViewName != ViewName.ARView)
                {
                    Debug.Log("ARView is not currently active, access is not allowed. Returning null.");
                    return null;
                }
                if (_ARViewBehaviour == null)
                {
                    GameObject[] x = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
                    foreach (var go in x)
                    {
                        if (go.name == "ARView(Clone)")
                        {
                            _ARViewBehaviour = go.GetComponent<ARViewBehaviour>();
                        }
                    }
                }
                return _ARViewBehaviour;
            }
        }

        private Dictionary<ViewName, View> _availableViews;

        private View _currentView;
        private GameObject _currentViewInstance;

        public bool StartingUp { get; set; }

        public UIManager()
        {
            _availableViews = new Dictionary<ViewName, View>();
        }

        internal void Initialize()
        {
            _availableViews.Add(ViewName.ARView,
                new View()
                {
                    ViewName = ViewName.ARView,
                    PrefabName = "UI/ARView",
                    OnExit = () => ARViewBehaviour.HidePoiDetails(),
                });

            _availableViews.Add(ViewName.SettingsView,
                new View()
                {
                    ViewName = ViewName.SettingsView,
                    PrefabName = "UI/SettingsView"
                });

            _availableViews.Add(ViewName.TutorialView,
                new View()
                {
                    ViewName = ViewName.TutorialView,
                    PrefabName = "UI/TutorialView"
                });

            _availableViews.Add(ViewName.CreditsView,
                new View()
                {
                    ViewName = ViewName.CreditsView,
                    PrefabName = "UI/CreditsView"
                });

            _availableViews.Add(ViewName.LanguageSelectView,
                new View()
                {
                    ViewName = ViewName.LanguageSelectView,
                    PrefabName = "UI/LanguageSelectView"
                });

            _availableViews.Add(ViewName.ColorSelectView,
                new View()
                {
                    ViewName = ViewName.ColorSelectView,
                    PrefabName = "UI/ColorSelectView"
                });

            _availableViews.Add(ViewName.FontsizeSelectView,
                new View()
                {
                    ViewName = ViewName.FontsizeSelectView,
                    PrefabName = "UI/FontsizeSelectView"
                });

            _availableViews.Add(ViewName.FullscreenModelView,
                new View()
                {
                    ViewName = ViewName.FullscreenModelView,
                    PrefabName = "UI/FullscreenModelView"
                });

            _availableViews.Add(ViewName.UpdaterView,
                new View()
                {
                    ViewName = ViewName.UpdaterView,
                    PrefabName = "UI/UpdaterView"
                });
        }

        public IEnumerator InitStartView()
        {
            yield return new WaitUntil(() => SettingsManager.Instance.IsInitialized.HasValue);
            if (SettingsManager.Instance.IsInitialized.Value == true)
            {
                StartingUp = false;
                SwitchToView(ViewName.ARView);
            }
            else
            {
                StartingUp = true;
                SwitchToView(ViewName.LanguageSelectView);
            }
        }

        public GameObject SwitchToView(ViewName nextViewName)
        {
            if (_currentView != null && _currentView.ViewName == nextViewName)
            {
                Debug.Log("Tried to switch to view '" + nextViewName + "', but it is already loaded.");
                return null;
            }

            View nextView;
            if (!_availableViews.TryGetValue(nextViewName, out nextView))
            {
                Debug.Log("Tried to switch to view '" + nextViewName + "', but it was not found.");
                return null;
            }

            if (_currentView != null)
            {
                Debug.Log("Switching from view '" + _currentView.ViewName + "' to '" +
                          nextViewName + "'");
            }
            else
            {
                Debug.Log("Switching to view '" + nextViewName + "'");
            }

            if (_currentView != null && _currentView.OnExit != null)
            {
                _currentView.OnExit();
            }

            if (_currentViewInstance != null)
            {
                Destroy(_currentViewInstance);
            }


            _currentView = nextView;
            GameObject prefab = Resources.Load<GameObject>(nextView.PrefabName);
            if (prefab != null)
            {
                _currentViewInstance = Instantiate(prefab);

                Canvas c = _currentViewInstance.GetComponentInChildren<Canvas>();
                if (c != null)
                {
                    c.worldCamera = UICamera;
                    c.renderMode = RenderMode.ScreenSpaceCamera;
                    c.planeDistance = 0.5f;
                }
            }
            // Set the StartingUp value
            if (StartingUp && nextViewName == ViewName.ARView)
            {
                StartingUp = false;
            }

            if (nextView.OnEnter != null)
            {
                nextView.OnEnter();
            }

            return _currentViewInstance;
        }

        void Update()
        {
            if (_currentView != null && _currentView.OnUpdate != null)
            {
                _currentView.OnUpdate();
            }
        }
    }
}