using System.Collections;
using System.Linq;
using UnityEngine;

[RequireComponent(typeof(DanMachiAssetLibrary), typeof(DanMachiModelBuilder), typeof(DanMachiModelViewerInterface))]
public class DanMachiModelViewerMain : ModelViewerMain
{
    public static DanMachiModelViewerMain Instance => GetInstance<DanMachiModelViewerMain>();

    protected DanMachiAssetLibrary _assets => DanMachiAssetLibrary.Instance;
    protected DanMachiModelBuilder _modelBuilder => DanMachiModelBuilder.Instance;

    protected override void Awake()
    {
        CurrentScene = SceneContainer.Create<DanMachiSceneContainer>(this);
        base.Awake();
    }

    private IEnumerator Start()
    {
        Application.targetFrameRate = 30;
        Error.Log(Color.green, "Viewer version: " + Application.version);

        float warningTimer = 0;
        while (DanMachiAssetLibrary.Instance == null || DanMachiModelBuilder.Instance == null || DanMachiModelViewerInterface.Instance == null || SharedResources.Instance == null)
        {
            warningTimer += Time.deltaTime;
            if(warningTimer > 2)
            {
                warningTimer = 0;
                string report = $"AssetLibrary: {DanMachiAssetLibrary.Instance != null}\nModelBuilder: {DanMachiModelBuilder.Instance != null}\nInterface: {DanMachiModelViewerInterface.Instance != null}\nResources: {SharedResources.Instance != null}";
                Error.Log(report, Color.red);
            }
            yield return 0;
        }
    }

    private void Update()
    {
        //AutoSaveUpdate();
    }

    public static void RegisterObject(DanMachiObjectContainer container)
    {
        Instance.CurrentScene.AllObjects.Add(container);
    }

    public static void UnregisterObject(DanMachiObjectContainer container)
    {
        Instance.CurrentScene.AllObjects.Remove(container);
    }

    public static void DisposeOf(GameObject go)
    {
        if (go == null) return;
        var rends = go.GetComponentsInChildren<Renderer>();
        foreach (var rend in rends)
        {
            for (int i = rend.materials.Length - 1; i >= 0; i--)
            {
                Destroy(rend.materials[i]);
            }
        }
        Destroy(go);
        UnityEngine.Resources.UnloadUnusedAssets();
        System.GC.Collect();
    }

    public IEnumerator LoadScene(DanMachiSceneSerializable bc)
    {
        EmptyScene<DanMachiSceneContainer>();

        foreach (var c in bc.Objects)
        {
            if (c.GUID == "cameraOrbit")
            {
                MainCameraOrbit.DeserializeFrames(c);
            }
            else
            {
                yield return _modelBuilder.SpawnSerialized(c);
            }
        }
        bc.Timeline.Deserialize(TimelineController.Instance);
        CurrentScene.Frames = bc.Frames.Select(f => new FrameContent(f)).ToList();
        yield return 0;
        TimelineController.SetCurrentFrame(TimelineController.Instance.CurrentFrame);
    }
}