using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using FDK;

namespace StrokeStyleT
{
	class C選曲ステージ : CActivity
	{
		public C選曲ステージ()
		{
			// 全フェーズ共通
			this.list子Activities.Add( this.act背景 = new CAct背景() );
			this.list子Activities.Add( this.actステージキット = new CActステージキット() );
			this.list子Activities.Add( this.actドラムキット = new CActドラムキット() );
			this.list子Activities.Add( this.actドラムの矢印 = new CActドラムの矢印() );

			// 選曲フェーズ
			this.list子Activities.Add( this.F選曲.act曲パネル一覧 = new CAct曲パネル一覧() );

			// ユーザ選択フェーズ
			this.list子Activities.Add( this.Fユーザ選択.actパネル = new CActGUIパネル( Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Window.png" ) ) );

			this.Fユーザ選択.actパネル.list子Activities.Add(
				this.Fユーザ選択.act設定ボタン = new CActGUIボタン(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Button Config.png" ),
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect ButtonDown Config.png" ) ) );

			this.Fユーザ選択.actパネル.list子Activities.Add(
				this.Fユーザ選択.act曲管理ボタン = new CActGUIボタン(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Button SongsSetting.png" ),
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect ButtonDown SongsSetting.png" ) ) );

			this.Fユーザ選択.actパネル.list子Activities.Add(
				this.Fユーザ選択.act名前変更ボタン = new CActGUIボタン(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Button RenamePlayer.png" ),
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect ButtonDown RenamePlayer.png" ) ) );

			this.Fユーザ選択.actパネル.list子Activities.Add(
				this.Fユーザ選択.act新規作成ボタン = new CActGUIボタン(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Button NewPlayer.png" ),
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect ButtonDown NewPlayer.png" ) ) );

			this.Fユーザ選択.actパネル.list子Activities.Add(
				this.Fユーザ選択.act削除ボタン = new CActGUIボタン(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Button RemovePlayer.png" ),
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect ButtonDown RemovePlayer.png" ) ) );

			this.Fユーザ選択.act設定ボタン.Location = new Point( 607, 92 );	// パネル相対

			this.Fユーザ選択.act設定ボタン.list子Activities.Add(
				this.Fユーザ選択.act設定英字ラベル = new CActGUI画像(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Label Config.png" ) ) );

			this.Fユーザ選択.act設定英字ラベル.Location = new Point( 718, 72 );	// パネル相対

			this.Fユーザ選択.act曲管理ボタン.Location = new Point( 607, 162 );	// パネル相対

			this.Fユーザ選択.act曲管理ボタン.list子Activities.Add(
				this.Fユーザ選択.act曲管理英字ラベル = new CActGUI画像(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Label SongsSetting.png" ) ) );

			this.Fユーザ選択.act曲管理英字ラベル.Location = new Point( 718, 140 );	// パネル相対

			this.Fユーザ選択.act名前変更ボタン.Location = new Point( 607, 232 );	// パネル相対

			this.Fユーザ選択.act名前変更ボタン.list子Activities.Add(
				this.Fユーザ選択.act名前変更英字ラベル = new CActGUI画像(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Label RenamePlayer.png" ) ) );

			this.Fユーザ選択.act名前変更英字ラベル.Location = new Point( 706, 211 );	// パネル相対

			this.Fユーザ選択.act新規作成ボタン.Location = new Point( 607, 418 );	// パネル相対

			this.Fユーザ選択.act新規作成ボタン.list子Activities.Add(
					this.Fユーザ選択.act新規作成英字ラベル = new CActGUI画像(
						this.Fユーザ選択.actパネル,
						Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Label NewPlayer.png" ) ) );

			this.Fユーザ選択.act新規作成英字ラベル.Location = new Point( 729, 397 );	// パネル相対

			this.Fユーザ選択.act削除ボタン.Location = new Point( 607, 485 );	// パネル相対

			this.Fユーザ選択.act削除ボタン.list子Activities.Add(
				this.Fユーザ選択.act削除英字ラベル = new CActGUI画像(
					this.Fユーザ選択.actパネル,
					Path.Combine( Global.Folders.stgシステムフォルダパス, @"Images\StageSelect PlayerSelect Label RemovePlayer.png" ) ) );

			this.Fユーザ選択.act削除英字ラベル.Location = new Point( 707, 464 );	// パネル相対
		}

		protected override void Onデバイスリソースの作成()
		{
			lock( this )
			{
				Global.tデバイスをロックして処理を行う( ( hDevice ) => {

					this.Fユーザ選択.dicユーザ名テクスチャ = new Dictionary<User, CTexture>();
					this.Fユーザ選択.fontユーザ名用フォント = new Font( "メイリオ", 36f, FontStyle.Bold );
					foreach( var user in Global.Users )
					{
						using( var bmp = new Bitmap( 502, 64, PixelFormat.Format32bppArgb ) )
						using( var g = Graphics.FromImage( bmp ) )
						{
							g.Clear( Color.FromArgb( alpha: 20, baseColor: Color.White ) );	// 背景色
							g.SmoothingMode = SmoothingMode.HighQuality;					// アンチエイリアス
							g.CompositingQuality = CompositingQuality.HighQuality;			// レンダリング品質

							using( var gp = new GraphicsPath() )
							{
								gp.AddString(												// 文字列のパスを作成
									user.stg名前,
									this.Fユーザ選択.fontユーザ名用フォント.FontFamily,
									(int) this.Fユーザ選択.fontユーザ名用フォント.Style,
									this.Fユーザ選択.fontユーザ名用フォント.SizeInPoints,
									new Point( 20, 4 ),
									StringFormat.GenericDefault );

								g.DrawPath( new Pen( Brushes.Black, 10f ), gp );			// 文字の縁を描画
								g.FillPath( Brushes.DarkOrange, gp );						// 文字の塗りつぶし
							}

							this.Fユーザ選択.dicユーザ名テクスチャ.Add( user, new CTexture( hDevice, bmp ) );	// テクスチャの作成と登録
						}
					}

				} );
			}
		}
		protected override void Onデバイスリソースの解放()
		{
			lock( this )
			{
				if( null != this.Fユーザ選択.fontユーザ名用フォント )
				{
					this.Fユーザ選択.fontユーザ名用フォント.Dispose();
					this.Fユーザ選択.fontユーザ名用フォント = null;
				}

				foreach( KeyValuePair<User, CTexture> kvp in this.Fユーザ選択.dicユーザ名テクスチャ )
					kvp.Value.Dispose();

				this.Fユーザ選択.dicユーザ名テクスチャ.Clear();

				base.Onデバイスリソースの解放();
			}
		}
		protected override void On活性化()
		{
			lock( this )
			{
				this.Fユーザ選択.actパネル.Location = new Point( 525, 179 );
				this.actステージキット.n透明度 = 255;

				// 最初のフェーズはユーザ選択。
				this.eフェーズ = Eフェーズ.ユーザ選択;
			}

		}
		protected override int On進行()
		{
			lock( this )
			{
				// 全フェーズ共通

				this.actドラムの矢印.t進行();


				// フェーズ別

				switch( this.eフェーズ )
				{
					case Eフェーズ.ユーザ選択:
						#region [ *** ]
						//-----------------
						{
							// モックコード。AutoPlay を選択する。
							Global.Users.tユーザを選択する( "AutoPlay" );
							Debug.Assert( Global.Users.SelectedUserIndex != -1 );
							Global.Users.SelectedUser.Songs.SelectedSongIndex = this.F選曲.act曲パネル一覧.n現在の選択曲番号;

							// 選曲フェーズへ。
							this.eフェーズ = Eフェーズ.選曲;
						}
						break;
						//-----------------
						#endregion

					case Eフェーズ.選曲:
						#region [ *** ]
						//-----------------
						{
							if( (int) E進行結果.曲決定 == this.F選曲.act曲パネル一覧.t進行() )
								return (int) E進行結果.曲決定;

							// 入力

							if( Global.Input.Keyboard.bキーが押された( Key.Escape ) )
								return (int) E進行結果.キャンセル;
						}
						break;
						//-----------------
						#endregion
				}

				return (int) E進行結果.継続;
			}
		}
		protected override void On描画前()
		{
			lock( this )
			{
				// フェーズ別

				switch( this.eフェーズ )
				{
					case Eフェーズ.ユーザ選択:
						this.Fユーザ選択.actパネル.t描画前();
						break;

					case Eフェーズ.選曲:
						break;
				}
			}
		}
		protected override void On描画( IntPtr hDevice )
		{
			lock( this )
			{
				// 全フェーズ共通その１

				this.act背景.t描画( hDevice );


				// フェーズ別

				switch( this.eフェーズ )
				{
					case Eフェーズ.ユーザ選択:
						#region [ *** ]
						//-----------------
						{
							this.Fユーザ選択.actパネル.t描画( hDevice );
							int i = 0;
							foreach( var kvp in this.Fユーザ選択.dicユーザ名テクスチャ )
								kvp.Value.t2D描画( hDevice, this.Fユーザ選択.actパネル.Location.X + 64, this.Fユーザ選択.actパネル.Location.Y + 97 + 64 * i++ );
						}
						break;
					//-----------------
						#endregion

					case Eフェーズ.選曲:
						this.F選曲.act曲パネル一覧.t描画( hDevice );
						break;
				}


				// 全フェーズ共通その２

				this.actステージキット.t描画( hDevice );
				this.actドラムキット.t描画( hDevice );
				this.actドラムの矢印.t描画( hDevice );
			}
		}

		private enum Eフェーズ
		{
			選曲,
			ユーザ選択,
			未定義,
		}
		private Eフェーズ eフェーズ = Eフェーズ.未定義;


		// 全フェーズ共通

		private CAct背景 act背景 = null;
		private CActステージキット actステージキット = null;
		private CActドラムキット actドラムキット = null;
		private CActドラムの矢印 actドラムの矢印 = null;


		// SongSelect フェーズ

		private struct ST選曲フェーズ
		{
			public CAct曲パネル一覧 act曲パネル一覧;
		}
		private ST選曲フェーズ F選曲 = new ST選曲フェーズ();
		
		
		// PlayerSelect フェーズ

		private struct STユーザ選択フェーズ
		{
			public CActGUIパネル actパネル;

			public CActGUIボタン act設定ボタン;
			public CActGUI画像 act設定英字ラベル;
	
			public CActGUIボタン act曲管理ボタン;
			public CActGUI画像 act曲管理英字ラベル;
			
			public CActGUIボタン act名前変更ボタン;
			public CActGUI画像 act名前変更英字ラベル;

			public CActGUIボタン act新規作成ボタン;
			public CActGUI画像 act新規作成英字ラベル;

			public CActGUIボタン act削除ボタン;
			public CActGUI画像 act削除英字ラベル;

			public Dictionary<User, CTexture> dicユーザ名テクスチャ;

			public Font fontユーザ名用フォント;
		}
		private STユーザ選択フェーズ Fユーザ選択 = new STユーザ選択フェーズ();
	}
}
