using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MikuMikuDance.XNA.Motion;
using System.Diagnostics;
using Microsoft.Xna.Framework;

namespace MikuMikuDance.XNA.Stages
{
    class CameraMotionTrack
    {
        public MMDStageMotion motion;
        Stopwatch timer = new Stopwatch();
        decimal frame = 0;
        decimal beforeMS = 0;
        decimal LossTime = 0;
        bool isEmpty = true;
        bool isLoopPlay;

        public bool IsEmpty { get { return isEmpty; } set { isEmpty = value; } }
        public bool IsLoopPlay { get { return isLoopPlay; } set { isLoopPlay = value; } }
        public void Clear() { motion = null; timer.Reset(); isLoopPlay = false; isEmpty = true; }
        public decimal NowFrame { get; set; }
        public long MaxFrame { get { return motion.MaxFrame; } }

        public void Stop()
        {
            if (!timer.IsRunning)
                return;
            timer.Stop();
            LossTime = (decimal)timer.Elapsed.TotalMilliseconds - beforeMS;//ロスタイムを計測
        }

        public void Start()
        {
            if (timer.IsRunning)
                return;
            timer.Start();
            beforeMS = (decimal)timer.Elapsed.TotalMilliseconds - LossTime;
        }
        public void Reset()
        {
            timer.Reset();
            beforeMS = 0;
            LossTime = 0;
            frame = 0;
            NowFrame = 0;
        }
        public bool IsPlay
        {
            get
            {
                return timer.IsRunning;
            }
        }
        public void UpdateFrame(decimal FramePerSecond)
        {
            //現在時刻の取得
            decimal nowMS = (decimal)timer.Elapsed.TotalMilliseconds;
            //前回コール時からの経過フレーム数を取得
            decimal dframe = (nowMS - beforeMS) * FramePerSecond / 1000.0m;
            //フレーム数の更新
            frame += dframe;
            beforeMS = nowMS;

            if (frame > motion.MaxFrame && !isLoopPlay)
            {
                Stop();
                NowFrame = (decimal)motion.MaxFrame;
            }
            NowFrame = frame % (decimal)(motion.MaxFrame + 1);
        }

        public void ApplyMotion(IMMDCamera mmdCamera)
        {
            float Length, ViewAngle;
            Vector3 Locate ;
            Quaternion Rotate;
            //モーションデータを計算
            motion.GetCameraData(NowFrame, out Length, out Locate, out Rotate, out ViewAngle);
            //カメラ位置を計算
            Vector3 CameraPos = new Vector3(0, 0, -1) * Length;
            CameraPos = Vector3.Transform(CameraPos, Rotate) + Locate;
            mmdCamera.CameraPos = CameraPos;
            //ターゲット位置を計算
            mmdCamera.CameraTarget = Locate;
            //Upvectorを計算
            mmdCamera.CameraUpVector = Vector3.Transform(Vector3.Up, Rotate);
            //viewAngleを適応
            mmdCamera.FieldOfView = ViewAngle;
        }
    }
}
