using System;
using System.Collections.Generic;
using MaidStatus;
using UnityEngine;
using wf;

namespace Kasizuki
{
	public static class PlayData
	{
		private static int GetMaidStatus(this Maid maid, string name)
		{
			switch (name)
			{
			case "接待":
				return maid.status.reception;
			case "お世話":
				return maid.status.care;
			case "可憐":
				return maid.status.lovely;
			case "気品":
				return maid.status.elegance;
			case "魅惑":
				return maid.status.charm;
			case "料理":
				return maid.status.cooking;
			case "ボーカル":
				return maid.status.vocal;
			case "ダンス":
				return maid.status.dance;
			case "アピールポイント":
				return maid.status.appealPoint;
			case "淫欲":
				return maid.status.inyoku;
			case "M性":
				return maid.status.mvalue;
			case "変態":
				return maid.status.hentai;
			case "奉仕":
				return maid.status.housi;
			case "指導":
				return maid.status.teachRate;
			case "経験人数":
				return maid.status.sexPlayNumberOfPeople;
			case "人気ランク":
				return maid.status.popularRank;
			case "評価":
				return maid.status.evaluation;
			}
			NDebug.Assert(string.Format("メイドパラメータ名「{0}」は未定義です", name), false);
			return -1;
		}

		public static PlayData.Data GetOptimalConditionData(Maid maid, RoomData.Data roomData, ManDataType manType)
		{
			PlayData.Data result;
			try
			{
				NDebug.Assert(maid != null, "メイドにnullが指定されました");
				NDebug.Assert(roomData != null, "部屋情報にnullが指定されました");
				NDebug.Assert(Enum.IsDefined(typeof(ManDataType), manType), "男種類に不正な値が入りました");
				if (!roomData.enableManTypeDic[manType])
				{
					result = null;
				}
				else
				{
					List<PlayData.Data> playDatas = roomData.GetPlayDatas();
					List<PlayData.Data> list = new List<PlayData.Data>();
					foreach (PlayData.Data data in playDatas)
					{
						if (data.enableManTypeDic[manType])
						{
							if (data.IsCorrectMaid(maid, manType))
							{
								list.Add(data);
							}
						}
					}
					PlayData.Data data2 = null;
					for (int i = 0; i < list.Count; i++)
					{
						if (data2 == null)
						{
							data2 = list[i];
						}
						else if (data2.needLikability < list[i].needLikability)
						{
							data2 = list[i];
						}
					}
					NDebug.Warning(data2 != null, "条件を満たすプレイが一つもない");
					result = data2;
				}
			}
			catch (Exception ex)
			{
				NDebug.Assert(ex.ToString(), false);
				Debug.LogError(ex);
				result = null;
			}
			return result;
		}

		public static int Count
		{
			get
			{
				PlayData.CreateData();
				return PlayData.commonIdManager.idMap.Count;
			}
		}

		public static bool Contains(string name)
		{
			return PlayData.commonIdManager.nameMap.ContainsKey(name);
		}

		public static bool Contains(int id)
		{
			return PlayData.commonIdManager.idMap.ContainsKey(id);
		}

		public static int uniqueNameToId(string uniqueName)
		{
			PlayData.CreateData();
			NDebug.Assert(PlayData.commonIdManager.nameMap.ContainsKey(uniqueName), "傅き.プレイ情報\nユニーク名[" + uniqueName + "]をIDに変換できませんでした");
			return PlayData.commonIdManager.nameMap[uniqueName];
		}

		public static string IdToUniqueName(int id)
		{
			PlayData.CreateData();
			NDebug.Assert(PlayData.commonIdManager.idMap.ContainsKey(id), "傅き.プレイ情報\nID[" + id + "]をユニーク名に変換できませんでした");
			return PlayData.commonIdManager.idMap[id].Key;
		}

		public static PlayData.Data GetData(int id)
		{
			PlayData.CreateData();
			NDebug.Assert(PlayData.basicDatas.ContainsKey(id), "傅き.プレイ情報\nID[" + id + "]のデータは存在しません");
			return PlayData.basicDatas[id];
		}

		public static PlayData.Data GetData(string uniqueName)
		{
			return PlayData.GetData(PlayData.uniqueNameToId(uniqueName));
		}

		public static bool IsEnabled(string uniqueName)
		{
			PlayData.CreateData();
			return PlayData.commonIdManager.enabledIdList.Contains(PlayData.uniqueNameToId(uniqueName));
		}

