using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace Nlgp1.Common {
	/// <summary>
	/// ステージを表すクラス
	/// </summary>
	public class StageData {
		/// <summary>
		/// ステージをロードします。
		/// </summary>
		/// <param name="currentDirectory">カレントディレクトリ</param>
		/// <param name="stageNumber">ステージ番号</param>
		/// <returns>ステージ</returns>
		public static StageData Load( string currentDirectory , int stageIndex ) {
			return DataLoader.LoadStageFromFile( Path.Combine( currentDirectory , string.Format( @"Stages\Stage{0}.xml" , stageIndex ) ) , stageIndex );
		}
		/// <summary>
		/// ステージをロードします。
		/// </summary>
		/// <param name="path">ステージへのパス</param>
		/// <returns>ステージ</returns>
		public static StageData Load( string path ) {
			return DataLoader.LoadStageFromFile( path , 0 );
		}
		/// <summary>
		/// ステージをセーブします。
		/// </summary>
		/// <param name="path">ステージへのパス</param>
		public void Save( string path ) {
			DataSaver.SaveStageToFile( path , this );
		}

		public int Index {
			get;
			private set;
		}

		public IEnumerable< LayerData > Layers {
			get {
				return this.LayerTable.Values;
			}
		}
		/// <summary>
		/// レイヤを取得します。
		/// </summary>
		/// <param name="name">レイヤ名</param>
		/// <returns>レイヤ</returns>
		public LayerData GetLayer( string name ) {
			return this.LayerTable[ name ];
		}

		/// <summary>
		/// マップの縦幅を取得します。
		/// </summary>
		public int MapRowCount {
			get {
				return this.Layers.Max( layer => layer.Map.GetLength( 0 ) );
			}
		}
		/// <summary>
		/// マップの横幅を取得します。
		/// </summary>
		public int MapColumnCount {
			get {
				return this.Layers.Max( layer => layer.Map.GetLength( 1 ) );
			}
		}
		/// <summary>
		/// チップ数を取得します。
		/// </summary>
		public int ChipCount {
			get {
				int value = 0;
				foreach( LayerData layer in this.LayerTable.Values ) {
					value += layer.ChipTable.Count;
				}
				return value;
			}
		}

		/// <summary>
		/// レイヤセットを取得します。
		/// </summary>
		public Dictionary< string , LayerData > LayerTable {
			get;
			set;
		}

		/// <summary>
		/// Mapクラスの新しいインスタンスを初期化します。
		/// </summary>
		public StageData( int index ) {
			this.Index = index;
		}

		/// <summary>
		/// BGMへのパスを取得します。
		/// </summary>
		public string BgmPath {
			get;
			set;
		}

		/// <summary>
		/// チップセットを取得します。
		/// </summary>
		/// <param name="name">レイヤ名</param>
		/// <returns>チップセット</returns>
		public IEnumerable< LayerChipData > GetChips( string name ) {
			return LayerTable[ name ].Chips;
		}

		#region マップの取得
		/// <summary>
		/// 指定のレイヤーのチップを参照します。
		/// </summary>
		public LayerChipData[,] GetMap( string name ) {
			return LayerTable[ name ].Map;
		}

		/// <summary>
		/// 背景レイヤーのチップを参照します。
		/// </summary>
		public LayerChipData[,] BackMap {
			get {
				return GetMap( "Back" );
			}
		}
		/// <summary>
		/// 背景(中間)レイヤーのチップを参照します。
		/// </summary>
		public LayerChipData[,] BackMiddleMap {
			get {
				return GetMap( "BackMiddle" );
			}
		}
		/// <summary>
		/// 中間レイヤーのチップを参照します。
		/// </summary>
		public LayerChipData[,] MiddleMap {
			get {
				return GetMap( "Middle" );
			}
		}
		/// <summary>
		/// 中間(前面)レイヤーのチップを参照します。
		/// </summary>
		public LayerChipData[,] MiddleFrontMap {
			get {
				return GetMap( "MiddleFront" );
			}
		}
		/// <summary>
		/// 前面レイヤーのチップを参照します。(地形)
		/// </summary>
		public LayerChipData[,] FrontMap {
			get {
				return GetMap( "Front" );
			}
		}
		/// <summary>
		/// キャラクタマップを参照します。
		/// </summary>
		public LayerChipData[,] CharactersMap {
			get {
				return GetMap( "Characters" );
			}
		}

		#endregion // レイヤーの取得

		public override string ToString() {
			return this.Index.ToString();
		}
	}
}
