using System;
using System.Collections.Generic;
using System.IO;
using Box2DX.Collision;
using Box2DX.Common;
using Box2DX.Dynamics;
using DxLibDLL;
using Nlgp1.Characters;
using Nlgp1.Common;
using Nlgp1.Drawers;
using Nlgp1.Sprites;
using Nlgp1.Utilities;

namespace Nlgp1.Stages {
	/// <summary>
	/// ステージ
	/// </summary>
	public static class Stage {
		/// <summary>
		/// ステージを読み込みます。
		/// </summary>
		/// <param name="stageIndex">ステージ番号</param>
		public static void Load( int stageIndex ) {
			Index = stageIndex;
			StageData stageData = StageData.Load( Program.CurrentDirectory , stageIndex );
			StageDrawer.LoadStage( stageData.ChipCount );
			Sprite.LoadStage( stageData.MapRowCount , stageData.MapColumnCount );

			World = new World( new AABB { LowerBound = new Vec2( 0 , 0 ), UpperBound = new Vec2( stageData.MapColumnCount , stageData.MapRowCount ) * ChipImage.SizeSide } , new Vec2() , false );

			// マップ上にチップを配置する。
			LayerData backLayer = stageData.GetLayer( "Back" );
			for( int y = 0 ; y < System.Math.Min( 2 * StageDrawer.ViewCellCountY , backLayer.Map.GetLength( 0 ) ) ; y++ ) {
				for( int x = 0 ; x < System.Math.Min( 2 * StageDrawer.ViewCellCountX , backLayer.Map.GetLength( 1 ) ) ; x++ ) {
					LayerChipData chipData = backLayer.Map[ y , x ];
					if( chipData.Index > 0 ) {
						SpriteDrawer drawer = SpriteDrawer.Load( new ChipId( LayerType.Back , chipData.Index ) , new Vec2( x , y ) * ChipImage.SizeSide , backLayer.ChipsetImagePath );
					}
				}
			}

			// マップ上にチップを配置する。
			LayerData frontLayer = stageData.GetLayer( "Front" );
			for( int y = 0 ; y < System.Math.Min( 2 * StageDrawer.ViewCellCountY , frontLayer.Map.GetLength( 0 ) ) ; y++ ) {
				for( int x = 0 ; x < System.Math.Min( 2 * StageDrawer.ViewCellCountX , frontLayer.Map.GetLength( 1 ) ) ; x++ ) {
					LayerChipData chipData = frontLayer.Map[ y , x ];
					if( chipData.Index > 0 ) {
						Sprite sprite = SpriteFactory.Load( World ,new ChipId( LayerType.Front , chipData.Index ) , chipData.Friction ,  new Vec2( x , y ) * ChipImage.SizeSide );
						SpriteDrawer drawer = SpriteDrawer.Load( sprite , frontLayer.ChipsetImagePath );
					}
				}
			}

			// マップ上にキャラクタを配置する。
			LayerData charactersLayer = stageData.GetLayer( "Characters" );
			for( int y = 0 ; y < System.Math.Min( 2 * StageDrawer.ViewCellCountY , charactersLayer.Map.GetLength( 0 ) ) ; y++ ) {
			  for( int x = 0 ; x < System.Math.Min( 2 * StageDrawer.ViewCellCountX , charactersLayer.Map.GetLength( 1 ) ) ; x++ ) {
					LayerChipData chipData = charactersLayer.Map[ y , x ];
					if( chipData.Index >= 1 ) {
						Sprite sprite = SpriteFactory.Load( World , new ChipId ( LayerType.Characters , chipData.Index ) , chipData.Friction , new Vec2( x , y ) * ChipImage.SizeSide );
						SpriteDrawer drawer = SpriteDrawer.Load( sprite , "CharacterImages" );
						if( chipData.Index == 1 ) {
							Player = sprite;
							PlayerDrawer = drawer;
						}
					}
				}
			}
		}

		public static void Update( Controller controller ) {
			World.Step( 1 , 8 , 1 );
			foreach ( Sprite sprite in Sprite.GetCollection() ) {
				sprite.Update();
			}
		}

		/// <summary>
		/// 現在のステージ番号を取得します。
		/// </summary>
		public static int Index {
			get;
			private set;
		}

		public static Sprite Player {
			get;
			private set;
		}

		public static SpriteDrawer PlayerDrawer {
			get;
			private set;
		}

		public static World World {
			get;
			private set;
		}
	}
}

