using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Thousandto.Core.Base;

public class MoveCameraByPath : MonoBehaviour {
    // 内部变量
    Vector3 m_startPos = Vector3.zero;
    Quaternion m_startQuatern = Quaternion.identity;
    Vector3 m_lastPos = Vector3.zero;
    Vector3 m_curPos = Vector3.zero;
    float m_startTime = 0.0f;
    float m_viewTime = 20.0f;
    bool m_showGUI = true;
    bool m_start = false;
    private bool adjustViewDirAuto = true;
    private int m_curIndex = 0;
    private iTweenPathEX m_curmovePath;
    private iTweenPathEX m_curviewPath;

    // 外部变量
    public List<iTweenPathEX> movePaths = new List<iTweenPathEX>();
    public List<iTweenPathEX> viewPaths = new List<iTweenPathEX>();

    // Use this for initialization
    void Start() {
        m_startPos = transform.position;
        m_startQuatern = transform.rotation;
        m_showGUI = true;
    }

    // Update is called once per frame
    void Update() {
        if ( m_start ) {
            m_curPos = transform.position;

            if ( adjustViewDirAuto ) {
                if ( m_curPos != m_lastPos ) {
                    UpdateDirection( m_curPos - m_lastPos );
                }
            } else {
                // 使用两个曲线描述观察者相机
                if ( m_curviewPath != null ) {
                    transform.LookAt( m_curviewPath.gameObject.transform );
                }
            }

            m_lastPos = m_curPos;

            if ( !m_showGUI ) {
                if ( Time.time - m_startTime > m_viewTime ) {
                    if ( movePaths.Count > m_curIndex ) {
                        m_showGUI = false;
                        iTween.Stop();
                        StartCoroutine(
                            WaitFrameToDo(
                                1,
                                ( _str ) => {
                                    if ( GetCurrentCurve( out m_curmovePath, out m_curviewPath ) ) {
                                        InitRunTime();
                                        RunViewCam( m_curmovePath, m_curviewPath );
                                    } else {
                                        Debug.LogError( "没有设置相机移动曲线" );
                                        m_showGUI = true;
                                        StopViewCam();
                                    }
                                }
                            )
                        );
                    } else {
                        m_showGUI = true;
                        StopViewCam();
                    }

                }
            }
        }
    }

    void OnGUI() {
        if ( m_showGUI ) {
            if ( GUI.Button( new Rect( 10, 10, 150, 80 ), "Run Camera" ) ) {
                if ( GetCurrentCurve( out m_curmovePath, out m_curviewPath ) ) {
                    InitRunTime();
                    RunViewCam( m_curmovePath, m_curviewPath );
                    m_showGUI = false;
                } else {
                    Debug.LogError( "没有设置相机移动曲线" );
                }
            }
        }

    }

    #region 主要功能
    public void InitRunTime() {
        if ( m_curmovePath != null ) {
            m_viewTime = m_curmovePath.totalePlayTime;
            if ( m_curviewPath != null ) {
                m_viewTime = Mathf.Max( m_curmovePath.totalePlayTime, m_curviewPath.totalePlayTime );
            }
        }
    }
    public void InitCurve( iTweenPathEX tagPath ) {
        if ( tagPath == null ) {
            return;
        }
        if ( !iTweenPath.paths.ContainsKey( tagPath.pathName ) ) {
            iTweenPath.paths.Add( tagPath.pathName.ToLower(), tagPath );
        }

    }
    // 使用曲线开始移动相机以及调整视线
    public void RunViewCam( iTweenPathEX movePath, iTweenPathEX viewPath ) {
        InitCurve( movePath );
        InitCurve( viewPath );

        iTweenPathEX pathComponent = movePath;
        if ( pathComponent != null ) {
            var path = iTweenPath.GetPath( pathComponent.pathName );
            if ( path != null ) {
                transform.position = path[0];
                m_curPos = transform.position;
                m_lastPos = m_curPos;
                iTween.MoveTo( gameObject, iTween.Hash(
                    "position", transform,
                    "path", path,
                    "time", pathComponent.totalePlayTime,
                    "easetype", "linear" ) );

                // settings 
                m_showGUI = false;
            }

        }

        iTweenPathEX viewComponent = viewPath;
        if ( viewComponent != null ) {
            var path = iTweenPath.GetPath( viewComponent.pathName );
            if ( path != null ) {
                viewComponent.gameObject.transform.position = path[0];
                iTween.MoveTo( viewComponent.gameObject, iTween.Hash(
                    "path", path,
                    "time", viewComponent.totalePlayTime,
                    "easetype", "linear" ) );
            }

        }

        m_startTime = Time.time;
        m_start = true;

        //Debug.LogWarning( "Start Curve : " + pathComponent.name + " Time : " + m_startTime.ToString() );
    }
    // 停止播放, 返回最初位置
    public void StopViewCam() {
        iTween.Stop();
        iTweenPath.paths.Clear();
        m_start = false;
        m_curIndex = 0;
        transform.position = m_startPos;
        transform.rotation = m_startQuatern;

    }
    #endregion

    #region Help Funcs
    // 自动转动镜头
    void UpdateDirection( Vector3 dir ) {
        transform.rotation = Quaternion.LookRotation( dir );
    }
    // 获取下一个相机曲线
    bool GetCurrentCurve( out iTweenPathEX movePath, out iTweenPathEX viewPath ) {
        movePath = movePaths[m_curIndex];
        viewPath = viewPaths[m_curIndex];
        if ( movePath != null ) {
            // 当使用自动调整时不需要视线曲线
            adjustViewDirAuto = movePath.adjustViewDirAuto;

            if ( adjustViewDirAuto || viewPath != null ) {
                m_curIndex++;
                return true;
            }
        }
        return false;
    }
    // 等待曲线END -- 在同一帧内的顶点会自动合并为曲线顶点
    IEnumerator WaitFrameToDo(int frames = 1, MyAction<string> func = null)
    {
        for ( int i = 0; i < frames; i++ ) {
            yield return new WaitForEndOfFrame();
        }
        if ( func != null ) {
            func( "test" );
        }
    }
    #endregion

}