		public static bool IsEnabled(int id)
		{
			PlayData.CreateData();
			return PlayData.commonIdManager.enabledIdList.Contains(id);
		}

		public static List<PlayData.Data> GetAllDatas(bool onlyEnabled)
		{
			PlayData.CreateData();
			List<PlayData.Data> list = new List<PlayData.Data>();
			foreach (KeyValuePair<int, KeyValuePair<string, string>> keyValuePair in PlayData.commonIdManager.idMap)
			{
				if (!onlyEnabled || PlayData.commonIdManager.enabledIdList.Contains(keyValuePair.Key))
				{
					list.Add(PlayData.basicDatas[keyValuePair.Key]);
				}
			}
			return list;
		}

		public static List<PlayData.Data> GetDatas(Func<PlayData.Data, bool> customCheckFunction)
		{
			PlayData.CreateData();
			List<PlayData.Data> list = new List<PlayData.Data>();
			foreach (KeyValuePair<int, KeyValuePair<string, string>> keyValuePair in PlayData.commonIdManager.idMap)
			{
				PlayData.Data data = PlayData.basicDatas[keyValuePair.Key];
				if (customCheckFunction(data))
				{
					list.Add(data);
				}
			}
			return list;
		}

		public static void CreateData()
		{
			if (PlayData.commonIdManager != null)
			{
				return;
			}
			PlayData.commonIdManager = new CsvCommonIdManager("kasizuki_play", "傅き.プレイ情報", CsvCommonIdManager.Type.IdOnly, null);
			PlayData.basicDatas = new Dictionary<int, PlayData.Data>();
			string[] array = new string[]
			{
				"list"
			};
			KeyValuePair<AFileBase, CsvParser>[] array2 = new KeyValuePair<AFileBase, CsvParser>[array.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				string text = "kasizuki_play_" + array[i] + ".nei";
				AFileBase afileBase = GameUty.FileSystem.FileOpen(text);
				CsvParser csvParser = new CsvParser();
				bool condition = csvParser.Open(afileBase);
				NDebug.Assert(condition, text + "\nopen failed.");
				array2[i] = new KeyValuePair<AFileBase, CsvParser>(afileBase, csvParser);
			}
			foreach (KeyValuePair<int, KeyValuePair<string, string>> keyValuePair in PlayData.commonIdManager.idMap)
			{
				int key = keyValuePair.Key;
				PlayData.Data value = new PlayData.Data(key, array2[0].Value);
				PlayData.basicDatas.Add(key, value);
			}
			foreach (KeyValuePair<AFileBase, CsvParser> keyValuePair2 in array2)
			{
				keyValuePair2.Value.Dispose();
				keyValuePair2.Key.Dispose();
			}
		}

		private const string csvTopCommonName = "kasizuki_play";

		private const string typeNameForErrorLog = "傅き.プレイ情報";

		private static CsvCommonIdManager commonIdManager;

		private static Dictionary<int, PlayData.Data> basicDatas;

