using System;
using System.Collections.Generic;
using System.Text;
using Yanesdk.System;
using Kyojin.Model;
using Yanesdk.Math;
using Yamalib.Util;
using Yanesdk.Draw;
using Yanesdk.Timer;
using Yamalib.Draw;
using Yamalib;
using System.Diagnostics;
using Yamalib.Draw.Effect;
using Yanesdk.Sound;

namespace Kyojin.Scene.Ending
{

    /// <summary>
    /// 去人たちメインパートでシナリオ途中に挿入される
    /// テロップを処理するクラス
    /// 
    /// 使用するときは、TelopSceneParamにシナリオ番号を指定すること
    /// </summary>
    class MainEndingScene : TaskBase, IDisposable
    {
        /// <summary>
        /// 時間の範囲を表すデータクラス
        /// </summary>
        private class TimeRange
        {
            public TimeRange(FixTimer timer, int start, int end)
            {
                m_timer = timer;
                m_start = start;
                m_end = end;
            }

            /// 残り時間の取得
            public int GetRemainEndTime()
            {
                return m_end - Get();
            }

            /// 開始されまでの時間
            public int GetRemainStartTime()
            {
                return m_start - Get();
            }

            /// 時間の取得
            public int GetRange()
            {
                return m_end - m_start;
            }

            /// 時間の前
            public bool IsBefore()
            {
                return IsBefore(m_start);
            }

            /// 時間内
            public bool IsDuring()
            {
                return m_now >= m_start && m_now <= m_end;

            }

            /// 時間の後
            public bool IsAfter()
            {
                return IsAfter(m_end);
            }

            //-------- おまけ		
            public bool IsBefore(int time)
            {
                return Get() < time;
            }
            public bool IsAfter(int time)
            {
                return Get() >= time;
            }

            /// 現在時間の取得
            public int Get()
            {
                return m_now;
            }

            /// 更新
            public void Update()
            {
                this.m_timer.Update();
                m_now = m_timer.Time;
            }

            private readonly FixTimer m_timer;
            private int m_start;
            private int m_end;
            private int m_now;
        }

        /// <summary>
        /// シーンを表現する基底クラス
        /// </summary>
        private abstract class SceneBase
        {
            /// 移動処理
            public abstract int OnInit(IScreen screen);
            /// 移動処理
            public abstract int OnMove(IScreen screen);
            /// 描画処理
            public abstract int OnDraw(IScreen screen);
            /// 終了したか
            public bool IsFinish()
            {
                return this.m_finish;
            }

            /// オブジェクトを解放する
            public virtual void Destroy()
            {
            }

            /// 静的コンストラクタ
            static SceneBase()
            {
                RAND = new Rand();
            }

            /// コンストラクタ
            public SceneBase(FixTimer grobalTimer)
            {
                m_timer = grobalTimer;
                m_innerTimer = new FixTimer();
                m_innerTimer.Reset();
                m_finish = false;
            }

            /// シーン内タイマーをリセットする
            public void ResetSceneTimer()
            {
                m_innerTimer.Reset();
            }

            /// TextureLoader にリストされている画像をすべてキャッシュに読み込む
            public static void LoadCacheAll(TextureLoader tl, int elementNum)
            {
                // キャッシュに読み込んでおく
                for (int i = 0; i < elementNum; ++i)
                {
                    ITexture t = tl.GetTexture(i);
                }
            }

            /// ネガポジ変換で描画する 
            /** 
             * これは、完全に白の背景に、変換したい画像を、subColor で描画することで
             * 実現してある。
             * したがって、これは一度、真っ白にクリアする。
             * そしてその後に対象のテクスチャを描画する。
             */
            public static void DrawNegaPosi(IScreen screen, ITexture texture, int x, int y)
            {
                if (screen == null || texture == null)
                {
                    return;
                }

                Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                int w = screen.Width;
                int h = screen.Height;

                // 白で塗りつぶし
                screen.SetColor(255, 255, 255);
                screen.DrawPolygon(
                    0, 0,
                    w, 0,
                    w, h,
                    0, h
                );

                screen.BlendSubColor();
                screen.Blt(texture, x, y);
            }

            /// ネガポジ変換で描画する 
            /** 
             * これは、完全に白の背景に、変換したい画像を、subColor で描画することで
             * 実現してある。
             * したがって、これは一度、真っ白にクリアする。
             * そしてその後に対象のテクスチャを描画する。
             * (DrawAssist で描画するバージョン）
             */
            public static void DrawNegaPosi(IScreen screen, DrawAssist.Context context,
                ITexture texture, int x, int y)
            {
                if (screen == null || texture == null || context == null)
                {
                    return;
                }

                Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                int w = screen.Width;
                int h = screen.Height;

                // 白で塗りつぶし
                screen.SetColor(255, 255, 255);
                screen.DrawPolygon(
                    0, 0,
                    w, 0,
                    w, h,
                    0, h
                );

                screen.BlendSubColor();
                DrawAssist.Blt(screen, texture, x, y, context);
            }

            /// ランダムで１、または-1を取得する
            protected static int GetSignRand()
            {
                return RAND.GetRand(2) == 0 ? 1 : -1;
            }


            protected static Rand RAND;
            protected FixTimer m_timer;
            protected FixTimer m_innerTimer;
            protected bool m_finish;
        }

