using System;
using System.Collections.Generic;
using System.IO;
using MaidStatus.CsvData;
using wf;

namespace MaidStatus
{
	public abstract class IClassSystem<T> where T : AbstractClassData
	{
		public abstract ReadOnlySortedDictionary<int, ClassData<T>> datas { get; protected set; }

		public abstract ReadOnlySortedDictionary<int, ClassData<T>> oldDatas { get; protected set; }

		public abstract Status status { get; protected set; }

		public abstract ClassData<T> Add(T data, bool setOpenFlag, bool updateBonusStatus = true);

		public abstract void Remove(T data, bool updateBonusStatus = true);

		public abstract T IdToClass(int id);

		public abstract void Serialize(BinaryWriter binary);

		public abstract void Deserialize(BinaryReader binary, int version);

		protected abstract List<T> GetAllBaseClassData();

		public virtual SortedDictionary<int, ClassData<T>> GetAllDatas()
		{
			SortedDictionary<int, ClassData<T>> sortedDictionary = new SortedDictionary<int, ClassData<T>>();
			foreach (ClassData<T> classData in this.datas.GetValueArray())
			{
				if (!sortedDictionary.ContainsKey(classData.data.id))
				{
					sortedDictionary.Add(classData.data.id, classData);
				}
			}
			if (this.oldDatas != null)
			{
				foreach (ClassData<T> classData2 in this.oldDatas.GetValueArray())
				{
					if (!sortedDictionary.ContainsKey(classData2.data.id))
					{
						sortedDictionary.Add(classData2.data.id, classData2);
					}
				}
			}
			return sortedDictionary;
		}

		public virtual ClassData<T> Add(int id, bool setOpenFlag, bool updateBonusStatus = true)
		{
			return this.Add(this.IdToClass(id), setOpenFlag, updateBonusStatus);
		}

		public virtual void Remove(int id, bool updateBonusStatus = true)
		{
			this.Remove(this.IdToClass(id), updateBonusStatus);
		}

		public virtual bool Contains(int id)
		{
			return this.Contains(this.IdToClass(id));
		}

		public virtual bool Contains(T data)
		{
			return data != null && (this.datas.ContainsKey(data.id) || (this.oldDatas != null && this.oldDatas.ContainsKey(data.id)));
		}

		public virtual ClassData<T> Get(T data)
		{
			return this.Contains(data) ? ((!this.datas.ContainsKey(data.id)) ? this.oldDatas[data.id] : this.datas[data.id]) : null;
		}

		public virtual ClassData<T> Get(int id)
		{
			return this.Get(this.IdToClass(id));
		}

		public virtual List<T> GetLearnPossibleClassDatas(bool unlearnedOnly, AbstractClassData.ClassType classTypeFlags)
		{
			List<T> list = new List<T>();
			CharacterMgr characterMgr = GameMain.Instance.CharacterMgr;
			List<T> allBaseClassData = this.GetAllBaseClassData();
			foreach (T t in allBaseClassData)
			{
				if (!unlearnedOnly || !this.Contains(t.id))
				{
					if ((classTypeFlags & t.classType) != (AbstractClassData.ClassType)0 && t.learnConditions.isLearnPossibleStatus(this.status))
					{
						list.Add(t);
					}
				}
			}
			return list;
		}

		protected SortedDictionary<int, ClassData<T>> classDatas_;

		protected SortedDictionary<int, ClassData<T>> oldClassDatas_;
	}
}
