using System;
using System.Collections.Generic;
using PlayerStatus;
using Schedule;
using UnityEngine;
using wf;

namespace MaidStatus.CsvData
{
	public abstract class AbstractClassData : IComparable, IComparable<AbstractClassData>
	{
		public AbstractClassData(string uniqueName, CsvParser basicCsv, CsvParser acquiredConditionCsv, CsvParser bonusCsv, CsvParser experienceCsv)
		{
			Func<CsvParser, int> func = delegate(CsvParser csv)
			{
				int cell_x = (basicCsv != csv) ? 0 : 1;
				for (int j = 1; j < csv.max_cell_y; j++)
				{
					if (csv.IsCellToExistData(cell_x, j))
					{
						if (uniqueName == csv.GetCellAsString(cell_x, j))
						{
							return j;
						}
					}
				}
				Debug.LogError("csv情報が不正です\n[" + uniqueName + "]を見つけられませんでした");
				return -1;
			};
			CsvParser basicCsv2 = basicCsv;
			int i = 0;
			int num = func(basicCsv2);
			this.id = basicCsv2.GetCellAsInteger(i++, num);
			this.uniqueName = basicCsv2.GetCellAsString(i++, num);
			this.drawName = basicCsv2.GetCellAsString(i++, num);
			this.sortId = basicCsv2.GetCellAsInteger(i++, num);
			this.explanatoryText = basicCsv2.GetCellAsString(i++, num);
			num = func(experienceCsv);
			List<int> list = new List<int>();
			i = 1;
			while (experienceCsv.IsCellToExistData(i, num))
			{
				list.Add(experienceCsv.GetCellAsInteger(i, num));
				i++;
			}
			this.experiences = list.ToArray();
			num = func(bonusCsv);
			ParametersPack parametersPack = new ParametersPack();
			this.levelBonuss = new ParametersPack[this.experiences.Length];
			for (i = 1; i <= this.levelBonuss.Length; i++)
			{
				this.levelBonuss[i - 1] = new ParametersPack();
				this.levelBonuss[i - 1].Parse(bonusCsv.GetCellAsString(i, num), ',');
				parametersPack += this.levelBonuss[i - 1];
				this.levelBonuss[i - 1] = new ParametersPack(parametersPack);
			}
			num = func(acquiredConditionCsv);
			this.learnConditions = new AbstractClassData.LearnConditions(acquiredConditionCsv, num, false);
			this.classType = AbstractClassData.ClassType.New;
		}

		public AbstractClassData(string uniqueName, string drawName, CsvParser infoCsv, CsvParser acquiredConditionCsv, CsvParser bonusCsv, CsvParser experienceCsv)
		{
			Func<CsvParser, int> func = delegate(CsvParser csv)
			{
				int cell_x = (infoCsv != csv) ? 0 : 1;
				if (infoCsv == csv && !infoCsv.IsCellToExistData(2, 0))
				{
					cell_x = 0;
				}
				for (int j = 1; j < csv.max_cell_y; j++)
				{
					if (csv.IsCellToExistData(cell_x, j))
					{
						if (uniqueName == csv.GetCellAsString(cell_x, j))
						{
							return j;
						}
					}
				}
				Debug.LogError("csv情報が不正です\n[" + uniqueName + "]を見つけられませんでした");
				return -1;
			};
			CsvParser infoCsv2 = infoCsv;
			int i = 0;
			int num = func(infoCsv2);
			if (!infoCsv2.IsCellToExistData(2, num))
			{
				this.id = num - 1;
				this.uniqueName = infoCsv2.GetCellAsString(i++, num);
				this.drawName = drawName;
			}
			else
			{
				this.id = infoCsv2.GetCellAsInteger(i++, num);
				this.uniqueName = infoCsv2.GetCellAsString(i++, num);
				this.drawName = drawName;
			}
			this.sortId = this.id;
			this.explanatoryText = infoCsv2.GetCellAsString(i++, num);
			num = func(experienceCsv);
			List<int> list = new List<int>();
			i = 1;
			while (experienceCsv.IsCellToExistData(i, num))
			{
				list.Add(experienceCsv.GetCellAsInteger(i, num));
				i++;
			}
			this.experiences = list.ToArray();
			num = func(bonusCsv);
			ParametersPack parametersPack = new ParametersPack();
			this.levelBonuss = new ParametersPack[this.experiences.Length];
			for (i = 1; i <= this.levelBonuss.Length; i++)
			{
				this.levelBonuss[i - 1] = new ParametersPack();
				this.levelBonuss[i - 1].Parse(bonusCsv.GetCellAsString(i, num).Replace("精神力", "精神"), ',');
				parametersPack += this.levelBonuss[i - 1];
				this.levelBonuss[i - 1] = new ParametersPack(parametersPack);
			}
			num = func(acquiredConditionCsv);
			this.learnConditions = new AbstractClassData.LearnConditions(acquiredConditionCsv, num, true);
			this.classType = AbstractClassData.ClassType.Old;
		}