		public class Data
		{
			public Data(int uniqueID, CsvParser csv)
			{
				for (int i = 1; i < csv.max_cell_y; i++)
				{
					if (csv.IsCellToExistData(0, i) && csv.GetCellAsInteger(0, i) == uniqueID)
					{
						int cell_x = 1;
						this.ID = uniqueID;
						string cellAsString = csv.GetCellAsString(cell_x++, i);
						this.strScenarioFileName = csv.GetCellAsString(cell_x++, i);
						this.drawName = csv.GetCellAsString(cell_x++, i);
						this.strDescription = csv.GetCellAsString(cell_x++, i);
						List<string> list = new List<string>();
						for (int j = 0; j < 6; j++)
						{
							string cellAsString2 = csv.GetCellAsString(cell_x++, i);
							if (!string.IsNullOrEmpty(cellAsString2))
							{
								list.Add(cellAsString2);
							}
						}
						this.strConditionArray = list.ToArray();
						string cellAsString3 = csv.GetCellAsString(cell_x++, i);
						this.seikeikenEnableDic = new Dictionary<Seikeiken, bool>();
						Seikeiken[] array = new Seikeiken[]
						{
							Seikeiken.No_No,
							Seikeiken.Yes_No,
							Seikeiken.No_Yes,
							Seikeiken.Yes_Yes
						};
						for (int k = 0; k < array.Length; k++)
						{
							string cellAsString4 = csv.GetCellAsString(cell_x++, i);
							if (cellAsString4 == "〇" || cellAsString4 == "○")
							{
								this.seikeikenEnableDic.Add(array[k], true);
							}
						}
						string cellAsString5 = csv.GetCellAsString(cell_x++, i);
						this.needLikability = csv.GetCellAsInteger(cell_x++, i);
						this.workCountEnableDic = new Dictionary<string, bool>();
						SortedDictionary<int, string> dic = WorkCountReplace.GetDic();
						foreach (string key in dic.Values)
						{
							string cellAsString6 = csv.GetCellAsString(cell_x++, i);
							if (cellAsString6 == "〇" || cellAsString6 == "○")
							{
								this.workCountEnableDic.Add(key, true);
							}
						}
						this.relationEnableDic = new Dictionary<Relation, bool>();
						Relation[] array2 = new Relation[]
						{
							Relation.Contact,
							Relation.Trust,
							Relation.Lover
						};
						for (int l = 0; l < array2.Length; l++)
						{
							string cellAsString7 = csv.GetCellAsString(cell_x++, i);
							if (cellAsString7 == "〇" || cellAsString7 == "○")
							{
								this.relationEnableDic.Add(array2[l], true);
							}
						}
						this.SplitParameterBlock(cellAsString3, out this.strNeedParameterArray);
						this.strNeedSkillArray = (string.IsNullOrEmpty(cellAsString5) ? null : cellAsString5.Split(new char[]
						{
							','
						}));
						this.roomID = RoomData.GetData(cellAsString).ID;
						string cellAsString8 = csv.GetCellAsString(cell_x++, i);
						string[] array3 = null;
						if (!string.IsNullOrEmpty(cellAsString8))
						{
							array3 = cellAsString8.Split(new char[]
							{
								','
							});
							for (int m = 0; m < array3.Length; m++)
							{
								array3[m] = array3[m].Trim();
							}
						}
						this.strEnablePersonalArray = array3;
						Dictionary<ManDataType, bool> dictionary = new Dictionary<ManDataType, bool>();
						int num = Enum.GetNames(typeof(ManDataType)).Length;
						for (int n = 0; n < num; n++)
						{
							string cellAsString9 = csv.GetCellAsString(cell_x, 0);
							ManDataType manType = ManData.GetData(cellAsString9).manType;
							dictionary.Add(manType, csv.GetCellAsString(cell_x++, i) == "○");
						}
						this.enableManTypeDic = new ReadOnlyDictionary<ManDataType, bool>(dictionary);
					}
				}
			}

			public bool IsPassed
			{
				get
				{
					string text = Enum.GetName(typeof(SystemDataType), SystemDataType.プレイ実行\uFF3F);
					text += this.ID.ToString();
					bool flag;
					return GameMain.Instance.KasizukiMgr.TryGetSystemData<bool>(text, out flag) && flag;
				}
				set
				{
					string text = Enum.GetName(typeof(SystemDataType), SystemDataType.プレイ実行\uFF3F);
					text += this.ID.ToString();
					GameMain.Instance.KasizukiMgr.SetSystemData<bool>(text, value, false);
				}
			}

			public string GetScenarioFileNameReplace(Maid maid)
			{
				return ScriptManager.ReplacePersonal(maid, this.strScenarioFileName);
			}

			public bool IsCorrectMaid(Maid maid, ManDataType manType)
			{
				return this.IsCorrectLikability(maid, manType) && this.IsCorrectWorkCount(maid) && this.IsCorrectParameter(maid) && this.IsCorrectSkill(maid) && this.IsCorrectSeikeiken(maid) && this.IsCorrectRelation(maid) && this.IsCorrectPersonal(maid);
			}

			public bool IsCorrectParameter(Maid maid)
			{
				if (this.strNeedParameterArray == null)
				{
					return true;
				}
				bool flag = true;
				int num = 0;
				while (num < this.strNeedParameterArray.Length && flag)
				{
					try
					{
						string name = this.strNeedParameterArray[num++];
						string s = this.strNeedParameterArray[num++];
						int maidStatus = maid.GetMaidStatus(name);
						flag &= (maidStatus >= int.Parse(s));
					}
					catch (Exception ex)
					{
						NDebug.Assert(ex.ToString(), false);
						Debug.LogError(ex);
					}
				}
				return flag;
			}

