using System;
using System.Collections.Generic;
using System.Text;
using Kyojin.Model;
using Yamalib.Util;
using Yanesdk.Draw;
using Yanesdk.System;
using Yamalib;
using System.Diagnostics;
using Yamalib.Yanesdkext.Draw;

namespace Kyojin.Scene.EyeCatche
{

    /// <summary>
    /// 去人たちメインパートでシナリオ選択後のアイキャッチタスク
    /// TeopScenePramに遷移先シナリオ番号を指定すること
    /// </summary>
    class SelectorEyeCatcheScene : TaskBase, IDisposable
    {
        #region 定数値

        /// 下の DEF_FILES とあわせる（昔のための互換性）
        private enum SHI_TYPE : int
        {
            STD = 0,
            TOMIE01,
            ALICE01,
            ANZAI01,
            RUBI01,
            MIDO01,
            YUIRI01,
            AYA01,
        };

        /// 処理タイプ	
        private enum PROCESS_TYPE
        {
            CHENGE_BG,
            FADE_IN,
            SLIDE,
            FADE_OUT
        };

        private const int TITLE_X = 25;
        private const int TITLE_Y = 247;
        private const int VARTICAL_BAR_X = 8;
        private const int HORIZONAL_BAR_Y = 232;
        private const int WAIT_TIME = 60;

        #endregion

        #region メンバフィールド

        private readonly GameSystem m_gSys;
        private bool init;
        private ITexture m_imgBackup;
        private ITexture m_imgBg;
        private ITexture m_imgTitle;
        private ITexture m_imgHorizonalBar;
        private ITexture m_imgVarticallBar;
        private ITexture m_imgBottomFrame;
        private ITexture m_imgUpperFrame;

        private int m_waitCount;

        private readonly RootCounterS m_phase = new RootCounterS();
        private readonly ICounter m_offsetCounter = new RootCounterS();
        private PROCESS_TYPE m_processType;

        #endregion

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="gameSystem"></param>
        public SelectorEyeCatcheScene(GameSystem gameSystem)
        {
            m_gSys = gameSystem;
        }

        #region IDisposable メンバ

        public void Dispose()
        {
            YamalibUtility.Dispose(m_imgBackup);
            YamalibUtility.Dispose(m_imgBg);
            YamalibUtility.Dispose(m_imgTitle);
            YamalibUtility.Dispose(m_imgHorizonalBar);
            YamalibUtility.Dispose(m_imgVarticallBar);
            YamalibUtility.Dispose(m_imgBottomFrame);
            YamalibUtility.Dispose(m_imgUpperFrame);
        }

        #endregion

        public override int Task(object o)
        {
            GameSystem gameSystem = (GameSystem)o;
            if (0 == OnMove(gameSystem))
            {
                return 0;
            }
            gameSystem.OnMoveCommon();
            if (!gameSystem.FpsTimer.ToBeSkip)
            {
                gameSystem.Screen.Select();
                OnPaint(gameSystem);
                gameSystem.OnDrawCommon();
                gameSystem.Screen.Update();
            }
            else
            {
                OnPaint(gameSystem);
                gameSystem.OnDrawCommon();
            }
            return 1;
        }