		public int CompareTo(AbstractClassData other)
		{
			return this.sortId.CompareTo(other.sortId);
		}

		public int CompareTo(object other)
		{
			return this.sortId.CompareTo(((AbstractClassData)other).sortId);
		}

		public void SetClassType(AbstractClassData.ClassType classType)
		{
			this.classType = classType;
		}

		public AbstractClassData.ClassType classType { get; private set; }

		protected abstract string termCategoryName { get; }

		public string termName
		{
			get
			{
				return "MaidStatus/" + this.termCategoryName + "/" + this.uniqueName;
			}
		}

		public readonly int id;

		public readonly string uniqueName;

		public readonly int sortId;

		public readonly string drawName;

		public readonly string explanatoryText;

		public readonly int[] experiences;

		public readonly ParametersPack[] levelBonuss;

		public readonly AbstractClassData.LearnConditions learnConditions;

		[Flags]
		public enum ClassType
		{
			Share = 1,
			New = 2,
			Old = 4
		}

		public class LearnConditions
		{
			public LearnConditions(CsvParser acquiredConditionCsv, int lineY, bool readOldCsv)
			{
				this.requestParameters = new ParametersPack();
				this.requestVipFlags = new List<int>();
				this.requestPersonals = new HashSet<int>();
				this.requestSeikeikens = new HashSet<Seikeiken>();
				this.requestContracts = new HashSet<Contract>();
				this.requestBillIds = new HashSet<int>();
				int cell_x = 1;
				if (!readOldCsv)
				{
					string cellAsString = acquiredConditionCsv.GetCellAsString(cell_x++, lineY);
					if (!string.IsNullOrEmpty(cellAsString))
					{
						string[] array = cellAsString.Split(new char[]
						{
							','
						});
						foreach (string text in array)
						{
							int id = Personal.GetData(text.Trim()).id;
							if (!this.requestPersonals.Contains(id))
							{
								this.requestPersonals.Add(id);
							}
						}
					}
					cellAsString = acquiredConditionCsv.GetCellAsString(cell_x++, lineY);
					if (cellAsString == "〇")
					{
						foreach (Personal.Data data in Personal.GetAllDatas(false))
						{
							if (data.oldPersonal && !this.requestPersonals.Contains(data.id))
							{
								this.requestPersonals.Add(data.id);
							}
						}
					}
					cellAsString = acquiredConditionCsv.GetCellAsString(cell_x++, lineY);
					if (!string.IsNullOrEmpty(cellAsString))
					{
						string[] array3 = cellAsString.Split(new char[]
						{
							'|'
						});
						foreach (string value in array3)
						{
							this.requestSeikeikens.Add((Seikeiken)Enum.Parse(typeof(Seikeiken), value));
						}
					}
					cellAsString = acquiredConditionCsv.GetCellAsString(cell_x++, lineY);
					if (!string.IsNullOrEmpty(cellAsString))
					{
						string[] array5 = cellAsString.Split(new char[]
						{
							'|'
						});
						foreach (string value2 in array5)
						{
							this.requestContracts.Add((Contract)Enum.Parse(typeof(Contract), value2));
						}
					}
					cellAsString = acquiredConditionCsv.GetCellAsString(cell_x++, lineY);
					if (!string.IsNullOrEmpty(cellAsString))
					{
						string[] array7 = cellAsString.Split(new char[]
						{
							'|'
						});
						foreach (string s in array7)
						{
							this.requestBillIds.Add(int.Parse(s));
						}
					}
				}
				else
				{
					foreach (Personal.Data data2 in Personal.GetAllDatas(false))
					{
						if (data2.oldPersonal && !this.requestPersonals.Contains(data2.id))
						{
							this.requestPersonals.Add(data2.id);
						}
					}
				}
				while (acquiredConditionCsv.IsCellToExistData(cell_x, lineY))
				{
					string cellAsString2 = acquiredConditionCsv.GetCellAsString(cell_x++, lineY);
					int cellAsInteger = acquiredConditionCsv.GetCellAsInteger(cell_x++, lineY);
					if (cellAsString2 == "VIP")
					{
						if (!readOldCsv)
						{
							this.requestVipFlags.Add(cellAsInteger);
						}
					}
					else
					{
						ParametersPack.StatusType targetStatus = ParametersPack.NameToStatusType(cellAsString2);
						this.requestParameters.Set(targetStatus, cellAsInteger);
					}
				}
			}

			public bool isSpecialConditions()
			{
				return 0 < this.requestSeikeikens.Count || 0 < this.requestContracts.Count;
			}

