using System;
using System.IO;

public abstract class IExperienceSystem : ICloneable
{
	protected IExperienceSystem()
	{
	}

	protected IExperienceSystem(IExperienceSystem other)
	{
		this.current_exp_ = other.current_exp_;
		this.total_exp_ = other.total_exp_;
		this.next_exp_ = other.next_exp_;
		this.level_ = other.level_;
	}

	public abstract int GetMaxLevel();

	public virtual int GetNextLevelExp(int level)
	{
		level++;
		if (level <= 0 || this.GetMaxLevel() < level)
		{
			return 0;
		}
		return this.GetNeedExp(level);
	}

	public virtual int GetCurrentLevel()
	{
		return this.level_;
	}

	public virtual int GetCurrentExp()
	{
		return this.current_exp_;
	}

	public virtual int GetNextLevelRestExp()
	{
		return this.next_exp_;
	}

	public virtual int GetMaxLevelNeedExp()
	{
		int num = 0;
		for (int i = 0; i < this.GetMaxLevel(); i++)
		{
			num += this.GetNextLevelExp(i);
		}
		return num;
	}

	public virtual int GetTotalExp()
	{
		return this.total_exp_;
	}

	public virtual void AddExp(int exp)
	{
		this.total_exp_ += exp;
		this.Update();
	}

	public virtual void SetLevel(int level)
	{
		this.total_exp_ = 0;
		if (level < 0)
		{
			level = 0;
		}
		int maxLevel = this.GetMaxLevel();
		if (maxLevel < level)
		{
			level = maxLevel;
		}
		if (1 <= level)
		{
			level = Math.Min(this.GetMaxLevel(), level);
			for (int i = 1; i <= level; i++)
			{
				this.total_exp_ += this.GetNeedExp(i);
			}
		}
		this.Update();
	}

	public virtual void SetTotalExp(int total_exp)
	{
		this.total_exp_ = total_exp;
		this.Update();
	}

	public virtual void Update()
	{
		int maxLevelNeedExp = this.GetMaxLevelNeedExp();
		if (maxLevelNeedExp < this.total_exp_)
		{
			this.total_exp_ = maxLevelNeedExp;
		}
		if (this.total_exp_ < 0)
		{
			this.total_exp_ = 0;
		}
		int num = this.total_exp_;
		int maxLevel = this.GetMaxLevel();
		for (int i = 1; i <= maxLevel; i++)
		{
			int needExp = this.GetNeedExp(i);
			num -= this.GetNeedExp(i);
			if (num < 0)
			{
				this.level_ = i - 1;
				this.next_exp_ = Math.Abs(num);
				this.current_exp_ = needExp + num;
				return;
			}
		}
		this.level_ = maxLevel;
		this.current_exp_ = (this.next_exp_ = 0);
	}

	public virtual void Serialize(BinaryWriter binary)
	{
		binary.Write(this.current_exp_);
		binary.Write(this.total_exp_);
		binary.Write(this.next_exp_);
		binary.Write(this.level_);
	}

	public virtual void Deserialize(BinaryReader binary, int version)
	{
		this.current_exp_ = binary.ReadInt32();
		this.total_exp_ = binary.ReadInt32();
		this.next_exp_ = binary.ReadInt32();
		this.level_ = binary.ReadInt32();
	}

	protected abstract int GetNeedExp(int level);

	public abstract object Clone();

	protected int current_exp_;

	protected int total_exp_;

	protected int next_exp_;

	protected int level_;
}
