﻿using System.Collections;
using UnityEngine;
using UnityEngine.Video;
using RememorySDK.API;
using System.IO;

namespace RememorySDK
{
    [RequireComponent(typeof(DepthPlayer))]
    public class RememoryPlayer : VolumetricPlayer
    {
        public override event OnCreatedDelegate OnCreated;
        public string captureDir;
        public MeshMode meshMode = RememorySDK.API.MeshMode.Medium;
        public bool isFollowCamera = true;
        protected VideoPlayer rem_videoPlayer;
        private DepthPlayer player;
        public override bool IsCreated
        {
            get
            {
                return player != null && player.IsPlayerSetup();
            }
        }



        public override float NearClip
        {
            set
            {
                if (!IsCreated)
                {
                    OnSetupError();
                    return;
                }

                player.NearClip = value;
            }
            get
            {
                return IsCreated ? player.NearClip : 0.0f;
            }
        }

        public override float FarClip
        {
            set
            {
                if (!IsCreated)
                {
                    OnSetupError();
                    return;
                }

                player.FarClip = value;
            }
            get
            {
                return IsCreated ? player.FarClip : 0.0f;
            }
        }

        public override bool IsAudioMute
        {
            set
            {
                if (!IsCreated)
                {
                    OnSetupError();
                    return;
                }

                player.IsAudioMute = value;
            }
            get
            {
                return IsCreated ? player.IsAudioMute : false;
            }
        }

        public override float Speed
        {
            set
            {
                if (!IsCreated)
                {
                    OnSetupError();
                    return;
                }

                player.Speed = value;
            }
            get
            {
                return IsCreated ? player.Speed : 1.0f;
            }
        }

        public override bool IsLoop
        {
            set
            {
                if (!IsCreated)
                {
                    OnSetupError();
                    return;
                }

                player.IsLoop = value;
            }
            get
            {
                return IsCreated ? player.IsLoop : false;
            }
        }

        public override bool IsFollowCamera
        {
            set
            {
                if (IsCreated)
                {
                    isFollowCamera = value;
                    player.IsFollowCamera = value;
                }
                else
                {
                    isFollowCamera = value;
                }
            }
            get
            {
                return IsCreated ? player.IsFollowCamera : isFollowCamera;
            }
        }

        public override MeshMode MeshModeType
        {
            set
            {
                if (IsCreated)
                {
                    meshMode = value;
                    player.MeshModeType = value;
                }
                else
                {
                    meshMode = value;
                }
            }
            get
            {
                return IsCreated ? player.MeshModeType : meshMode;
            }
        }

        public override void CreatePlayer()
        {
            rem_videoPlayer = gameObject.GetComponent<VideoPlayer>();
            if (rem_videoPlayer == null)
            {
                rem_videoPlayer = gameObject.AddComponent<VideoPlayer>();
            }
            StartCoroutine(Create(meshMode, IsFollowCamera));
        }

        private IEnumerator Create(MeshMode meshMode = MeshMode.Medium, bool isFollowCamera = true)
        {
            var isAndroid = Application.platform == RuntimePlatform.Android;

            if (isAndroid)
            {
                yield return StartCoroutine(SetupAndroid.Init(captureDir));
            }

            player = gameObject.GetComponent<DepthPlayer>();

            var captureDirPath = Path.Combine((isAndroid ? Application.persistentDataPath : Application.streamingAssetsPath), captureDir);

            yield return player.Setup(captureDirPath, meshMode, isFollowCamera);

            if (OnCreated != null)
            {
                OnCreated();
            }
        }

        private void OnVideoPlayerError()
        {
            Debug.LogWarning("Rememory SDK Error : VideoPlayer is null. This Function must be done after VideoPlayer setup is complete.");
        }

        private void OnSetupError()
        {
            Debug.LogWarning("Rememory SDK Error : Setup has not completed. This Function must be done after IsCreated is complete.");
        }

        public override void Play()
        {
            if (!IsCreated)
            {
                OnSetupError();
                return;
            }
            player.Play();
        }

        public override void Pause()
        {
            if (!IsCreated)
            {
                OnSetupError();
                return;
            }
            player.Pause();
        }

        public override void Stop()
        {
            if (!IsCreated)
            {
                OnSetupError();
                return;
            }
            player.StopPlaying();
        }

        public override bool IsPlaying()
        {
            if (rem_videoPlayer == null)
            {
                OnVideoPlayerError();
                return false;
            }
            return rem_videoPlayer.isPlaying;
        }

        public override int GetCurrentFrame()
        {
            if (rem_videoPlayer == null)
            {
                OnVideoPlayerError();
                return 0;
            }
            return (int)rem_videoPlayer.frame;
        }

        public override double GetCurrentTime()
        {
            if (rem_videoPlayer == null)
            {
                OnVideoPlayerError();
                return 0;
            }
            return rem_videoPlayer.time;
        }

        public override int GetTotalFrame()
        {
            if (!IsCreated)
            {
                OnSetupError();
                return 0;
            }
            return player.GetTotalFrame();
        }

        public override double GetDuration()
        {
            if (rem_videoPlayer == null)
            {
                OnVideoPlayerError();
                return 0;
            }
            return rem_videoPlayer.length;
        }

        public override void Seek(float toTimeSeconds)
        {
            if (!IsCreated)
            {
                OnSetupError();
                return;
            }
            player.Seek(toTimeSeconds);
        }

        public override uint GetVideoWidth()
        {
            if (rem_videoPlayer == null)
            {
                OnVideoPlayerError();
                return 0;
            }
            return rem_videoPlayer.width;
        }

        public override uint GetVideoHeight()
        {
            if (rem_videoPlayer == null)
            {
                OnVideoPlayerError();
                return 0;
            }
            return rem_videoPlayer.height;
        }
    }
}

