using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using FacilityFlag;
using MaidStatus;
using PlayerStatus;
using UnityEngine;

namespace Kasizuki
{
	public class KasizukiManager : MonoBehaviour
	{
		public int NowOriginSaveDataNumber
		{
			get
			{
				return this.m_NowOriginSaveDataNumber;
			}
			set
			{
				this.m_NowOriginSaveDataNumber = value;
			}
		}

		public int NowSaveDataIndex
		{
			get
			{
				return this.m_NowKasizukiSaveDataIndex;
			}
		}

		public int LatestSaveDataNumber
		{
			get
			{
				return this.m_LatestSaveDataNumber;
			}
		}

		public DataArray<string, string> systemData
		{
			get
			{
				return this.m_SystemData;
			}
		}

		public Dictionary<string, DataArray<string, string>> maidDataArray
		{
			get
			{
				return this.m_MaidDataArray;
			}
		}

		private void Awake()
		{
		}

		public void Init()
		{
			this.ResetData();
			if (this.m_SaveDataArray != null)
			{
				this.m_SaveDataArray.Clear();
				this.m_SaveDataArray = null;
			}
			this.m_SaveDataArray = new Dictionary<int, KasizukiManager.SaveData>();
		}

		public void UnInit()
		{
			if (this.m_NowHaveItemDic != null)
			{
				this.m_NowHaveItemDic.Clear();
				this.m_NowHaveItemDic = null;
			}
			this.m_SystemData = null;
			if (this.m_MaidDataArray != null)
			{
				this.m_MaidDataArray.Clear();
				this.m_MaidDataArray = null;
			}
		}

		private void ResetData()
		{
			if (this.m_NowHaveItemDic != null)
			{
				this.m_NowHaveItemDic.Clear();
			}
			else
			{
				this.m_NowHaveItemDic = new DataArray<int, bool>();
			}
			if (this.m_SystemData != null)
			{
				this.m_SystemData.Clear();
			}
			else
			{
				this.m_SystemData = new DataArray<string, string>();
			}
			if (this.m_MaidDataArray != null)
			{
				this.m_MaidDataArray.Clear();
			}
			else
			{
				this.m_MaidDataArray = new Dictionary<string, DataArray<string, string>>();
			}
			this.SetNowManType(ManDataType.主人公);
		}

		public void CreateNewData()
		{
			this.ResetData();
		}

		public bool IsMeetConditions(string comparisonFlagName, string comparisonOperator, string comparisonValue, bool isEnableWarning = true)
		{
			if (string.IsNullOrEmpty(comparisonOperator))
			{
				NDebug.Assert("KasizukiManager.IsMeetConditions(string[])\n比較演算子が空文字でした", false);
				Debug.LogError("KasizukiManager.IsMeetConditions(string[])\n比較演算子が空文字でした");
			}
			if (string.IsNullOrEmpty(comparisonFlagName))
			{
				NDebug.Assert("KasizukiManager.IsMeetConditions(string[])\n比較するフラグ名が空文字でした", false);
				Debug.LogError("KasizukiManager.IsMeetConditions(string[])\n比較するフラグ名が空文字でした");
			}
			if (string.IsNullOrEmpty(comparisonValue))
			{
				NDebug.Assert("KasizukiManager.IsMeetConditions(string[])\n比較する値が空文字でした", false);
				Debug.LogError("KasizukiManager.IsMeetConditions(string[])\n比較する値が空文字でした");
			}
			string text;
			if (!this.TryGetSystemData<string>(comparisonFlagName, out text))
			{
				if (isEnableWarning)
				{
					NDebug.Warning(string.Format("KasizukiManager.IsMeetConditions(string[])\nフラグ[{0}]は存在しませんでした。", comparisonFlagName));
					Debug.LogWarning(string.Format("KasizukiManager.IsMeetConditions(string[])\nフラグ[{0}]は存在しませんでした。", comparisonFlagName));
				}
				return false;
			}
			if (comparisonOperator != null)
			{
				if (comparisonOperator == "<")
				{
					int num;
					NDebug.Assert(int.TryParse(text, out num), string.Format("KasizukiManager.IsMeetConditions(string[])\nフラグ[{0}]の値は数値に変換できません", comparisonFlagName));
					int num2;
					NDebug.Assert(int.TryParse(comparisonValue, out num2), string.Format("KasizukiManager.IsMeetConditions(string[])\n文字列[{0}]は数値に変換できません", comparisonValue));
					return num < num2;
				}
				if (comparisonOperator == ">")
				{
					int num;
					NDebug.Assert(int.TryParse(text, out num), string.Format("KasizukiManager.IsMeetConditions(string[])\nフラグ[{0}]の値は数値に変換できません", comparisonFlagName));
					int num2;
					NDebug.Assert(int.TryParse(comparisonValue, out num2), string.Format("KasizukiManager.IsMeetConditions(string[])\n文字列[{0}]は数値に変換できません", comparisonValue));
					return num > num2;
				}
				if (comparisonOperator == "<=")
				{
					int num;
					NDebug.Assert(int.TryParse(text, out num), string.Format("KasizukiManager.IsMeetConditions(string[])\nフラグ[{0}]の値は数値に変換できません", comparisonFlagName));
					int num2;
					NDebug.Assert(int.TryParse(comparisonValue, out num2), string.Format("KasizukiManager.IsMeetConditions(string[])\n文字列[{0}]は数値に変換できません", comparisonValue));
					return num <= num2;
				}
				if (comparisonOperator == ">=")
				{
					int num;
					NDebug.Assert(int.TryParse(text, out num), string.Format("KasizukiManager.IsMeetConditions(string[])\nフラグ[{0}]の値は数値に変換できません", comparisonFlagName));
					int num2;
					NDebug.Assert(int.TryParse(comparisonValue, out num2), string.Format("KasizukiManager.IsMeetConditions(string[])\n文字列[{0}]は数値に変換できません", comparisonValue));
					return num >= num2;
				}
				if (comparisonOperator == "=")
				{
					return text.CompareTo(comparisonValue) == 0;
				}
				if (comparisonOperator == "!")
				{
					return text.CompareTo(comparisonValue) != 0;
				}
			}
			NDebug.Assert(string.Format("KasizukiManager.IsMeetConditions(string[])\n比較演算子に不正な文字列が指定されました\n受け取った比較演算子：{0}", comparisonOperator), false);
			return false;
		}