        /// <summary>
        /// シーン１
        /// </summary>
        private class Scene01 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene01(FixTimer grobalTimer, FilmNoise filmNoise, FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 5200));	// 空白
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 15000)); // 去人たち
                m_timeRange.Add(new TimeRange(m_innerTimer, 15000, 25000));	// プレゼント
                m_timeRange.Add(new TimeRange(m_innerTimer, 25000, 30000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 30000, 35000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 35000, 40000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 40000, 45000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 45000, 50000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 50000, 55000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 55000, 60000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 60000, 65000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 65000, 70000));	// スタッフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 70000, 75000));	// スタッフ

                m_timeRange.Add(new TimeRange(m_innerTimer, 75000, 80000));	// セリフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 80000, 85000));	// セリフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 85000, 87500));	// セリフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 87500, 90000));	// セリフ
                m_timeRange.Add(new TimeRange(m_innerTimer, 90000, 92500));	// セリフ

                m_timeRange.Add(new TimeRange(m_innerTimer, 92600, 93000));	// キャラ１
                m_timeRange.Add(new TimeRange(m_innerTimer, 93000, 93400));	// キャラ２
                m_timeRange.Add(new TimeRange(m_innerTimer, 93400, 93900));	// セリフ３
                m_timeRange.Add(new TimeRange(m_innerTimer, 93800, 94400));	// セリフ４
                m_timeRange.Add(new TimeRange(m_innerTimer, 94300, 95000));	// セリフ５

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.EMPTY;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                m_textureLoader.LoadDefFile("img/main_ending/s01/bg.lst");
                m_drawAlpha = new RootCounterS();
                m_drawAlpha.Set(0, 255, 1);
                ////Log.print("%s#OnInit : FINISH.", super.toString());
                return 0;
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                ////Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                if (m_finish)
                {
                    return 0;
                }
                switch (m_currentSection)
                {
                    case SECTION.EMPTY:
                        screen.SetClearColor(255, 255, 255);
                        m_drawAlpha.Inc();
                        m_timeRange[(int)SECTION.EMPTY].Update();
                        if (m_timeRange[(int)SECTION.EMPTY].IsAfter())
                        {
                            m_currentSection = SECTION.KYOJIN;
                            m_imgIndex = 1;

                            // ノイズを入れる
                            m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                            screen.SetClearColor(0, 0, 0);
                            ////Log.print("TO KYOJIN [%s ms]", m_timeRange[(int)SECTION.EMPTY].Get());
                        }
                        break;
                    case SECTION.KYOJIN:
                        m_timeRange[(int)SECTION.KYOJIN].Update();
                        if (m_timeRange[(int)SECTION.KYOJIN].IsAfter())
                        {
                            m_currentSection = SECTION.K2C;
                            m_imgIndex = 2;
                            // ノイズを入れる
                            m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                            ////Log.print("TO K2C [%s ms]", m_timeRange[(int)SECTION.KYOJIN].Get());
                        }
                        break;
                    case SECTION.K2C:
                        m_timeRange[(int)SECTION.K2C].Update();
                        if (m_timeRange[(int)SECTION.K2C].IsAfter())
                        {
                            m_currentSection = SECTION.STAFF;
                            m_imgIndex = 3;
                            // ノイズを入れる
                            m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            m_innerIndex = 0;
                            ////Log.print("TO STAFF [%s ms]", m_timeRange[(int)SECTION.K2C].Get());
                        }
                        break;
                    case SECTION.STAFF:
                        m_timeRange[(int)SECTION.STAFF + m_innerIndex].Update();
                        if (m_timeRange[(int)SECTION.STAFF + m_innerIndex].IsAfter())
                        {
                            ++m_innerIndex;
                            if (m_innerIndex >= 10)
                            {
                                ++m_imgIndex;
                                m_innerIndex = 0;
                                m_currentSection = SECTION.REMARK;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                ////Log.print("TO REMARK [%s ms]", m_timeRange[(int)SECTION.K2C].Get());
                            }
                            else
                            {
                                ++m_imgIndex;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }
                        }
                        break;
                    case SECTION.REMARK:
                        m_timeRange[(int)SECTION.REMARK + m_innerIndex].Update();
                        if (m_timeRange[(int)SECTION.REMARK + m_innerIndex].IsAfter())
                        {
                            ++m_innerIndex;
                            if (m_innerIndex >= 5)
                            {
                                ++m_imgIndex;
                                m_innerIndex = 0;
                                m_currentSection = SECTION.CHARA;
                                ////Log.print("TO CHARA [%s ms]", m_timeRange[(int)SECTION.K2C].Get());
                                m_filmNoiseBg.NoiseDrawNow(10 * GetSignRand(), 5);
                            }
                            else
                            {
                                ++m_imgIndex;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }
                        }
                        break;
                    case SECTION.CHARA:
                        m_timeRange[(int)SECTION.CHARA + m_innerIndex].Update();
                        if (m_timeRange[(int)SECTION.CHARA + m_innerIndex].IsAfter())
                        {
                            ++m_innerIndex;
                            if (m_innerIndex >= 5)
                            {
                                m_finish = true;
                                m_innerIndex = 0;
                                m_currentSection = SECTION.CHARA;
                            }
                            else
                            {
                                ++m_imgIndex;
                                m_filmNoiseBg.NoiseDrawNow(10 * GetSignRand(), 5);
                            }
                        }
                        break;
                    default:
                        Debug.Assert(false);
                        break;
                }

                m_filmNoiseBg.OnMove(screen);
                m_filmNoise.OnMove(screen);
                return 0;
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                screen.Clear();
                Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                switch (m_currentSection)
                {
                    case SECTION.EMPTY:
                        screen.SetColor(colorOrg.R, colorOrg.G, colorOrg.B, m_drawAlpha.Value());
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    case SECTION.KYOJIN:
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    case SECTION.K2C:
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    case SECTION.STAFF:
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    case SECTION.REMARK:
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    case SECTION.CHARA:
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    default:
                        ////Log.printError("m_currentSection = %s", (int)m_currentSection);
                        Debug.Assert(false);
                        break;
                }

                m_filmNoise.OnDraw(screen);

                screen.SetColor(colorOrg);

                return 0;
            }

            private enum SECTION : int { EMPTY, KYOJIN, K2C, STAFF, REMARK = 13, CHARA = 18 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private RootCounterS m_drawAlpha;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            private int m_innerIndex;
        }

        /** シーン03 声優クレジット */
        private class Scene03 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene03(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {
                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 5000));		// ありす
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 10000));  // 翠子
                m_timeRange.Add(new TimeRange(m_innerTimer, 10400, 15000));	// 富絵
                m_timeRange.Add(new TimeRange(m_innerTimer, 15600, 20000));	// 安西
                m_timeRange.Add(new TimeRange(m_innerTimer, 20600, 25000));	// ルビ
                m_timeRange.Add(new TimeRange(m_innerTimer, 25600, 29400));	// アウト
                m_timeRange.Add(new TimeRange(m_innerTimer, 29000, 30000));	// アウト

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.ALICE;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s03/bg.lst");
                    m_drawAlpha = new RootCounterS();
                    m_drawAlpha.Set(0, 255, 1);
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]", super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.ALICE:
                            m_timeRange[(int)SECTION.ALICE].Update();
                            if (m_timeRange[(int)SECTION.ALICE].IsAfter())
                            {
                                m_currentSection = SECTION.MIDORIKO;
                                m_imgIndex = 1;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO MIDORIKO [%s ms]", m_timeRange[(int)SECTION.ALICE].Get());
                            }
                            break;
                        case SECTION.MIDORIKO:
                            m_timeRange[(int)SECTION.MIDORIKO].Update();
                            if (m_timeRange[(int)SECTION.MIDORIKO].IsAfter())
                            {
                                m_currentSection = SECTION.TOMIE;
                                m_imgIndex = 2;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO TOMIE [%s ms]", m_timeRange[(int)SECTION.MIDORIKO].Get());
                            }
                            break;
                        case SECTION.TOMIE:
                            m_timeRange[(int)SECTION.TOMIE].Update();
                            if (m_timeRange[(int)SECTION.TOMIE].IsAfter())
                            {
                                m_currentSection = SECTION.ANZAI;
                                m_imgIndex = 3;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("TO ANZAI [%s ms]", m_timeRange[(int)SECTION.TOMIE].Get());
                            }
                            break;
                        case SECTION.ANZAI:
                            m_timeRange[(int)SECTION.ANZAI].Update();
                            if (m_timeRange[(int)SECTION.ANZAI].IsAfter())
                            {
                                ++m_imgIndex;
                                m_currentSection = SECTION.RUBI;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("TO RUBI [%s ms]", m_timeRange[(int)SECTION.ANZAI].Get());
                            }
                            break;
                        case SECTION.RUBI:
                            m_timeRange[(int)SECTION.RUBI].Update();
                            if (m_timeRange[(int)SECTION.RUBI].IsAfter())
                            {
                                m_currentSection = SECTION.K2C_STYLE;
                                ++m_imgIndex;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("TO FADE_OUT [%s ms]", m_timeRange[(int)SECTION.TOMIE].Get());
                            }
                            break;
                        case SECTION.K2C_STYLE:
                            m_timeRange[(int)SECTION.K2C_STYLE].Update();
                            if (m_timeRange[(int)SECTION.K2C_STYLE].IsAfter())
                            {
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                m_currentSection = SECTION.FADE_OUT;
                            }
                            break;
                        case SECTION.FADE_OUT:
                            m_timeRange[(int)SECTION.FADE_OUT].Update();
                            if (m_timeRange[(int)SECTION.FADE_OUT].IsAfter())
                            {
                                m_finish = true;
                            }
                            else
                            {
                                // フルノイズ
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();

                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.ALICE:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.MIDORIKO:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.TOMIE:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.ANZAI:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.RUBI:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.K2C_STYLE:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.FADE_OUT:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;
                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }


            private enum SECTION : int { ALICE, MIDORIKO, TOMIE, ANZAI, RUBI, K2C_STYLE, FADE_OUT };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private RootCounterS m_drawAlpha;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            //int m_innerIndex;
        }


        /** シーン04 ボーカル歌詞 */
        private class Scene04 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene04(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 5000));		// cos I was not Able to help you, Yet.
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 10000));  // but you Also, you did Not heip me, too.
                m_timeRange.Add(new TimeRange(m_innerTimer, 10000, 15000));	// Cos I am FOOLish, I will Be satisfied...
                m_timeRange.Add(new TimeRange(m_innerTimer, 15000, 20000));	// repeat

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s04/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = 1;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = 2;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_imgIndex = 3;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.CUT02:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.CUT03:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.CUT04:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            //private int m_innerIndex;

        }


        /** シーン05 ボーカル間奏 */
        private class Scene05 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene05(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {
                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 2500));		// cos I was not Able to help you, Yet.
                m_timeRange.Add(new TimeRange(m_innerTimer, 2500, 5000));  // but you Also, you did Not heip me, too.
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 7500));	// Cos I am FOOLish, I will Be satisfied...
                m_timeRange.Add(new TimeRange(m_innerTimer, 7500, 10000));	// repeat

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s05/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = 1;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = 2;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_imgIndex = 3;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                        case SECTION.CUT02:
                        case SECTION.CUT03:
                        case SECTION.CUT04:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            //private int m_innerIndex;

        }

        /** シーン06 ボーカルサビ KILL ME! */
        private class Scene06 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene06(FixTimer grobalTimer, FilmNoise filmNoise,
                         FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 2500));		// KILL ME!
                m_timeRange.Add(new TimeRange(m_innerTimer, 2500, 5000));  // KILL ME!
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 7500));	// I WANT YOU TO!
                m_timeRange.Add(new TimeRange(m_innerTimer, 7500, 10000));	// KILL ME!

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s06/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = 1;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = 2;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_imgIndex = 3;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;
                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.CUT02:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.CUT03:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        case SECTION.CUT04:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }


            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;
            //private int m_innerIndex;
        }

        /** シーン07 ボーカル 間奏 キャラクター線画 */
        private class Scene07 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制すべし
            public Scene07(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 2500));		//
                m_timeRange.Add(new TimeRange(m_innerTimer, 2500, 5000));  // KILL ME!
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 7500));	// I WANT YOU TO!
                m_timeRange.Add(new TimeRange(m_innerTimer, 7500, 10000));	// KILL ME!
                m_timeRange.Add(new TimeRange(m_innerTimer, 10000, 12500));		//
                m_timeRange.Add(new TimeRange(m_innerTimer, 12500, 15000));  // KILL ME!
                m_timeRange.Add(new TimeRange(m_innerTimer, 15000, 17500));	// I WANT YOU TO!
                m_timeRange.Add(new TimeRange(m_innerTimer, 17500, 20000));	// KILL ME!

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;

                for (int i = 0; i < IMG_STOCK - 1; ++i)
                {
                    m_imgNumbers.Add(i);
                }

                Rand myRand = new Rand();
                myRand.Randomize();
                // シャッフル
                for (int i = 0; i < 128; ++i)
                {
                    int src = myRand.GetRand(m_imgNumbers.Count);
                    int dst = myRand.GetRand(m_imgNumbers.Count);
                    if (src == dst)
                    {
                        continue;
                    }
                    int tmp = m_imgNumbers[src];
                    m_imgNumbers[src] = m_imgNumbers[dst];
                    m_imgNumbers[dst] = tmp;
                }

                // 最後は固定
                m_imgNumbers[(int)SECTION.CUT08] = IMG_STOCK - 1;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s07/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    m_imgIndex = m_imgNumbers[m_imgCounter];
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                m_currentSection = SECTION.CUT05;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT05:
                            m_timeRange[(int)SECTION.CUT05].Update();
                            if (m_timeRange[(int)SECTION.CUT05].IsAfter())
                            {
                                m_currentSection = SECTION.CUT06;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT05].Get());
                            }
                            break;
                        case SECTION.CUT06:
                            m_timeRange[(int)SECTION.CUT06].Update();
                            if (m_timeRange[(int)SECTION.CUT06].IsAfter())
                            {
                                m_currentSection = SECTION.CUT07;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT06].Get());
                            }
                            break;
                        case SECTION.CUT07:
                            m_timeRange[(int)SECTION.CUT07].Update();
                            if (m_timeRange[(int)SECTION.CUT07].IsAfter())
                            {
                                m_currentSection = SECTION.CUT08;
                                m_imgIndex = m_imgNumbers[++m_imgCounter];
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT07].Get());
                            }
                            break;
                        case SECTION.CUT08:
                            m_timeRange[(int)SECTION.CUT08].Update();
                            if (m_timeRange[(int)SECTION.CUT08].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT08].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                        case SECTION.CUT02:
                        case SECTION.CUT03:
                        case SECTION.CUT04:
                        case SECTION.CUT05:
                        case SECTION.CUT06:
                        case SECTION.CUT07:
                        case SECTION.CUT08:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }


            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04, CUT05, CUT06, CUT07, CUT08 };
            private const int BASE_RANGE = 5000;
            private const int IMG_STOCK = 12;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            private readonly List<int> m_imgNumbers = new List<int>();
            private int m_imgCounter;
            //private int m_innerIndex;

        }

        /** シーン０８
         * ありす＋廊下
         */
        private class Scene08 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene08(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                // 表示用テクスチャローダ
                m_textureLoader = new TextureLoader();

                // カット１（イントロ）
                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 2500));	// 壁＋ノイズ
                m_timeRange.Add(new TimeRange(m_innerTimer, 2500, 5000));	// ノイズ（廊下）
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 7500));	// 壁＋ノイズ
                m_timeRange.Add(new TimeRange(m_innerTimer, 7500, 10000));	// ノイズ（廊下＋ありす）

                // カット２(you Ask Me)
                m_timeRange.Add(new TimeRange(m_innerTimer, 10000, 12500));	// 壁＋文字
                // カット３(so I Tell you)
                m_timeRange.Add(new TimeRange(m_innerTimer, 12000, 14800));	// 壁＋文字
                // カット４("A Nice")
                m_timeRange.Add(new TimeRange(m_innerTimer, 14500, 15400));	// 壁拡大
                // カット５("to")
                m_timeRange.Add(new TimeRange(m_innerTimer, 14900, 15800));	// 壁拡大
                // カット６("Meet
                m_timeRange.Add(new TimeRange(m_innerTimer, 15300, 16100));	// 壁拡大
                // カット７("You")
                m_timeRange.Add(new TimeRange(m_innerTimer, 15700, 17700));	// 壁拡大
                // カット８("is it?")
                m_timeRange.Add(new TimeRange(m_innerTimer, 16800, 18200));	// 壁＋ありす
                // カット８("is it?")
                m_timeRange.Add(new TimeRange(m_innerTimer, 19000, 19750));	// 壁＋ありす

                // アルファカウンタ
                m_alphaCounter = new RootCounterS();
                m_alphaCounter.Set(255, 0, 48);

                m_alphaFlash = new RootCounter();
                m_alphaFlash.ReverseFlg = (true);
                m_alphaFlash.Set(0, 48, 8);

                m_filmNoiseBg = filmNoiseBg;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    // 表示画像リストの読み込み
                    m_textureLoader.LoadDefFile("img/main_ending/s08/bg.lst");
                    // 展開が速いので読み込んでおくべし
                    LoadCacheAll(m_textureLoader, YanesdkUtil.GetElementNum("img/main_ending/s08/bg.lst"));

                    //Log.print("%s#OnInit FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    // 終了してる
                    if (m_finish)
                    {
                        return 0;
                    }
                    // タイマーリセット
                    if (!m_init)
                    {
                        ResetSceneTimer();
                        m_init = true;
                    }
                    if (m_currentRange >= m_timeRange.Count)
                    {
                        // シーン終了
                        m_finish = true;
                        return 0;
                    }


                    switch (m_currentRange)
                    {
                        case 0:	// カット１壁＋ノイズ
                            if (checkAfter())
                            {
                                // ぶれノイズ発生
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }
                            break;
                        case 1:	// カット２廊下オーバー
                            // 常にノイズ
                            if (m_nextTime < m_timeRange[m_currentRange].Get())
                            {
                                m_alphaFlash.Inc();
                            }
                            if (m_alphaFlash.IsLapAroundI)
                            {
                                m_nextTime = m_timeRange[m_currentRange].Get() + 500 + RAND.GetRand(750);
                                m_alphaFlash.Reset();
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }

                            if (checkAfter())
                            {
                                m_currentRange = 2;
                                m_alphaFlash.Reset();
                            }
                            break;
                        case 2:	// カット３壁＋ノイズ
                            if (checkAfter())
                            {
                                // ぶれノイズ発生
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                m_currentRange = 3;
                            }
                            break;

                        case 3:	// カット４（廊下＋alice）オーバー
                            if (m_nextTime < m_timeRange[m_currentRange].Get())
                            {
                                m_alphaFlash.Inc();
                            }
                            if (m_alphaFlash.IsLapAroundI)
                            {
                                m_nextTime = m_timeRange[m_currentRange].Get() + 500 + RAND.GetRand(750);
                                m_alphaFlash.Reset();
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }

                            if (checkAfter())
                            {
                                // ぶれノイズ発生
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                m_currentRange = 4;
                            }
                            break;
                        case 4:	// カット５ you Ask Me
                            if (checkAfter())
                            {
                                // ぶれノイズ発生
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                m_currentRange = 5;
                            }
                            break;
                        case 5:	// カット６ so I Tell You
                            if (checkAfter())
                            {
                                m_imgIndex = IMG_REMARK1;
                                m_currentRange = 6;
                                m_filmNoise.GetManager().SetRate(3.0f);
                            }
                            break;
                        case 6:	// カット６ A Nice
                            if (checkAfter())
                            {
                                ++m_imgIndex;
                                m_currentRange = 7;
                                m_alphaCounter.Reset();
                            }
                            break;
                        case 7:	// カット７ to
                            m_alphaCounter.Inc();
                            if (checkAfter())
                            {
                                ++m_imgIndex;
                                m_currentRange = 8;
                                m_alphaCounter.Reset();
                            }
                            break;
                        case 8:	// カット８ Meet
                            m_alphaCounter.Inc();
                            if (checkAfter())
                            {
                                ++m_imgIndex;
                                m_currentRange = 9;
                                m_alphaCounter.Reset();
                            }
                            break;
                        case 9:	// カット９ You
                            m_alphaCounter.Inc();
                            if (checkAfter())
                            {
                                ++m_imgIndex;
                                m_currentRange = 10;
                                m_filmNoise.GetManager().SetRate(1.0f);
                                m_alphaCounter.Set(800, 0, 7);
                            }
                            break;
                        case 10:	// カット１０ is it?
                            if (checkAfter())
                            {
                                ++m_imgIndex;
                                m_currentRange = 11;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                            }
                            break;
                        case 11:	// カット１１ フェードアウト
                            m_alphaCounter.Inc();
                            if (checkAfter())
                            {
                                m_finish = true;
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    screen.Clear();

                    switch (m_currentRange)
                    {
                        case 0:	// カット１壁＋ノイズ
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_WALL1), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        case 1:	// カット２廊下
                            // 壁
                            screen.SetColor(255, 255, 255, 255);
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_WALL1), 0, 0);
                            screen.SetColor(255, 255, 255, m_alphaFlash.Value());
                            // 廊下ノイズ
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_ROUKA1), 0, 0);
                            break;
                        case 2:	// カット３壁＋ノイズ
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_WALL1), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        case 3:	// カット４廊下＋alice
                            // 壁
                            screen.SetColor(255, 255, 255, 255);
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_WALL1), 0, 0);
                            screen.SetColor(255, 255, 255, m_alphaFlash.Value());
                            // 廊下ノイズ
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_ROUKA2), 0, 0);
                            break;
                        case 4:	// カット５ you Ask Me
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_WALL2), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        case 5:	// カット６ so I Tell You
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(IMG_WALL3), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        case 6:	// カット６ A Nice
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        case 7:	// カット７ to
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            if (0 != m_alphaCounter.Value())
                            {
                                screen.SetColor(255, 255, 255, m_alphaCounter.Value());
                                DrawAssist.Blt(screen, m_textureLoader.GetTexture(m_imgIndex - 1), 0, 0,
                                        (DrawAssist.Context)DrawAssist.SCREEN_SIZE);
                                screen.SetColor(255, 255, 255, 255);
                            }
                            break;
                        case 8:	// カット８ Meet
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            if (0 != m_alphaCounter.Value())
                            {
                                screen.SetColor(255, 255, 255, m_alphaCounter.Value());
                                DrawAssist.Blt(screen, m_textureLoader.GetTexture(m_imgIndex - 1), 0, 0,
                                        (DrawAssist.Context)DrawAssist.SCREEN_SIZE);
                                screen.SetColor(255, 255, 255, 255);
                            }
                            break;
                        case 9:	// カット９ You
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            if (0 != m_alphaCounter.Value())
                            {
                                screen.SetColor(255, 255, 255, m_alphaCounter.Value());
                                DrawAssist.Blt(screen, m_textureLoader.GetTexture(m_imgIndex - 1), 0, 0,
                                        (DrawAssist.Context)DrawAssist.SCREEN_SIZE);
                                screen.SetColor(255, 255, 255, 255);
                            }
                            break;
                        case 10:	// カット１０ is it?
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        case 11:	// カット１１ フェードアウト
                            int alpha = m_alphaCounter.Value();
                            if (alpha > 255)
                            {
                                alpha = 255;
                            }
                            screen.SetColor(colorOrg.R, colorOrg.G, colorOrg.B, alpha);
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            m_filmNoise.OnDraw(screen);
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    screen.SetColor(colorOrg);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                try
                {
                    m_init = false;
                    m_finish = false;
                    m_textureLoader.Dispose();
                    //Log.print("%s#Destroy : FINISH.", super.toString());
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#Destroy : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }


            private const int IMG_WALL1 = 0;
            private const int IMG_ROUKA1 = 1;
            private const int IMG_ROUKA2 = 2;
            private const int IMG_WALL2 = 3;
            private const int IMG_WALL3 = 4;
            private const int IMG_REMARK1 = 5;

            /// 現在のカットが終了ならばture
            private bool checkAfter()
            {
                m_timeRange[m_currentRange].Update();
                if (m_timeRange[m_currentRange].IsAfter())
                {
                    if (m_currentRange + 1 >= m_timeRange.Count)
                    {
                        m_finish = true;
                        return true;
                    }
                    ++m_currentRange;
                    //Log.print("NEXT %s [%s ms]", m_currentRange, m_timeRange[m_currentRange - 1].Get());
                    return true;
                }
                return false;
            }

            private bool m_init;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private int m_currentRange;

            private TextureLoader m_textureLoader;
            private int m_imgIndex;

            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            private RootCounterS m_alphaCounter;	//!< アルファ用のカウンタ
            private RootCounter m_alphaFlash;
            private int m_nextTime;
        }

        /** シーン09 ボーカル歌詞 */
        private class Scene09 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene09(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 5000));		// cos I was not Able to help you, Yet.
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 10000));  // but you Also, you did Not heip me, too.
                m_timeRange.Add(new TimeRange(m_innerTimer, 10000, 15000));	// Cos I am FOOLish, I will Be satisfied...
                m_timeRange.Add(new TimeRange(m_innerTimer, 15000, 20000));	// repeat

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s09/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = 1;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = 2;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_imgIndex = 3;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                        case SECTION.CUT02:
                        case SECTION.CUT03:
                        case SECTION.CUT04:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }


            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            //private int m_innerIndex;
        }

        /** シーン10 ボーカル歌詞 */
        private class Scene10 : SceneBase
        {

            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene10(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 2500));		// cos I was not Able to help you, Yet.
                m_timeRange.Add(new TimeRange(m_innerTimer, 2500, 5000));  // but you Also, you did Not heip me, too.
                m_timeRange.Add(new TimeRange(m_innerTimer, 5000, 7500));	// Cos I am FOOLish, I will Be satisfied...
                m_timeRange.Add(new TimeRange(m_innerTimer, 7500, 10000));	// repeat
                m_timeRange.Add(new TimeRange(m_innerTimer, 10000, 12500));		// cos I was not Able to help you, Yet.
                m_timeRange.Add(new TimeRange(m_innerTimer, 12500, 15000));  // but you Also, you did Not heip me, too.
                m_timeRange.Add(new TimeRange(m_innerTimer, 15000, 17500));	// Cos I am FOOLish, I will Be satisfied...
                m_timeRange.Add(new TimeRange(m_innerTimer, 17500, 20000));	// repeat

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s10/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = 1;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = 2;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 9);
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_imgIndex = 3;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                m_currentSection = SECTION.CUT05;
                                ++m_imgIndex;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        case SECTION.CUT05:
                            m_timeRange[(int)SECTION.CUT05].Update();
                            if (m_timeRange[(int)SECTION.CUT05].IsAfter())
                            {
                                m_currentSection = SECTION.CUT06;
                                ++m_imgIndex;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT05].Get());
                            }
                            break;
                        case SECTION.CUT06:
                            m_timeRange[(int)SECTION.CUT06].Update();
                            if (m_timeRange[(int)SECTION.CUT06].IsAfter())
                            {
                                m_currentSection = SECTION.CUT07;
                                ++m_imgIndex;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT06].Get());
                            }
                            break;
                        case SECTION.CUT07:
                            m_timeRange[(int)SECTION.CUT07].Update();
                            if (m_timeRange[(int)SECTION.CUT07].IsAfter())
                            {
                                m_currentSection = SECTION.CUT08;
                                ++m_imgIndex;
                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //m_innerIndex = 0;
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT07].Get());
                            }
                            break;
                        case SECTION.CUT08:
                            m_timeRange[(int)SECTION.CUT08].Update();
                            if (m_timeRange[(int)SECTION.CUT08].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                try
                {
                    screen.Clear();
                    Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                        case SECTION.CUT02:
                        case SECTION.CUT03:
                        case SECTION.CUT04:
                        case SECTION.CUT05:
                        case SECTION.CUT06:
                        case SECTION.CUT07:
                        case SECTION.CUT08:
                            m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                    m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                            break;
                        default:
                            //Log.printError("m_currentSection = %s", (int)m_currentSection);
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoise.OnDraw(screen);

                    screen.SetColor(colorOrg);

                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnDraw : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }


            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04, CUT05, CUT06, CUT07, CUT08 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;

            //private int m_innerIndex;
        }

        /** シーン11 ボーカル歌詞 */
        private class Scene11 : SceneBase
        {
            /// コンストラクタ
            /// 必要なものをすべて強制
            public Scene11(FixTimer grobalTimer, FilmNoise filmNoise,
                    FilmNoiseBgDraw filmNoiseBg, Sound bgm)
                : base(grobalTimer)
            {

                m_timeRange.Add(new TimeRange(m_innerTimer, 0, 10000));	// Are you reciving this?
                m_timeRange.Add(new TimeRange(m_innerTimer, 10000, 25000));	// Are you reciving this?
                m_timeRange.Add(new TimeRange(m_innerTimer, 25000, 40000)); // but you Also, you did Not heip me, too.
                m_timeRange.Add(new TimeRange(m_innerTimer, 40000, 43000));	// Cos I am FOOLish, I will Be satisfied...

                // フィルムノイズ用背景描画クラス
                m_filmNoiseBg = filmNoiseBg;
                // 使用する画像
                m_textureLoader = new TextureLoader();

                m_currentSection = SECTION.CUT01;
                m_filmNoise = filmNoise;

                m_bgm = bgm;
                m_cameraWork = new CameraWork("img/main_ending/s11/cw/list.lst", 2, 2);
                m_cameraWork.LoadFlow("img/main_ending/s11/cw/mouse.txt");

                m_alpha = new RootCounterS();
                m_alpha.Set(255, 0, 4);
                m_imgIndex = 1;
            }

            /// 初期化処理
            public override int OnInit(IScreen screen)
            {
                try
                {
                    m_textureLoader.LoadDefFile("img/main_ending/s11/bg.lst");
                    m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                    //Log.print("%s#OnInit : FINISH.", super.toString());
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnInit : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// オブジェクトの解放
            public override void Destroy()
            {
                m_textureLoader.Dispose();
                m_finish = false;
                //Log.print("%s#Destroy : FINISH.", super.toString());
            }

            /// 移動処理	
            public override int OnMove(IScreen screen)
            {
                try
                {
                    if (m_finish)
                    {
                        return 0;
                    }
                    switch (m_currentSection)
                    {
                        case SECTION.CUT01:
                            m_timeRange[(int)SECTION.CUT01].Update();
                            if (m_timeRange[(int)SECTION.CUT01].IsAfter())
                            {
                                m_currentSection = SECTION.CUT02;
                                m_imgIndex = 0;

                                // ノイズを入れる
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 8);
                                screen.SetClearColor(0, 0, 0);
                                //Log.print("TO CUT02 [%s ms]", m_timeRange[(int)SECTION.CUT01].Get());
                            }
                            break;
                        case SECTION.CUT02:
                            m_timeRange[(int)SECTION.CUT02].Update();
                            if (m_timeRange[(int)SECTION.CUT02].IsAfter())
                            {
                                m_currentSection = SECTION.CUT03;
                                m_imgIndex = 2;
                                //Log.print("TO CUT03 [%s ms]", m_timeRange[(int)SECTION.CUT02].Get());
                            }
                            break;
                        case SECTION.CUT03:
                            m_timeRange[(int)SECTION.CUT03].Update();
                            if (m_timeRange[(int)SECTION.CUT03].IsAfter())
                            {
                                m_currentSection = SECTION.CUT04;
                                m_bgm.Stop();
                                m_filmNoise.GetManager().SetRate(3.0f);
                                //Log.print("TO CUT04 [%s ms]", m_timeRange[(int)SECTION.CUT03].Get());
                            }
                            break;
                        case SECTION.CUT04:
                            m_cameraWork.OnMove(screen);
                            m_alpha.Inc();
                            m_timeRange[(int)SECTION.CUT04].Update();
                            if (m_timeRange[(int)SECTION.CUT04].IsAfter())
                            {
                                //m_innerIndex = 0;
                                m_finish = true;
                                m_filmNoiseBg.NoiseDrawNow(20 * GetSignRand(), 10);
                                //Log.print("SCENE04 END [%s ms]", m_timeRange[(int)SECTION.CUT04].Get());
                            }
                            break;
                        default:
                            Debug.Assert(false);
                            break;

                    }

                    m_filmNoiseBg.OnMove(screen);
                    m_filmNoise.OnMove(screen);
                    return 0;
                }
                catch (Exception e)
                {
                    //Log.printError("Exception %s#OnMove : [%s] [%s]",super.toString(), e.toString(), e.msg);
                    throw e;
                }
            }

            /// 描画処理	
            public override int OnDraw(IScreen screen)
            {
                screen.Clear();
                Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
                switch (m_currentSection)
                {
                    case SECTION.CUT01:
                    case SECTION.CUT02:
                    case SECTION.CUT03:
                        m_filmNoiseBg.OnDraw((DrawAssist.Context)DrawAssist.SCREEN_SIZE, screen,
                                m_textureLoader.GetTexture(m_imgIndex), 0, 0);
                        break;
                    case SECTION.CUT04:
                        screen.SetColor(255, 255, 255, m_alpha.Value());
                        m_cameraWork.OnDraw(screen);
                        break;
                    default:
                        //Log.printError("m_currentSection = %s", (int)m_currentSection);
                        Debug.Assert(false);
                        break;

                }

                m_filmNoise.OnDraw(screen);

                screen.SetColor(colorOrg);

                return 0;
            }


            private enum SECTION : int { CUT01, CUT02, CUT03, CUT04 };
            private const int BASE_RANGE = 5000;

            private SECTION m_currentSection;
            private readonly List<TimeRange> m_timeRange = new List<TimeRange>();
            private TextureLoader m_textureLoader;
            private int m_imgIndex;
            private FilmNoiseBgDraw m_filmNoiseBg;
            private FilmNoise m_filmNoise;
            private Sound m_bgm;
            private CameraWork m_cameraWork;

            private RootCounterS m_alpha;

            //private int m_innerIndex;

        }

        #region 定数値


        #endregion

        #region メンバフィールド

        private readonly GameSystem m_gSys;
        private bool m_init;
        private bool m_loading;
        private bool m_finish;
        private readonly List<SceneBase> m_allScene = new List<SceneBase>();
        private int m_currentScene;
        private Sound m_bgm;
        private readonly FixTimer m_timer;
        private FilmNoise m_filmNoise;
        private FilmNoiseBgDraw m_filmNoiseBg;
        private ITexture noiseTexture;
        private TextureLoader noiseTextureLoader;


        #endregion

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

        #region IDisposable メンバ

        public void Dispose()
        {
            YamalibUtility.Dispose(m_bgm);
            YamalibUtility.Dispose(noiseTexture);
            YamalibUtility.Dispose(noiseTextureLoader);
        }

        #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 (!m_init)
            {
                OnInit();
                m_gSys.Screen.BlendSrcAlpha();
                m_init = true;
            }

            if (m_loading)
            {
                //if (m_bgm.isLoading())
                //{
                //    return 0;
                //}
                //else
                {
                    m_loading = false;
                    m_allScene[m_currentScene].ResetSceneTimer();
                }
            }

            // 現在のシーンの終了チェック
            if (m_allScene[m_currentScene].IsFinish())
            {
                if (m_currentScene < m_allScene.Count - 1)
                {
                    // オブジェクト破棄
                    m_allScene[m_currentScene].Destroy();
                    ++m_currentScene;
                    // タイマーをリセット
                    m_allScene[m_currentScene].ResetSceneTimer();
                    //Log.print("%s#OnMove : NEXT SCENE%s. [%s]ms",super.toString(), m_currentScene, m_timer.Get());
                }
                else
                {
                    m_gSys.Mouse.Show();
                    m_finish = true;
                    // エンディング終了
                    // すべてのスタックを破棄		
                    m_gSys.SceneController.ExitScene();
                    //m_gSys.SceneController.setTransitType(19, 2, true);
                    m_gSys.SceneController.JumpScene(Scenes.Startmenu);
                    //Log.print("%s#OnMove : ALL SCENE FINISHED.", super.toString());
                    return 0;
                }
            }

            if (!m_finish)
            {
                m_allScene[m_currentScene].OnMove(m_gSys.Screen);
            }
            return 1;
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="gameSystem"></param>
        private void OnPaint(GameSystem gameSystem)
        {
            if (m_loading)
            {
                return;
            }
            if (!m_finish)
            {
                m_allScene[m_currentScene].OnDraw(m_gSys.Screen);
            }
        }

        /// <summary>
        /// 初期化処理
        /// </summary>
        private void OnInit()
        {
            // まずマウスけしく
            m_gSys.Mouse.Hide();

            // 現在のシーン
            m_currentScene = 0;	// DEFAULT
            //		m_currentScene = 1;	// VOICE 03
            //		m_currentScene = 2;	// VOCAL 04
            //		m_currentScene = 3;	// ボーカル間奏 05
            //		m_currentScene = 4;	// ボーカルさび 06
            //		m_currentScene = 5;	// VOICE 07
            //		m_currentScene = 6;	// VOICE 08
            //		m_currentScene = 7;	// VOICE 09
            //		m_currentScene = 8;	// VOICE 10
            //		m_currentScene = 9;	// VOICE 11

            // BGM 読み込み
            m_bgm = new Sound();
            //		m_bgm.load( FileSys.read("snd/song/COZ_I_Want_You_To_(Ye-He).ogg"), 0);

            switch (m_currentScene)
            {
                case 0:
                    m_bgm.Load("snd\\song\\COZ_I_Want_You_To_(Ye-He).ogg", -1);
                    break;
                case 1:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)03.wav", 0);
                    break;
                case 2:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)04.wav", 0);
                    break;
                case 3:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)05.wav", 0);
                    break;
                case 4:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)06.wav", 0);
                    break;
                case 5:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)07.wav", 0);
                    break;
                case 6:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)08.wav", 0);
                    break;
                case 7:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)09.wav", 0);
                    break;
                case 8:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)10.wav", 0);
                    break;
                case 9:
                    m_bgm.Load("snd/song/COZ_I_Want_You_To_(Ye-He)11.wav", 0);
                    break;
                default:
                    Debug.Assert(false);
                    break;
            }

            //		m_currentScene = 0;	// 現在のシーン

            // フィルムノイズ用背景描画クラスの生成
            m_filmNoiseBg = new FilmNoiseBgDraw(80, 6, 3);
            // フィルムノイズフィルターの生成
            CreateFilmNoise();


            // 使用するシーンの生成
            CreateScene();

            // 全シーン初期化(loadOnMemory)
            foreach (SceneBase scene in m_allScene)
            {
                scene.OnInit(m_gSys.Screen);
            }

            // BGMのボリュームはオプション画面のボリュームにしとっかー
            m_bgm.Volume = m_gSys.OptionInfo.BGMVolume / 100.0f;
            m_bgm.Play();
            m_loading = true;
            Sdl.SDL.SDL_Delay(175);
        }

        /// <summary>
        /// 使用するシーンを構築します
        /// </summary>
        private void CreateScene()
        {
            m_allScene.Add(new Scene01(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene03(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene04(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene05(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene06(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene07(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene08(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene09(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene10(m_timer, m_filmNoise, m_filmNoiseBg));
            m_allScene.Add(new Scene11(m_timer, m_filmNoise, m_filmNoiseBg, m_bgm));
        }

        /// <summary>
        /// フィルムノイズクラスのセットアップを行う
        /// </summary>
        private void CreateFilmNoise()
        {
            FilmNoiseEssenceCreator.SetRange(20, 600);
            FilmNoiseEssenceCreator.SetMaxWidth(200, 150);
            FilmNoiseEssenceCreator.SetMaxSpeed(5.0f, 1.5f);
            FilmNoiseEssenceCreator.SetMaxAlpha(128, 16);
            FilmNoiseEssenceCreator.SetReverseDefault(false, false);

            // ノイズテクスチャのロード
            noiseTexture = YamalibConst.CreateTexture("img/main_ending/film_noise.png");
            //
            noiseTextureLoader = new TextureLoader();
            noiseTextureLoader.LoadDefFile("img/main_ending/noise/noise.lst");

            FilmNoise.FilmNoiseEssenceManager filmNoiseMgr = new FilmNoise.FilmNoiseEssenceManager();
            filmNoiseMgr.SetMaxShowNum(5);
            filmNoiseMgr.SetCreateInterval(25);
            filmNoiseMgr.SetNoiseTextureLoader(noiseTextureLoader, YanesdkUtil.GetElementNum("img/main_ending/noise/noise.lst"));
            filmNoiseMgr.SetDrawNoiseNum(5, 20);
            for (int i = 0; i < 128; ++i)
            {
                FilmNoise.FilmNoiseEssence essence = FilmNoiseEssenceCreator.Create();
                essence.Texture = noiseTexture;
                filmNoiseMgr.AddEssence(essence);
            }

            m_filmNoise = new FilmNoise(filmNoiseMgr);
        }



    }
}