			public bool IsCorrectSkill(Maid maid)
			{
				if (this.strNeedSkillArray == null)
				{
					return true;
				}
				bool flag = true;
				int num = 0;
				while (num < this.strNeedSkillArray.Length && flag)
				{
					try
					{
						flag &= maid.status.yotogiSkill.Contains(int.Parse(this.strNeedSkillArray[num]));
					}
					catch (Exception ex)
					{
						NDebug.Assert(ex.ToString(), false);
						Debug.LogError(ex);
					}
					num++;
				}
				return flag;
			}

			public bool IsCorrectLikability(Maid maid, ManDataType manType)
			{
				int maidLikability = GameMain.Instance.KasizukiMgr.GetMaidLikability(maid, manType);
				return this.needLikability <= maidLikability;
			}

			public bool IsCorrectWorkCount(Maid maid)
			{
				if (this.workCountEnableDic == null || this.workCountEnableDic.Count <= 0)
				{
					return true;
				}
				int maidData = GameMain.Instance.KasizukiMgr.GetMaidData<int>(maid, MaidDataType.仕事回数, true);
				string workCountName = WorkCountReplace.GetWorkCountName(maidData);
				return this.workCountEnableDic.ContainsKey(workCountName);
			}

			public bool IsCorrectSeikeiken(Maid maid)
			{
				Seikeiken seikeiken = maid.status.seikeiken;
				return this.seikeikenEnableDic.ContainsKey(seikeiken);
			}

			public bool IsCorrectRelation(Maid maid)
			{
				if (this.relationEnableDic == null || this.relationEnableDic.Count <= 0)
				{
					return true;
				}
				Relation relation = maid.status.relation;
				return this.relationEnableDic.ContainsKey(relation);
			}

			public bool IsCorrectPersonal(Maid maid)
			{
				if (this.strEnablePersonalArray == null || this.strEnablePersonalArray.Length <= 0)
				{
					return true;
				}
				for (int i = 0; i < this.strEnablePersonalArray.Length; i++)
				{
					if (maid.status.personal.uniqueName == this.strEnablePersonalArray[i])
					{
						return true;
					}
				}
				return false;
			}

			public List<Maid> GetFilteringPlayDataMaidArray(ManDataType manType)
			{
				CharacterMgr characterMgr = GameMain.Instance.CharacterMgr;
				List<Maid> list = new List<Maid>();
				for (int i = 0; i < characterMgr.GetStockMaidCount(); i++)
				{
					Maid stockMaid = characterMgr.GetStockMaid(i);
					if (!(stockMaid == null))
					{
						if (stockMaid.status.heroineType != HeroineType.Transfer)
						{
							if (stockMaid.status.heroineType != HeroineType.Sub)
							{
								if (this.IsCorrectMaid(stockMaid, manType))
								{
									list.Add(stockMaid);
								}
							}
						}
					}
				}
				return list;
			}

			private void SplitParameterBlock(string strParameterBlock, out string[] output)
			{
				if (string.IsNullOrEmpty(strParameterBlock))
				{
					output = null;
					return;
				}
				string[] array = strParameterBlock.Split(new char[]
				{
					','
				});
				output = new string[array.Length * 2];
				for (int i = 0; i < array.Length; i++)
				{
					string[] array2 = array[i].Split(new char[]
					{
						'|'
					});
					NDebug.Assert(array2.Length == 2, string.Format("kasizukiDataTable.PlayData\n表データの「必要パラメータ条件式」の数が不正です\n{0}", array[i]));
					output[i * 2] = array2[0];
					output[i * 2 + 1] = array2[1];
				}
			}

			private const int CONDITION_COUNT = 6;

			public readonly int ID;

			public readonly int roomID;

			public readonly string strScenarioFileName;

			public readonly string drawName;

			public readonly string strDescription;

			public readonly string[] strConditionArray;

			public readonly Dictionary<Seikeiken, bool> seikeikenEnableDic;

			public readonly string[] strNeedParameterArray;

			public readonly string[] strNeedSkillArray;

			public readonly int needLikability;

			public readonly Dictionary<string, bool> workCountEnableDic;

			public readonly Dictionary<Relation, bool> relationEnableDic;

			public readonly string[] strEnablePersonalArray;

			public readonly ReadOnlyDictionary<ManDataType, bool> enableManTypeDic;
		}
	}
}