        /// <summary>
        /// 動作処理
        /// </summary>
        /// <param name="gameSystem"></param>
        private int OnMove(GameSystem gameSystem)
        {
            if (!init)
            {
                OnInit();
                m_gSys.Screen.BlendSrcAlpha();
                m_imgBackup = m_gSys.TelopParam.ScreenImg;
                init = true;
            }

            switch (m_processType)
            {
                case PROCESS_TYPE.CHENGE_BG:
                    m_phase++;
                    if (m_phase.IsEnd)
                    {
                        m_phase.Set(0, 255, 2);
                        m_processType = PROCESS_TYPE.FADE_IN;
                    }
                    break;
                case PROCESS_TYPE.FADE_IN:
                    m_phase++;
                    // ある程度はからはスライドを並行させる
                    if (m_phase.Value() > 32)
                    {
                        m_processType = PROCESS_TYPE.SLIDE;
                        //Log.print("STEP : PROCESS_TYPE.SLIDE");
                    }
                    break;
                case PROCESS_TYPE.SLIDE:
                    m_offsetCounter.Inc();
                    m_phase.Inc();

                    if (m_offsetCounter.IsEnd && m_phase.IsEnd)
                    {
                        m_phase.Set(255, 0, 2);
                        m_processType = PROCESS_TYPE.FADE_OUT;
                        //Log.print("STEP : PROCESS_TYPE.FADE_OUT");
                    }
                    break;
                case PROCESS_TYPE.FADE_OUT:
                    if (m_waitCount >= WAIT_TIME)
                    {
                        m_phase++;
                    }
                    else
                    {
                        ++m_waitCount;
                    }
                    if (m_phase.IsEnd)
                    {
                        jumpScenario();
                        return 0;
                    }
                    break;
                default:
                    Debug.Assert(false);
                    break;
            }
            return 1;
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="gameSystem"></param>
        private void OnPaint(GameSystem gameSystem)
        {
            m_gSys.Screen.Clear();
            m_gSys.Screen.SetColor(255, 255, 255, 255);

            switch (m_processType)
            {
                case PROCESS_TYPE.CHENGE_BG:
                    // バックアップしたテクスチャは反転している
                    m_gSys.Screen.Blt(m_imgBackup, 0, 0, new Rect(0, 480, 640, 0), null);

                    // 現在画像上書き
                    TransBltter.Blt(
                        22,
                        m_gSys.Screen,
                        m_imgBg,
                        0, 0,
                        m_phase.Value()
                    );
                    break;
                case PROCESS_TYPE.FADE_IN:
                    m_gSys.Screen.Blt(m_imgBg, 0, 0);

                    // 上
                    TransBltter.Blt(
                        22,
                        m_gSys.Screen,
                        m_imgUpperFrame,
                        0, 0,
                        m_phase.Value()
                    );
                    // 下
                    TransBltter.Blt(
                        23,
                        m_gSys.Screen,
                        m_imgBottomFrame,
                        0, 480 - (int)m_imgBottomFrame.Height,
                        m_phase.Value()
                    );

                    // フェードイン
                    m_gSys.Screen.SetColor(255, 255, 255, m_phase.Value());
                    m_gSys.Screen.Blt(m_imgTitle, TITLE_X, TITLE_Y);
                    break;
                case PROCESS_TYPE.SLIDE:
                    m_gSys.Screen.Blt(m_imgBg, 0, 0);

                    // 上
                    TransBltter.Blt(
                        22,
                        m_gSys.Screen,
                        m_imgUpperFrame,
                        0, 0,
                        m_phase.Value()
                    );
                    // 下
                    TransBltter.Blt(
                        23,
                        m_gSys.Screen,
                        m_imgBottomFrame,
                        0, 480 - (int)m_imgBottomFrame.Height,
                        m_phase.Value()
                    );
                    m_gSys.Screen.SetColor(255, 255, 255, m_phase.Value());
                    m_gSys.Screen.Blt(m_imgTitle, TITLE_X, TITLE_Y);
                    m_gSys.Screen.SetColor(255, 255, 255, 255);
                    m_gSys.Screen.Blt(m_imgHorizonalBar,
                        m_offsetCounter.Value() - (int)m_imgHorizonalBar.Width,
                        HORIZONAL_BAR_Y);

                    m_gSys.Screen.Blt(m_imgVarticallBar,
                        VARTICAL_BAR_X,
                        (480 - (int)m_imgVarticallBar.Height)
                        + ((int)m_imgVarticallBar.Height - m_offsetCounter.Value()));

                    break;

                case PROCESS_TYPE.FADE_OUT:
                    m_gSys.Screen.SetColor(255, 255, 255, m_phase.Value());
                    m_gSys.Screen.Blt(m_imgBg, 0, 0);
                    m_gSys.Screen.Blt(m_imgUpperFrame, 0, 0);
                    m_gSys.Screen.Blt(m_imgBottomFrame, 0, 480 - (int)m_imgBottomFrame.Height);
                    m_gSys.Screen.Blt(m_imgTitle, TITLE_X, TITLE_Y);
                    m_gSys.Screen.Blt(m_imgHorizonalBar, 0, HORIZONAL_BAR_Y);
                    m_gSys.Screen.Blt(m_imgVarticallBar, VARTICAL_BAR_X,
                        480 - (int)m_imgVarticallBar.Height);
                    break;
                default:
                    Debug.Assert(false);
                    break;
            }

            m_gSys.Screen.SetColor(255, 255, 255, 255);
        }

        /// <summary>
        /// 初期化処理
        /// </summary>
        private void OnInit()
        {
            // テクスチャのロード
            loadTexture();

            int frameSize = (int)m_imgHorizonalBar.Width;
            // アルファ
            m_phase.Set(0, 255, 4);

            // スライド用
            m_offsetCounter.Set(0, frameSize, 10);

            m_processType = PROCESS_TYPE.CHENGE_BG;
        }


        /// テクスチャのロード
        private void loadTexture()
        {
            m_imgBg = YamalibConst.CreateTexture("img/eyecatch/ec_bg_dammy.png");
            m_imgTitle = YamalibConst.CreateTexture("img/eyecatch/ec_t.png");
            m_imgHorizonalBar = YamalibConst.CreateTexture("img/eyecatch/ec_line.png");
            m_imgVarticallBar = YamalibConst.CreateTexture("img/eyecatch/ec_line_v.png");
            m_imgBottomFrame = YamalibConst.CreateTexture("img/eyecatch/ec bar_2.png");
            m_imgUpperFrame = YamalibConst.CreateTexture("img/eyecatch/ec bar_1.png");
        }

        /// シナリオタスクに遷移する
        private void jumpScenario()
        {
            // シナリオタスクへのパラメータ作成
            m_gSys.ScenarioSceneParam.IsReadTop = true;
            //if (m_gSys.ScenarioSceneParam.ScenarioInfo == null)
            {
                m_gSys.ScenarioSceneParam.ScenarioInfo = new ScenarioInfo();
            }
            m_gSys.ScenarioSceneParam.ScenarioInfo.ScenarioID = m_gSys.EyeCatcheSceneParam.CallScenarioNo;


            // すべてのスタックを破棄		
            m_gSys.SceneController.ExitScene();

            // 強制バックアップを行う
            m_gSys.SceneController.CallScene(Scenes.Scenario);
        }

    }
}
