using RothenburgAR.Common;
using System.Collections;
using System.IO;
using System.Threading;
using UnityEngine;

namespace RothenburgAR.PointOfInterest
{
    public class PoiData
    {
        public string ID { get; set; }
        public string SourcePath { get; set; }
        public TextElement Description { get; set; }
        // Currently not used, but maybe relevant for future projects
        public TextElement Title { get; set; }
        // The cached model prefab
        private GameObject _modelPrefab;

        // Path to the model. Null if not set.
        public PoiModelDescription ModelDescription { get; set; }

        public bool HasModelDescription
        {
            get { return ModelDescription.ModelPath != null; }
        }

        public bool IsModelLoaded
        {
            get
            {
                return _modelPrefab != null;
            }
        }

        public bool ModelLoadFailed { get; private set; }

        public IEnumerator LoadModel()
        {
            ModelLoadFailed = false;
            if (!File.Exists(ModelDescription.ModelPath))
            {
                Debug.LogError(ModelDescription.ModelPath + " does not exist;");
                ModelLoadFailed = true;
                yield break;
            }

            var loader = new OBJLoader(ModelDescription.ModelPath);

            ThreadStart start = new ThreadStart(loader.ParseObjFile);
            Thread t = new Thread(start);
            t.Start();

            yield return new WaitUntil(() => t.ThreadState == ThreadState.Stopped);

            try
            {
                var model = loader.BuildUnityObjects();

                model.SetActive(false);
                _modelPrefab = model;
            }
            catch (System.Exception)
            {
                ModelLoadFailed = true;
                yield break;
            }
        }

        public GameObject GetModelPrefab()
        {
            if (!HasModelDescription)
                return null;
            if (_modelPrefab != null)
                return _modelPrefab;

            LoadModel();
            return _modelPrefab;
        }

        public GameObject InstantiateModelPrefab()
        {
            if (!HasModelDescription)
                return null;
            var modelPrefab = GetModelPrefab();
            var gameObject = GameObject.Instantiate(modelPrefab);

            gameObject.SetActive(true);
            gameObject.transform.localRotation = Quaternion.identity;
            gameObject.transform.localScale = ModelDescription.Scale;

            var modelGO = gameObject.transform.GetChild(0);
            modelGO.transform.eulerAngles = ModelDescription.Rotation;
            modelGO.gameObject.layer = LayerMask.NameToLayer("UIModel");

            return gameObject;
        }
    }
}