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

namespace pcd_g1
{
	static class StageManager
	{
		public static Stage AvailableStage { get; private set; }

		public static SaveData CurrentDataSet { get; private set; }

		static string savefname = "";
		public static string SaveFileName
		{
			get
			{
				if (savefname == "")
				{
					savefname = System.Windows.Forms.Application.StartupPath + @"\save.dat";
				}
				return savefname;
			}
			set
			{
				savefname = value;
			}
		}

		public static void Init()
		{
			AvailableStage = null;
			CurrentDataSet = new SaveData();

			string[] param = Environment.GetCommandLineArgs();
			if (param.Length >= 2)
			{
				if (param.Length >= 3 && param[1] == "class")
				{
					continueStg = param[2];
					RunStage(param[2]);
				}
				else
				{
					continueStg = "pcd_g1.FreeStage";
					FreeStage.FileName = param[1];
					RunStage(typeof(FreeStage));
				}
			}
			else
			{
				RunStage(typeof(startMenuStage));
			}
		}

		public static void Clear()
		{
			CurrentDataSet = new SaveData();
		}

		static void Clean()
		{
			CurrentDataSet.Clean();
		}

		static string continueStg = "";
		public static void Continue()
		{
			if (continueStg == "")
			{
				//セーブデータが読み込めないときには
				if (!StageManager.Load())
				{
					//初期ステージから開始
					StageManager.Clear();
					StageManager.RunStage("mori-ie1");
				}

			}
			else
			{
				StageManager.Clear();
				StageManager.RunStage(continueStg);
			}
		}

		static string aiName = "";
		public static void RunStage(string stage, int x = -1, int y = -1, IEffect change = null)
		{
			Clean();

			//StgAi用のストリーム
			//System.IO.Stream stream = null;

			//まずはResourcesからの取得を試みる。
			//try
			//{
			//stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("pcd_g1.Properties.Resources.resources." + stage);
			//}catch(Exception){}
	
			//次にstagesディレクトリからの取得を試みる。
			string aiFileName = System.Windows.Forms.Application.StartupPath + @"\stgs\" + stage + ".stgai";
			if (System.IO.File.Exists(aiFileName))
			{
				AvailableStage = null;
				MainForm.form.Widghets.Clear();

				StgAiStage aiStage = new StgAiStage(aiFileName);

				if (aiStage.MainCharacter != null)
				{
					if (x != -1) aiStage.MainCharacter.X = x;
					if (y != -1) aiStage.MainCharacter.Y = y;
				}

				if (change == null) change = new UniversalTransChangingEffect();
				MainForm.form.Effects.Add(change);
				AvailableStage = aiStage;
				aiName = stage;
				MainForm.form.ResetKey();
			}
			else
			{
				RunStage(Type.GetType(stage), x, y, change);
			}
		}


		public static void RunStage(Type stage, int x = -1, int y = -1, IEffect change = null)
		{
			Clean();
			AvailableStage = null;
			MainForm.form.Widghets.Clear();
			var stg = (Stage) System.Activator.CreateInstance(stage, new object[] { });

			if (!(stg is Stage))
			{
				throw new ApplicationException("不正なステージです");
			}

			if (stg.MainCharacter != null)
			{
				if (x != -1) stg.MainCharacter.X = x;
				if (y != -1) stg.MainCharacter.Y = y;
			}

			if (change == null) change = new UniversalTransChangingEffect();
			MainForm.form.Effects.Add(change);
			AvailableStage = stg;
			MainForm.form.ResetKey();
		}

		public static bool Load()
		{
			if (ExistsSaveData)
			{
				try
				{
					string stg;
					int x, y;
					XDocument doc = XDocument.Load(SaveFileName);
					XElement root = doc.Element("savedata");
					var data = new SaveData();
					stg = root.Element("stage").Value;
					x = int.Parse(root.Element("X").Value);
					y = int.Parse(root.Element("Y").Value);
					data.Deserialize(root.Element("savedata"));
					data.Debug();

					CurrentDataSet = data;
					RunStage(stg, x, y);
					return true;
				}
				catch
				{
				}
			}
			return false;
		}

		public static void Store()
		{
			string stg;
			if (AvailableStage is StgAiStage)
			{
				stg = aiName;
			}
			else
			{
				stg = AvailableStage.GetType().ToString();
			}
			XNamespace ns = "http://iwruhliouoiuhuygfwi9lg.com/oierhgo/"; 
			XElement doc = new XElement("savedata",
				new XElement("stage", stg),
				new XElement("X", AvailableStage.MainCharacter.X.ToString()),
				new XElement("Y", AvailableStage.MainCharacter.Y.ToString()));
			doc.Add(CurrentDataSet.Serialize());
			var xdoc = new XDocument(doc);
			xdoc.Save(SaveFileName);
		}

		public static bool ExistsSaveData
		{
			get
			{
				return System.IO.File.Exists(SaveFileName);
			}
		}
	}
}