		public bool IsMeetConditions(string[] str)
		{
			if (str.Length != 3)
			{
				NDebug.Assert("KasizukiManager.IsMeetConditions(string[])\n引数の数が正しくありません。", false);
				Debug.LogErrorFormat("KasizukiManager.IsMeetConditions(string[])\n渡された引数の数：{0}", new object[]
				{
					str.Length
				});
				return false;
			}
			return this.IsMeetConditions(str[0], str[1], str[2], true);
		}

		private void UpdateData<T>(DataArray<string, string> dataArray, string valueName, T value, bool enableWarningEmptyData = true)
		{
			if (dataArray == null)
			{
				NDebug.Assert("データ配列にnullが指定されました", false);
				return;
			}
			string value2 = value.ToString();
			if (!dataArray.Contains(valueName))
			{
				if (enableWarningEmptyData)
				{
					NDebug.Warning(string.Format("データ配列には「{0}」が登録されていません。", valueName));
					return;
				}
				dataArray.Add(valueName, value2, false);
			}
			else
			{
				dataArray.Add(valueName, value2, true);
			}
		}

		private T GetData<T>(DataArray<string, string> dataArray, string valueName, bool enableWarningEmptyData = true)
		{
			if (dataArray == null)
			{
				NDebug.Assert("データ配列にnullが指定されました", false);
				return default(T);
			}
			string text = dataArray.Get(valueName, false);
			if (text == null)
			{
				if (enableWarningEmptyData)
				{
					Debug.LogWarning(string.Format("データ配列には「{0}」が登録されていません。", valueName));
				}
				return default(T);
			}
			Type typeFromHandle = typeof(T);
			TypeConverter converter = TypeDescriptor.GetConverter(typeFromHandle);
			T result = default(T);
			try
			{
				if (converter != null)
				{
					result = (T)((object)converter.ConvertFromString(text));
				}
			}
			catch (Exception ex)
			{
				string message = string.Concat(new string[]
				{
					"データの変換に失敗しました\n値： ",
					text,
					"\nを ",
					typeFromHandle.Name,
					" への変換に失敗しました。"
				});
				NDebug.Warning(message);
				Debug.LogWarning(message);
			}
			return result;
		}

		private bool TryGetData<T>(DataArray<string, string> dataArray, string valueName, out T value)
		{
			value = default(T);
			if (dataArray == null)
			{
				NDebug.Assert("データ配列にnullが指定されました", false);
				Debug.LogError("データ配列にnullが指定されました");
				return false;
			}
			string text = dataArray.Get(valueName, false);
			if (text == null)
			{
				return false;
			}
			Type typeFromHandle = typeof(T);
			TypeConverter converter = TypeDescriptor.GetConverter(typeFromHandle);
			try
			{
				if (converter != null)
				{
					value = (T)((object)converter.ConvertFromString(text));
				}
			}
			catch (Exception ex)
			{
				string message = string.Concat(new string[]
				{
					"データの変換に失敗しました\n値： ",
					text,
					"\nを ",
					typeFromHandle.Name,
					" への変換に失敗しました。"
				});
				NDebug.Warning(message);
				Debug.LogWarning(message);
			}
			return true;
		}

		private bool RemoveData(DataArray<string, string> dataArray, string valueName, bool enableWarningEmptyData = true)
		{
			if (dataArray == null)
			{
				NDebug.Assert("データ配列にnullが指定されました", false);
				return false;
			}
			bool flag = dataArray.Remove(valueName, enableWarningEmptyData);
			if (!flag && enableWarningEmptyData)
			{
				NDebug.Warning(string.Format("データ配列には「{0}」が登録されていません。", valueName));
			}
			return flag;
		}

		public void SetSystemData<T>(string valueName, T value, bool isEnableDebugLog = false)
		{
			this.UpdateData<T>(this.m_SystemData, valueName, value, false);
			if (isEnableDebugLog)
			{
				Debug.LogFormat("傅きモードのシステムの情報を更新しました。\nデータ名：{0}\u3000\u3000値：{1}", new object[]
				{
					valueName,
					value.ToString()
				});
			}
		}

