using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using Nlgp1.StageEditor.Notifies.LayerChipProperties;

namespace Nlgp1.StageEditor.Notifies {
	public class LayerNotify : INotifyPropertyChanged {
		public static readonly LayerNotify None = new LayerNotify( 0 , 0 );

		public string ChipsetPath {
			get;
			set;
		}

		public string Name {
			get;
			private set;
		}
		public ChipsetImage ChipsetImage {
			get;
			private set;
		}
		public IEnumerable< LayerChipNotify > Chips {
			get {
				return this.ChipTable.Values;
			}
		}
		public LayerChipNotify[,] Map {
			get;
			private set;
		}

		public SortedDictionary< int , LayerChipNotify > ChipTable {
			get;
			private set;
		}

		public LayerNotify( int row , int column ) {
			if( row > 0 && column > 0 ) {
				this.ChipsetImage = new ChipsetImage();
				this.ChipTable = new SortedDictionary< int , LayerChipNotify >();

				this.Map = new LayerChipNotify[ row , column ];
				for( int i = 0; i < this.Map.GetLength( 0 ); ++i ) {
					for( int j = 0; j < this.Map.GetLength( 1 ); ++j ) {
						this.Map[ i , j ] = LayerChipNotify.None;
					}
				}
			}
			else {
				this.Name = "None";
				this.Map = new LayerChipNotify[ row , column ];
				this.ChipsetImage = ChipsetImage.None;
				this.ChipTable = new SortedDictionary< int , LayerChipNotify >();
			}
		}

		public void SetProperty( string name ) {
			this.Name = name;
			OnPropertyChanged( "SetProperty" );
		}

		public void LoadLayerImage( string path ) {
			this.ChipsetImage.Path = path;
			OnPropertyChanged( "LoadLayerImage" );
		}

		#region チップ操作
		public LayerChipNotify CreateChip() {
			return new LayerChipNotify( ChipTable.Keys.Max() + 1 );
		}

		public void AddChip( LayerChipNotify chip ) {
			this.ChipTable.Add( chip.Index , chip );
			OnPropertyChanged( "AddChipData" );
		}

		public void RemoveChip( LayerChipNotify removedChip ) {
			if( ChipTable.Count <= 1 )
				return;

			if( removedChip == LayerChipNotify.None ) {
				ChipTable.Remove( removedChip.Index );
				OnPropertyChanged( "RemoveChipData" );
				return;
			}


			ChipTable.Remove( removedChip.Index );

			for( int i = 0; i < this.Map.GetLength( 0 ); ++i ) {
				for( int j = 0; j < this.Map.GetLength( 1 ); ++j ) {
					if( this.Map[ i , j ] == removedChip ) {
						this.Map[ i , j ] = this.ChipTable[ 0 ];
					}
				}
			}

			OnPropertyChanged( "RemoveChipData" );
		}

		public LayerChipNotify GetPreviousChip( LayerChipNotify chip ) {
			if( Chips.Contains( chip ) == false )
				return Chips.First();

			var index = chip.Index;
			index = Math.Max( index - 1 , 0 );
			return ChipTable[index];
		}

		public LayerChipNotify GetNextChip( LayerChipNotify chip ) {
			if( Chips.Contains( chip ) == false )
				return Chips.Last();

			var index = chip.Index;
			index = Math.Min( index + 1 , ChipTable.Count - 1 );
			return ChipTable[index];
		}
		#endregion

		#region マップ操作

		public void SetChip( LayerChipNotify chip , int row , int column )
		{
			if( row >= this.Map.GetLength( 0 ) )
				return;
			if( column >= this.Map.GetLength( 1 ) )
				return;

			this.Map[ row , column ] = chip;
			OnPropertyChanged("SetChipIndex");
		}
		public void SetChip(int chipIndex, int row, int column)
		{
			this.SetChip( this.ChipTable[ chipIndex ] , row , column );
		}
		//ID返す
		public int GetChipIndex(int row, int column)
		{
			return this.Map[ row , column ].Index;
		}

		public void SetMap( LayerChipNotify[,] map )
		{
			this.Map = map;
			OnPropertyChanged( "SetGridData" );
		}


		public void ShiftLeft()
		{
			for( int i = 0; i < this.Map.GetLength( 0 ); ++i ) {
				int j = 0;
				LayerChipNotify edgeChip = this.Map[ i , j ];
				for( ; j < this.Map.GetLength( 1 ) - 1; ++j ) {
					this.Map[ i , j ] = this.Map[ i , j + 1 ];
				}
				this.Map[ i , j ] = edgeChip;
			}

			OnPropertyChanged( "Shift" );
		}

		public void ShiftRight()
		{
			for( int i = 0; i < this.Map.GetLength( 0 ); ++i ) {
				int j = this.Map.GetLength( 1 ) - 1;
				LayerChipNotify edgeChip = this.Map[ i , j ];
				for( ; j > 0; --j ) {
					this.Map[ i , j ] = this.Map[ i , j - 1 ];
				}
				this.Map[ i , j ] = edgeChip;
			}

			OnPropertyChanged( "Shift" );
		}

		public void ShiftUp()
		{
			for( int j = 0; j < this.Map.GetLength( 1 ); ++j ) {
				int i = 0;
				LayerChipNotify edgeChip = this.Map[ i , j ];
				for( ; i < this.Map.GetLength( 0 ) - 1; ++i ) {
					this.Map[ i , j ] = this.Map[ i + 1 , j ];
				}
				this.Map[ i , j ] = edgeChip;
			}

			OnPropertyChanged( "Shift" );
		}

		public void ShiftDown()
		{
			for( int j = 0; j < this.Map.GetLength( 1 ); ++j ) {
				int i = this.Map.GetLength( 1 ) - 1;
				LayerChipNotify edgeChip = this.Map[ i , j ];
				for( ; i > 0; --j ) {
					this.Map[ i , j ] = this.Map[ i - 1 , j ];
				}
				this.Map[ i , j ] = edgeChip;
			}

			OnPropertyChanged( "Shift" );
		}

		private List<int> CreateRow( int count , int chipIndex ) {
			var row = new List<int>();
			for( int i = 0 ; i < count ; i++ ) {
				row.Add( chipIndex );
			}
			return row;
		}
		#endregion // グリッド操作

		#region INotifyPropertyChanged メンバ

		public event PropertyChangedEventHandler PropertyChanged;
		public void OnPropertyChanged( string name ) {
			if( PropertyChanged == null )
				return;

			var e = new PropertyChangedEventArgs( name );
			PropertyChanged( this , e );
		}

		#endregion
	}
}