			public bool CheckSpecialConditions(Status status)
			{
				return (0 >= this.requestSeikeikens.Count || this.requestSeikeikens.Contains(status.seikeiken)) && (0 >= this.requestContracts.Count || this.requestContracts.Contains(status.contract));
			}

			public bool isLearnPossiblePersonal(Personal.Data personalData)
			{
				return this.requestPersonals.Count == 0 || this.requestPersonals.Contains(personalData.id);
			}

			public bool isFutureLearnPossible(Status status)
			{
				return (0 >= this.requestContracts.Count || status.contract == Contract.Trainee || this.requestContracts.Contains(status.contract)) && (0 >= this.requestSeikeikens.Count || this.requestSeikeikens.Contains(status.seikeiken) || (!this.requestSeikeikens.Contains(Seikeiken.Yes_No) && !this.requestSeikeikens.Contains(Seikeiken.No_Yes)) || status.seikeiken == Seikeiken.No_No) && this.isLearnPossiblePersonal(status.personal);
			}

			public bool isLearnPossibleStatus(Status status)
			{
				if (0 < this.requestBillIds.Count)
				{
					bool flag = false;
					if (GameMain.Instance.FacilityMgr != null)
					{
						foreach (int facilityTypeID in this.requestBillIds)
						{
							flag |= GameMain.Instance.FacilityMgr.IsFacilityBuildFlag(facilityTypeID);
						}
					}
					if (!flag)
					{
						return false;
					}
				}
				if (!this.isLearnPossiblePersonal(status.personal) || !this.CheckSpecialConditions(status))
				{
					return false;
				}
				if (!this.requestParameters.GreaterThanOrEqualToStatus(status))
				{
					return false;
				}
				foreach (int key in this.requestVipFlags)
				{
					ReadOnlyDictionary<int, NightWorkState> night_works_state_dic = GameMain.Instance.CharacterMgr.status.night_works_state_dic;
					if (!night_works_state_dic.ContainsKey(key) || !night_works_state_dic[key].finish)
					{
						return false;
					}
				}
				return true;
			}

			public virtual List<KeyValuePair<string, bool>> CreateConditionTextAndStaturResults(Status status)
			{
				List<KeyValuePair<string, bool>> list = new List<KeyValuePair<string, bool>>();
				if (0 < this.requestSeikeikens.Count)
				{
					string text = "性経験 : ";
					bool flag = false;
					foreach (Seikeiken seikeiken in this.requestSeikeikens)
					{
						if (flag)
						{
							text += ",";
						}
						text += EnumConvert.GetString(seikeiken);
						flag = true;
					}
					list.Add(new KeyValuePair<string, bool>(text, this.requestSeikeikens.Contains(status.seikeiken)));
				}
				if (0 < this.requestContracts.Count)
				{
					string text2 = "契約タイプ : ";
					bool flag2 = false;
					foreach (Contract contract in this.requestContracts)
					{
						if (flag2)
						{
							text2 += ",";
						}
						text2 += EnumConvert.GetString(contract);
						flag2 = true;
					}
					list.Add(new KeyValuePair<string, bool>(text2, this.requestContracts.Contains(status.contract)));
				}
				if (0 < this.requestVipFlags.Count)
				{
					string text3 = string.Empty;
					foreach (int num in this.requestVipFlags)
					{
						if (!ScheduleCSVData.AllData.ContainsKey(num) || ScheduleCSVData.AllData[num].type != ScheduleTaskCtrl.TaskType.Yotogi)
						{
							text3 = "不明なVIP[" + num + "]を実行している";
						}
						else
						{
							ScheduleCSVData.ScheduleBase scheduleBase = ScheduleCSVData.AllData[num];
							ScheduleCSVData.Yotogi yotogi = (ScheduleCSVData.Yotogi)scheduleBase;
							text3 = "「" + yotogi.name + "」を実行している";
						}
						if (!string.IsNullOrEmpty(text3))
						{
							ReadOnlyDictionary<int, NightWorkState> night_works_state_dic = GameMain.Instance.CharacterMgr.status.night_works_state_dic;
							bool value = night_works_state_dic.ContainsKey(num) && night_works_state_dic[num].finish;
							list.Add(new KeyValuePair<string, bool>(text3, value));
						}
					}
				}
				List<KeyValuePair<string, bool>> list2 = this.requestParameters.CreateConditionTextAndStaturResults(status);
				foreach (KeyValuePair<string, bool> item in list2)
				{
					list.Add(item);
				}
				return list;
			}

			public readonly ParametersPack requestParameters;

			public readonly List<int> requestVipFlags;

			public readonly HashSet<int> requestPersonals;

			public readonly HashSet<Seikeiken> requestSeikeikens;

			public readonly HashSet<Contract> requestContracts;

			public readonly HashSet<int> requestBillIds;
		}
	}
}
