using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nlgp1.StageEditor.Controls;
using Nlgp1.StageEditor.Notifies;
using Nlgp1.StageEditor.Notifies.LayerChipProperties;
using System.IO;
using System.Windows.Forms;
using Nlgp1.Common;

namespace Nlgp1.StageEditor.Notifies {
	public static class NotifySaver {
		public static void SaveStageToFile( string path , StageNotify stageNotify ) {
			var isValid = IsValidStage( stageNotify );
			if( isValid == false )
				return;

			var stageData = new StageData( 0 );

			stageData.LayerTable = new Dictionary< string , LayerData >();
			foreach( var layerNotify in stageNotify.LayerList ) {
				var layerData = new LayerData( layerNotify.Name );
				layerData.ChipsetPath = layerNotify.ChipsetPath;
				layerData.ChipsetImagePath = layerNotify.ChipsetImage.Path;
				layerData.ChipTable = new SortedDictionary< int ,LayerChipData >();
				foreach( var chipNotify in layerNotify.Chips ) {
					var chipData = new LayerChipData( chipNotify.Index );
					chipData.Name = chipNotify.Property.Name;
					chipData.Summary = chipNotify.Property.Summary;
					chipData.Type = chipNotify.Property.Type.ToEnum< LayerChipType >();
					chipData.Friction = chipNotify.Property.Friction;
					layerData.ChipTable.Add( chipData.Index , chipData );
				}
				var mapNotify = layerNotify.Map;
				layerData.Map = new LayerChipData[ mapNotify.GetLength( 0 ) , mapNotify.GetLength( 1 ) ];
				for( int y = 0 ; y < mapNotify.GetLength( 0 ) ; y++ ) {
					for( int x = 0 ; x < mapNotify.GetLength( 1 ) ; x++ ) {
						layerData.Map[ y , x ] = layerData.ChipTable[ mapNotify[ y , x ].Index ];
					}
				}
				stageData.LayerTable.Add( layerData.Name , layerData );
			}

			stageData.Save( path );
			stageNotify.SetPath( path );
		}

		private static bool IsValidStage( StageNotify stage ) {
			var layerNames = Enum.GetNames( typeof( LayerType ) );

			var message = "";

			var layerList = stage.LayerList;
			var layerNum = layerList.Count != layerNames.Length;
			if( layerNum )
				message = "レイヤーの数が不正です";

			var layerImage = layerList.Find( layer =>
				layer.ChipsetImage.Image == null );
			if( layerImage != null )
				message = string.Format( "{0}レイヤーに画像が設定されていません" , layerImage.Name );

			var sameChipFunc = new Action( () => {
				foreach( var layer in layerList )
					foreach( var chip1 in layer.Chips )
						foreach( var chip2 in layer.Chips ) {
							if( chip1 == chip2 )
								continue;
							if( chip1.Property.Name != chip2.Property.Name )
								continue;
							message = string.Format(
								"{0}レイヤーのID:{1},ID:{2}\n" +
								"チップのCodeが同じです" ,
								layer.Name , chip1.Index , chip2.Index );
							return;
						}
			} );
			sameChipFunc();

			if( message != "" ) {
				MessageBox.Show( message , "セーブを実行できません！！" );
				return false;
			}

			return true;
		}
	}
}