		public void SetSystemData<T>(SystemDataType dataType, T value, bool isEnableDebugLog = false)
		{
			string name = Enum.GetName(typeof(SystemDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			this.SetSystemData<T>(name, value, isEnableDebugLog);
		}

		public T GetSystemData<T>(string valueName)
		{
			return this.GetData<T>(this.m_SystemData, valueName, false);
		}

		public T GetSystemData<T>(SystemDataType dataType)
		{
			string name = Enum.GetName(typeof(SystemDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			return this.GetSystemData<T>(name);
		}

		public bool TryGetSystemData<T>(string valueName, out T value)
		{
			return this.TryGetData<T>(this.m_SystemData, valueName, out value);
		}

		public bool TryGetSystemData<T>(SystemDataType dataType, out T value)
		{
			string name = Enum.GetName(typeof(SystemDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			return this.TryGetSystemData<T>(name, out value);
		}

		public Maid GetMan()
		{
			return GameMain.Instance.CharacterMgr.GetMan(0);
		}

		public int GetNowManType()
		{
			return this.GetSystemData<int>(SystemDataType.男種類);
		}

		public void SetNowManType(int manTypeID)
		{
			ManData.Data data = ManData.GetData(manTypeID);
			if (ManData.IsEnabled(manTypeID))
			{
				this.SetSystemData<int>(SystemDataType.男種類, manTypeID, false);
			}
			else
			{
				NDebug.Assert("男の種類に正しくない値が入りました", false);
			}
		}

		public void SetNowManType(ManDataType manType)
		{
			this.SetNowManType((int)manType);
		}

		public void SetManModel(Maid target, ManDataType type)
		{
			if (type == ManDataType.主人公)
			{
				this.UpdateManModelToPlayerData(target);
			}
			else
			{
				ManData.Data data = ManData.GetData((int)type);
				CharacterMgr.NpcData npcData = CharacterMgr.npcDatas[data.modelResourceName];
				npcData.Apply(target, false);
				GameMain.Instance.CharacterMgr.status.playerName = npcData.firstName;
			}
		}

		public void UpdateManModel(Maid target, Action callback)
		{
			target.Visible = true;
			target.AllProcProp();
			target.body0.SetChinkoVisible(false);
			target.CrossFade("man_porse01.anm", false, true, false, 0f, 1f);
			base.StartCoroutine(this.CoroutineWaitPropSeq(target, callback));
		}

		private void UpdateManModelToPlayerData(Maid target)
		{
			if (this.m_CachedOriginPlayerDataDic == null)
			{
				Debug.LogWarning("プレイヤーの情報は未だキャッシュされていない");
				return;
			}
			Maid man = GameMain.Instance.CharacterMgr.GetMan(0);
			PlayerStatus.Status status = GameMain.Instance.CharacterMgr.status;
			target.status.lastName = this.m_CachedOriginPlayerName;
			status.playerName = this.m_CachedOriginPlayerName;
			for (int i = 0; i < 99; i++)
			{
				MPN mpn = (MPN)i;
				if (mpn != MPN.null_mpn)
				{
					target.SetProp(mpn, this.m_CachedOriginPlayerDataDic[mpn].strFileName, this.m_CachedOriginPlayerDataDic[mpn].nFileNameRID, false, false);
					target.SetProp(mpn, this.m_CachedOriginPlayerDataDic[mpn].value, false);
				}
			}
			target.ManColor = this.m_CachedOriginPlayerColor;
			target.ManColorUpdate();
		}

		public void CacheOriginPlayerData()
		{
			this.m_CachedOriginPlayerDataDic = new Dictionary<MPN, MaidProp>();
			Maid man = GameMain.Instance.CharacterMgr.GetMan(0);
			for (int i = 0; i < 99; i++)
			{
				MPN mpn = (MPN)i;
				MaidProp maidProp = new MaidProp();
				MaidProp prop = man.GetProp(mpn);
				maidProp.strFileName = prop.strFileName;
				maidProp.nFileNameRID = prop.nFileNameRID;
				maidProp.value = prop.value;
				this.m_CachedOriginPlayerDataDic.Add(mpn, maidProp);
			}
			this.m_CachedOriginPlayerName = GameMain.Instance.CharacterMgr.status.playerName;
			this.m_CachedOriginPlayerColor = man.ManColor;
		}

		public void ClearCacheOriginPlayerData()
		{
			if (this.m_CachedOriginPlayerDataDic != null)
			{
				this.m_CachedOriginPlayerDataDic.Clear();
				this.m_CachedOriginPlayerDataDic = null;
			}
			this.m_CachedOriginPlayerName = string.Empty;
		}

		private IEnumerator CoroutineWaitPropSeq(Maid target, Action callback)
		{
			while (target.IsBusy)
			{
				yield return null;
			}
			if (callback != null)
			{
				callback();
			}
			yield break;
		}

		private DataArray<string, string> GetMaidDataArray(Maid maid)
		{
			if (maid == null)
			{
				NDebug.Assert("メイドにnullが指定されました", false);
				return null;
			}
			string guid = maid.status.guid;
			DataArray<string, string> result = null;
			if (this.m_MaidDataArray.ContainsKey(guid))
			{
				result = this.m_MaidDataArray[guid];
			}
			return result;
		}

		private DataArray<string, string> CreateMaidDataArray(Maid maid)
		{
			if (maid == null)
			{
				NDebug.Assert("メイドにnullが指定されました", false);
				return null;
			}
			string guid = maid.status.guid;
			if (this.m_MaidDataArray.ContainsKey(guid))
			{
				Debug.LogFormat("メイド「{0}」のデータ配列は既に作成されています。", new object[]
				{
					maid.status.fullNameJpStyle
				});
				return this.m_MaidDataArray[guid];
			}
			DataArray<string, string> dataArray = new DataArray<string, string>();
			this.m_MaidDataArray.Add(guid, dataArray);
			return dataArray;
		}

		public void SetMaidData<T>(Maid maid, string valueName, T value, bool enableWarning = false)
		{
			DataArray<string, string> dataArray = this.GetMaidDataArray(maid);
			if (dataArray == null)
			{
				dataArray = this.CreateMaidDataArray(maid);
			}
			if (valueName == Enum.GetName(typeof(MaidDataType), MaidDataType.好感度\uFF3F本編))
			{
				if (enableWarning)
				{
					NDebug.Warning(string.Format("本編用メイドデータ「{0}」を書き換えようとしました", valueName));
					Debug.LogWarning(string.Format("本編用メイドデータ「{0}」を書き換えようとしました", valueName));
				}
				return;
			}
			this.UpdateData<T>(dataArray, valueName, value, enableWarning);
		}

		public void SetMaidData<T>(Maid maid, MaidDataType dataType, T value, bool enableWarning = false)
		{
			string name = Enum.GetName(typeof(MaidDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			this.SetMaidData<T>(maid, name, value, enableWarning);
		}

		public T GetMaidData<T>(Maid maid, string valueName, bool enableWarning = true)
		{
			if (valueName == Enum.GetName(typeof(MaidDataType), MaidDataType.好感度\uFF3F本編))
			{
				try
				{
					T result = default(T);
					string text = maid.status.likability.ToString();
					TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
					if (converter != null)
					{
						result = (T)((object)converter.ConvertFromString(text));
					}
					return result;
				}
				catch (Exception ex)
				{
					NDebug.Assert(ex.ToString(), false);
					Debug.LogError(ex);
				}
			}
			DataArray<string, string> maidDataArray = this.GetMaidDataArray(maid);
			if (maidDataArray == null)
			{
				Debug.LogFormat("メイド「{0}」の傅きモード用データ配列は未作成でした", new object[]
				{
					maid.status.fullNameJpStyle
				});
				return default(T);
			}
			return this.GetData<T>(maidDataArray, valueName, enableWarning);
		}

		public T GetMaidData<T>(Maid maid, MaidDataType dataType, bool enableWarning = true)
		{
			string name = Enum.GetName(typeof(MaidDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			return this.GetMaidData<T>(maid, name, enableWarning);
		}

		public int GetMaidLikability(Maid maid, ManDataType dataType)
		{
			if (dataType == ManDataType.主人公)
			{
				return this.GetMaidData<int>(maid, MaidDataType.好感度\uFF3F本編, false);
			}
			if (dataType == ManDataType.傅き男１)
			{
				return this.GetMaidData<int>(maid, MaidDataType.好感度\uFF3F傅き男１, false);
			}
			if (dataType == ManDataType.傅き男２)
			{
				return this.GetMaidData<int>(maid, MaidDataType.好感度\uFF3F傅き男２, false);
			}
			if (dataType == ManDataType.傅き男３)
			{
				return this.GetMaidData<int>(maid, MaidDataType.好感度\uFF3F傅き男３, false);
			}
			if (dataType == ManDataType.傅き男４)
			{
				return this.GetMaidData<int>(maid, MaidDataType.好感度\uFF3F傅き男４, false);
			}
			if (dataType != ManDataType.傅き男５)
			{
				NDebug.Assert("[KasizukiManager.GetMaidLikability] 男種類に不正な値が入りました", false);
				Debug.LogErrorFormat("[KasizukiManager.GetMaidLikability] 男種類に不正な値が入りました\n男種類.{0}", new object[]
				{
					dataType.ToString()
				});
				return -1;
			}
			return this.GetMaidData<int>(maid, MaidDataType.好感度\uFF3F傅き男５, false);
		}

		public bool TryGetMaidData<T>(Maid maid, string valueName, out T value)
		{
			value = default(T);
			DataArray<string, string> maidDataArray = this.GetMaidDataArray(maid);
			return maidDataArray != null && this.TryGetData<T>(maidDataArray, valueName, out value);
		}

		public bool TryGetMaidData<T>(Maid maid, MaidDataType dataType, out T value)
		{
			string name = Enum.GetName(typeof(MaidDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			return this.TryGetMaidData<T>(maid, name, out value);
		}

		public bool RemoveMaidData(Maid maid, string valueName, bool enableWarning = false)
		{
			DataArray<string, string> maidDataArray = this.GetMaidDataArray(maid);
			if (maidDataArray == null)
			{
				Debug.LogFormat("メイド「{0}」に関する傅きモードのデータ配列は未作成でした\nデータ名：{1}", new object[]
				{
					maid.status.fullNameJpStyle,
					valueName
				});
				return false;
			}
			return this.RemoveData(maidDataArray, valueName, enableWarning);
		}

		public bool RemoveMaidData(Maid maid, MaidDataType dataType, bool enableWarning = false)
		{
			string name = Enum.GetName(typeof(MaidDataType), dataType);
			if (string.IsNullOrEmpty(name))
			{
				NDebug.Assert("データ型に不正な値が入りました", false);
				Debug.LogError("データ型に不正な値が入りました");
			}
			return this.RemoveMaidData(maid, name, enableWarning);
		}

		public static List<Maid> GetEnableMaidList()
		{
			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.status.heroineType != HeroineType.Transfer)
				{
					if (stockMaid.status.heroineType != HeroineType.Sub)
					{
						list.Add(stockMaid);
					}
				}
			}
			return list;
		}

		public void UpdateLatestSaveDataNumber()
		{
			int count = this.m_SaveDataArray.Count;
			List<KasizukiManager.SaveData> list = new List<KasizukiManager.SaveData>(this.m_SaveDataArray.Values);
			int latestSaveDataNumber = -1;
			long num = -1L;
			for (int i = 0; i < count; i++)
			{
				KasizukiManager.SaveData saveData = list[i];
				if (saveData != null && saveData.header != null)
				{
					long num2 = 0L;
					if (long.TryParse(saveData.header.strRealTime, out num2))
					{
						if (num < num2)
						{
							num = num2;
							latestSaveDataNumber = saveData.header.saveDataNumber;
						}
					}
				}
			}
			this.m_LatestSaveDataNumber = latestSaveDataNumber;
		}

		public void SerializeLocal(int saveDataIndex)
		{
			this.m_NowKasizukiSaveDataIndex = saveDataIndex;
			KasizukiManager.SaveData saveData;
			if (this.m_SaveDataArray.ContainsKey(saveDataIndex))
			{
				saveData = this.m_SaveDataArray[saveDataIndex];
			}
			else
			{
				saveData = new KasizukiManager.SaveData();
				this.m_SaveDataArray.Add(saveDataIndex, saveData);
			}
			saveData.header.saveDataNumber = saveDataIndex;
			saveData.header.saveDataVersion = 5;
			saveData.header.UpdateNowTime();
			saveData.header.lastManType = this.GetNowManType();
			saveData.header.playCount = this.GetSystemData<int>(SystemDataType.プレイ回数);
			this.SerializeSaveData(saveData);
			this.UpdateLatestSaveDataNumber();
		}

		public void DeserializeLocal(int saveDataIndex)
		{
			this.m_NowKasizukiSaveDataIndex = saveDataIndex;
			if (!this.m_SaveDataArray.ContainsKey(saveDataIndex))
			{
				Debug.LogWarning(string.Format("傅きモードのセーブデータ[{0}]番は存在しません", saveDataIndex));
				return;
			}
			KasizukiManager.SaveData saveData = this.m_SaveDataArray[saveDataIndex];
			this.ResetData();
			this.DeserializeSaveData(saveData);
		}

		public void DeleteSaveDataLocal(int saveDataIndex)
		{
			if (!this.m_SaveDataArray.ContainsKey(saveDataIndex))
			{
				return;
			}
			this.m_SaveDataArray.Remove(saveDataIndex);
			this.UpdateLatestSaveDataNumber();
		}

		public KasizukiManager.SaveDataHeader GetSaveDataHeader(int saveDataIndex)
		{
			KasizukiManager.SaveDataHeader result;
			this.TryGetSaveDataHeader(saveDataIndex, out result);
			return result;
		}

		public bool TryGetSaveDataHeader(int saveDataIndex, out KasizukiManager.SaveDataHeader header)
		{
			header = null;
			if (this.m_SaveDataArray.ContainsKey(saveDataIndex))
			{
				header = this.m_SaveDataArray[saveDataIndex].header;
				return true;
			}
			return false;
		}

		public bool IsExistSaveData(int saveDataIndex)
		{
			return this.m_SaveDataArray.ContainsKey(saveDataIndex);
		}

		public void Serialize(BinaryWriter bw)
		{
			bw.Write("COM3D2_KASIZUKI");
			bw.Write(1170);
			this.SerializeOriginHeader(bw);
			foreach (KeyValuePair<int, KasizukiManager.SaveData> keyValuePair in this.m_SaveDataArray)
			{
				int key = keyValuePair.Key;
				KasizukiManager.SaveData value = keyValuePair.Value;
				value.Serialize(bw.BaseStream);
			}
			this.UpdateLatestSaveDataNumber();
			KasizukiManager.FixMaidThumbnails();
		}

		public void Deserialize(int originSaveDataNumber, BinaryReader br)
		{
			this.NowOriginSaveDataNumber = originSaveDataNumber;
			KasizukiManager.DeleteTmpMaidThumnails();
			long position = br.BaseStream.Position;
			if (br.BaseStream.Length <= position + 1L)
			{
				Debug.LogWarning(string.Format("これ以上バッファが無いので、処理を終了します\n現在位置：{0}\n長さ：{1}", position, br.BaseStream.Length));
				return;
			}
			string text = br.ReadString();
			if (text != "COM3D2_KASIZUKI")
			{
				NDebug.Warning(string.Format("傅きモードのヘッダー取得に失敗しました\n取得した文字：{0}\n読み込み位置を戻します", text));
				Debug.LogWarning(string.Format("傅きモードのヘッダー取得に失敗しました\n取得した文字：{0}\n読み込み位置を戻します", text));
				br.BaseStream.Seek(position, SeekOrigin.Begin);
				return;
			}
			int num = br.ReadInt32();
			int num2;
			this.DeserializeOriginHeader(br, out num2);
			this.m_SaveDataArray.Clear();
			for (int i = 0; i < num2; i++)
			{
				KasizukiManager.SaveData saveData = new KasizukiManager.SaveData();
				if (!saveData.Deserialize(br.BaseStream))
				{
					break;
				}
				if (!this.m_SaveDataArray.ContainsKey(saveData.header.saveDataNumber))
				{
					this.m_SaveDataArray.Add(saveData.header.saveDataNumber, saveData);
				}
				else
				{
					this.m_SaveDataArray[saveData.header.saveDataNumber] = saveData;
				}
			}
			this.UpdateLatestSaveDataNumber();
			Debug.Log("プレイヤーの元情報をキャッシュします");
			this.CacheOriginPlayerData();
		}

		private void SerializeOriginHeader(BinaryWriter bw)
		{
			int count = this.m_SaveDataArray.Count;
			byte[] buffer = Util.CreatePrefix(count);
			bw.Write(buffer);
		}

		private void DeserializeOriginHeader(BinaryReader br, out int saveDataCount)
		{
			int prefix = Util.GetPrefix(br.BaseStream, br.BaseStream.Position, true);
			saveDataCount = prefix;
		}

		private void SerializeSaveData(KasizukiManager.SaveData saveData)
		{
			using (MemoryStream memoryStream = new MemoryStream())
			{
				using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
				{
					DataArray<string, string> systemData = this.m_SystemData;
					BinaryWriter brWrite = binaryWriter;
					if (KasizukiManager.<>f__mg$cache0 == null)
					{
						KasizukiManager.<>f__mg$cache0 = new Converter<string, byte[]>(Util.GetBytes);
					}
					Converter<string, byte[]> converter_key = KasizukiManager.<>f__mg$cache0;
					if (KasizukiManager.<>f__mg$cache1 == null)
					{
						KasizukiManager.<>f__mg$cache1 = new Converter<string, byte[]>(Util.GetBytes);
					}
					systemData.Serialize(brWrite, converter_key, KasizukiManager.<>f__mg$cache1);
					int count = this.m_MaidDataArray.Count;
					binaryWriter.Write(count);
					foreach (KeyValuePair<string, DataArray<string, string>> keyValuePair in this.m_MaidDataArray)
					{
						binaryWriter.Write(keyValuePair.Key);
						DataArray<string, string> value = keyValuePair.Value;
						BinaryWriter brWrite2 = binaryWriter;
						if (KasizukiManager.<>f__mg$cache2 == null)
						{
							KasizukiManager.<>f__mg$cache2 = new Converter<string, byte[]>(Util.GetBytes);
						}
						Converter<string, byte[]> converter_key2 = KasizukiManager.<>f__mg$cache2;
						if (KasizukiManager.<>f__mg$cache3 == null)
						{
							KasizukiManager.<>f__mg$cache3 = new Converter<string, byte[]>(Util.GetBytes);
						}
						value.Serialize(brWrite2, converter_key2, KasizukiManager.<>f__mg$cache3);
					}
				}
				saveData.buffer = memoryStream.ToArray();
			}
		}

		private void DeserializeSaveData(KasizukiManager.SaveData saveData)
		{
			using (MemoryStream memoryStream = new MemoryStream(saveData.buffer))
			{
				using (BinaryReader binaryReader = new BinaryReader(memoryStream))
				{
					this.SetNowManType(saveData.header.lastManType);
					DataArray<string, string> systemData = this.m_SystemData;
					BinaryReader brRead = binaryReader;
					if (KasizukiManager.<>f__mg$cache4 == null)
					{
						KasizukiManager.<>f__mg$cache4 = new Func<BinaryReader, string>(Util.ToString);
					}
					Func<BinaryReader, string> func_read_key = KasizukiManager.<>f__mg$cache4;
					if (KasizukiManager.<>f__mg$cache5 == null)
					{
						KasizukiManager.<>f__mg$cache5 = new Func<BinaryReader, string>(Util.ToString);
					}
					systemData.Deserialize(brRead, func_read_key, KasizukiManager.<>f__mg$cache5);
					int num = binaryReader.ReadInt32();
					for (int i = 0; i < num; i++)
					{
						string text = binaryReader.ReadString();
						Maid stockMaid = GameMain.Instance.CharacterMgr.GetStockMaid(text);
						if (stockMaid == null)
						{
							Debug.LogFormat("GUID「{0}」のメイドは存在しなかったので、このメイドの情報は読み飛ばします", new object[]
							{
								text
							});
							DataArray<string, string> dataArray = new DataArray<string, string>();
							DataArray<string, string> dataArray2 = dataArray;
							BinaryReader brRead2 = binaryReader;
							if (KasizukiManager.<>f__mg$cache6 == null)
							{
								KasizukiManager.<>f__mg$cache6 = new Func<BinaryReader, string>(Util.ToString);
							}
							Func<BinaryReader, string> func_read_key2 = KasizukiManager.<>f__mg$cache6;
							if (KasizukiManager.<>f__mg$cache7 == null)
							{
								KasizukiManager.<>f__mg$cache7 = new Func<BinaryReader, string>(Util.ToString);
							}
							dataArray2.Deserialize(brRead2, func_read_key2, KasizukiManager.<>f__mg$cache7);
						}
						else
						{
							DataArray<string, string> dataArray3 = this.CreateMaidDataArray(stockMaid);
							DataArray<string, string> dataArray4 = dataArray3;
							BinaryReader brRead3 = binaryReader;
							if (KasizukiManager.<>f__mg$cache8 == null)
							{
								KasizukiManager.<>f__mg$cache8 = new Func<BinaryReader, string>(Util.ToString);
							}
							Func<BinaryReader, string> func_read_key3 = KasizukiManager.<>f__mg$cache8;
							if (KasizukiManager.<>f__mg$cache9 == null)
							{
								KasizukiManager.<>f__mg$cache9 = new Func<BinaryReader, string>(Util.ToString);
							}
							dataArray4.Deserialize(brRead3, func_read_key3, KasizukiManager.<>f__mg$cache9);
						}
					}
				}
			}
		}

		public static Texture2D GetMaidThumbnail(Maid maid)
		{
			Texture2D result = null;
			string text = Path.GetFullPath(".\\") + "Thumb\\";
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string guid = maid.status.guid;
			string text2 = text + "_tmp_kasizuki_" + guid + ".png";
			if (File.Exists(text2))
			{
				result = UTY.LoadTexture(text2);
			}
			else
			{
				text2 = text + "kasizuki_" + guid + ".png";
				if (File.Exists(text2))
				{
					result = UTY.LoadTexture(text2);
				}
			}
			return result;
		}

		public static bool IsExistMaidThumbnail(Maid maid)
		{
			string text = Path.GetFullPath(".\\") + "Thumb\\";
			if (!Directory.Exists(text))
			{
				return false;
			}
			string guid = maid.status.guid;
			string path = text + "_tmp_kasizuki_" + guid + ".png";
			if (File.Exists(path))
			{
				return true;
			}
			path = text + "kasizuki_" + guid + ".png";
			return File.Exists(path);
		}

		private static void FixMaidThumbnails()
		{
			string text = Path.GetFullPath(".\\") + "Thumb\\";
			if (!Directory.Exists(text))
			{
				return;
			}
			string[] files = Directory.GetFiles(text, "*", SearchOption.TopDirectoryOnly);
			for (int i = 0; i < files.Length; i++)
			{
				string text2 = string.Empty;
				try
				{
					text2 = files[i].Substring(text.Length, files[i].Length - text.Length);
				}
				catch
				{
				}
				if (string.IsNullOrEmpty(text2))
				{
					files[i] = string.Empty;
				}
				else if (0 > text2.IndexOf(".png") || 0 > text2.IndexOf("_tmp_kasizuki_"))
				{
					files[i] = string.Empty;
				}
			}
			for (int j = 0; j < files.Length; j++)
			{
				if (!string.IsNullOrEmpty(files[j]))
				{
					try
					{
						int length = "_tmp_kasizuki_".Length;
						string text3 = files[j].Substring(text.Length, files[j].Length - text.Length);
						string str = "kasizuki_" + text3.Substring(length, text3.Length - length - ".png".Length) + ".png";
						if (File.Exists(text + str))
						{
							File.Delete(text + str);
						}
						File.Move(files[j], text + str);
					}
					catch
					{
					}
				}
			}
		}

		private static void DeleteTmpMaidThumnails()
		{
			string text = Path.GetFullPath(".\\") + "Thumb\\";
			if (!Directory.Exists(text))
			{
				return;
			}
			string[] files = Directory.GetFiles(text, "*", SearchOption.TopDirectoryOnly);
			for (int i = 0; i < files.Length; i++)
			{
				string text2 = string.Empty;
				try
				{
					text2 = files[i].Substring(text.Length, files[i].Length - text.Length);
				}
				catch
				{
				}
				if (string.IsNullOrEmpty(text2))
				{
					files[i] = string.Empty;
				}
				else if (0 > text2.IndexOf(".png") || 0 > text2.IndexOf("_tmp_kasizuki_"))
				{
					files[i] = string.Empty;
				}
			}
			for (int j = 0; j < files.Length; j++)
			{
				if (!string.IsNullOrEmpty(files[j]))
				{
					try
					{
						File.Delete(files[j]);
					}
					catch
					{
					}
				}
			}
		}

		public void TJSFuncGetKasizukiSystemFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(result != null, "error GetKasizukiSystemFlag");
			NDebug.Assert(1 == tjs_param.Length, "GetKasizukiSystemFlag args count error.");
			KasizukiManager kasizukiMgr = GameMain.Instance.KasizukiMgr;
			result.SetString(kasizukiMgr.GetSystemData<string>(tjs_param[0].AsString()));
		}

		public void TJSFuncSetKasizukiSystemFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(2 == tjs_param.Length, "SetKasizukiSystemFlag args count error.");
			KasizukiManager kasizukiMgr = GameMain.Instance.KasizukiMgr;
			kasizukiMgr.SetSystemData<string>(tjs_param[0].AsString(), tjs_param[1].AsString(), false);
		}

		public void TJSFuncAddKasizukiSystemFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(2 == tjs_param.Length, "AddKasizukiSystemFlag args count error.");
			KasizukiManager kasizukiMgr = GameMain.Instance.KasizukiMgr;
			string valueName = tjs_param[0].AsString();
			int num = kasizukiMgr.GetSystemData<int>(valueName);
			num += tjs_param[1].AsInteger();
			kasizukiMgr.SetSystemData<int>(valueName, num, false);
		}

		public void TJSFuncSetKasizukiPassFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(1 == tjs_param.Length, "SetKasizukiPassFlag args count error.");
			KasizukiManager kasizukiMgr = GameMain.Instance.KasizukiMgr;
			int id = tjs_param[0].AsInteger();
			PlayData.Data data = PlayData.GetData(id);
			data.IsPassed = true;
		}

		public void TJSFuncSetKasizukiMaidFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(3 == tjs_param.Length, "SetKasizukiMaidFlag args count error.");
			int num = tjs_param[0].AsInteger();
			string valueName = tjs_param[1].AsString();
			int value = tjs_param[2].AsInteger();
			Maid maid = GameMain.Instance.CharacterMgr.GetMaid(num);
			NDebug.Assert(maid != null, "[SetKasizukiMaidFlag]\nメイド" + num + "番が見つかりません");
			KasizukiManager kasizukiMgr = GameMain.Instance.KasizukiMgr;
			kasizukiMgr.SetMaidData<int>(maid, valueName, value, false);
		}

		public void TJSFuncGetKasizukiMaidFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(result != null, "error GetKasizukiMaidFlag");
			NDebug.Assert(2 == tjs_param.Length, "GetKasizukiMaidFlag args count error.");
			int num = tjs_param[0].AsInteger();
			string valueName = tjs_param[1].AsString();
			Maid maid = GameMain.Instance.CharacterMgr.GetMaid(num);
			NDebug.Assert(maid != null, "[GetKasizukiMaidFlag]\nメイド" + num + "番が見つかりません");
			KasizukiManager kasizukiMgr = GameMain.Instance.KasizukiMgr;
			int maidData = kasizukiMgr.GetMaidData<int>(maid, valueName, false);
			result.SetInteger(maidData);
		}

		public void TJSFuncIsKasizukiCorrectSenarioFlag(TJSVariantRef[] tjs_param, TJSVariantRef result)
		{
			NDebug.Assert(result != null, "error GetKasizukiMaidFlag");
			NDebug.Assert(2 == tjs_param.Length, "GetKasizukiMaidFlag args count error.");
			int num = tjs_param[0].AsInteger();
			int id = tjs_param[1].AsInteger();
			Maid maid = GameMain.Instance.CharacterMgr.GetMaid(num);
			NDebug.Assert(maid != null, "[GetKasizukiMaidFlag]\nメイド" + num + "番が見つかりません");
			ManDataType nowManType = (ManDataType)this.GetNowManType();
			bool @bool = PlayData.GetData(id).IsCorrectMaid(maid, nowManType);
			result.SetBool(@bool);
		}

		public static string CreateMaidTmpThumbName(Maid maid)
		{
			NDebug.AssertNull(maid != null);
			return "_tmp_kasizuki_" + maid.status.guid + ".png";
		}

		public const int MAN_ACTIVATE_SLOT = 0;

		private const string STR_SERIALIZE_HEADER = "COM3D2_KASIZUKI";

		private const int SERIALIZE_VERSION = 5;

		private int m_NowOriginSaveDataNumber;

		private int m_NowKasizukiSaveDataIndex = 1;

		private DataArray<int, bool> m_NowHaveItemDic;

		private DataArray<string, string> m_SystemData;

		private Dictionary<string, DataArray<string, string>> m_MaidDataArray;

		private Dictionary<int, KasizukiManager.SaveData> m_SaveDataArray;

		private int m_LatestSaveDataNumber = -1;

		private Dictionary<MPN, MaidProp> m_CachedOriginPlayerDataDic;

		private string m_CachedOriginPlayerName;

		private Color m_CachedOriginPlayerColor;

		public const string STR_TMP_THUMB_NAME = "_tmp_kasizuki_";

		public const string STR_THUMB_NAME = "kasizuki_";

		[CompilerGenerated]
		private static Converter<string, byte[]> <>f__mg$cache0;

		[CompilerGenerated]
		private static Converter<string, byte[]> <>f__mg$cache1;

		[CompilerGenerated]
		private static Converter<string, byte[]> <>f__mg$cache2;

		[CompilerGenerated]
		private static Converter<string, byte[]> <>f__mg$cache3;

		[CompilerGenerated]
		private static Func<BinaryReader, string> <>f__mg$cache4;

		[CompilerGenerated]
		private static Func<BinaryReader, string> <>f__mg$cache5;

		[CompilerGenerated]
		private static Func<BinaryReader, string> <>f__mg$cache6;

		[CompilerGenerated]
		private static Func<BinaryReader, string> <>f__mg$cache7;

		[CompilerGenerated]
		private static Func<BinaryReader, string> <>f__mg$cache8;

		[CompilerGenerated]
		private static Func<BinaryReader, string> <>f__mg$cache9;

		public class SaveDataHeader
		{
			public SaveDataHeader()
			{
				this.strRealTime = DateTime.Now.ToString("yyyyMMddHHmmss");
				this.saveDataNumber = -1;
				this.saveDataVersion = -1;
				this.lastManType = 10;
				this.playCount = 0;
				this.strComment = string.Empty;
			}

			public void Serialize(BinaryWriter bw)
			{
				bw.Write(this.saveDataNumber);
				bw.Write(this.saveDataVersion);
				bw.Write(this.strRealTime);
				bw.Write(this.lastManType);
				bw.Write(this.playCount);
				bw.Write(this.strComment);
			}

			public void Deserialize(BinaryReader br)
			{
				this.saveDataNumber = br.ReadInt32();
				this.saveDataVersion = br.ReadInt32();
				this.strRealTime = br.ReadString();
				this.lastManType = br.ReadInt32();
				if (this.saveDataVersion >= 5)
				{
					this.playCount = br.ReadInt32();
				}
				this.strComment = br.ReadString();
			}

			public void UpdateNowTime()
			{
				this.strRealTime = DateTime.Now.ToString("yyyyMMddHHmmss");
			}

			public DateTime GetDateTime()
			{
				return DateTime.ParseExact(this.strRealTime, "yyyyMMddHHmmss", null);
			}

			public string strRealTime;

			public int saveDataNumber;

			public int saveDataVersion;

			public int lastManType;

			public int playCount;

			public string strComment;
		}

		public class SaveData
		{
			public SaveData()
			{
				this.header = new KasizukiManager.SaveDataHeader();
			}

			public void Serialize(Stream stream)
			{
				BinaryWriter binaryWriter = new BinaryWriter(stream);
				this.header.Serialize(binaryWriter);
				byte[] array = Util.CreatePrefix(this.buffer.Length);
				binaryWriter.Write(array);
				binaryWriter.Write(this.buffer);
				binaryWriter.Flush();
			}

			public bool Deserialize(Stream stream)
			{
				if (stream.Position + 1L >= stream.Length)
				{
					return false;
				}
				BinaryReader binaryReader = new BinaryReader(stream);
				this.header.Deserialize(binaryReader);
				int prefix = Util.GetPrefix(binaryReader.BaseStream, binaryReader.BaseStream.Position, true);
				this.buffer = new byte[prefix];
				binaryReader.Read(this.buffer, 0, this.buffer.Length);
				return true;
			}

			public KasizukiManager.SaveDataHeader header;

			public byte[] buffer;
		}
	}
}
