/*
 * CreateDate :2014-02-07
 * desc :卡片类
 * ModiftyDate :2014-02-12
 */
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using DataEditorX.Core.Info;

namespace DataEditorX.Core
{
	public struct Card : IEquatable<Card>
	{
        public const int STR_MAX = 0x10;
        public const int SETCODE_MAX = 4;

		#region 构造
		/// <summary>
		/// 卡片
		/// </summary>
		/// <param name="cardCode">密码</param>
		/// <param name="cardName">名字</param>
		public Card(long cardCode)
		{
            this.id = cardCode;
            this.name = "";
            this.ot = 0;
            this.alias = 0;
            this.setcode = 0;
            this.type = 0;
            this.atk = 0;
            this.def = 0;
            this.level = 0;
            this.race = 0;
            this.attribute = 0;
            this.category = 0;
            this.desc = "";
            this.str = new string[STR_MAX];
            for (int i = 0; i < STR_MAX; i++)
            {
                this.str[i] = "";
            }
        }
		#endregion

		#region 成员
		/// <summary>卡片密码</summary>
		public long id;
		/// <summary>卡片规则</summary>
		public int ot;
		/// <summary>卡片同名卡</summary>
		public long alias;
		/// <summary>卡片系列号</summary>
		public long setcode;
		/// <summary>卡片种类</summary>
		public long type;
		/// <summary>攻击力</summary>
		public int atk;
		/// <summary>防御力</summary>
		public int def;
		/// <summary>卡片等级</summary>
		public long level;
		/// <summary>卡片种族</summary>
		public long race;
		/// <summary>卡片属性</summary>
		public int attribute;
		/// <summary>效果种类</summary>
		public long category;
		/// <summary>卡片名称</summary>
		public string name;
		/// <summary>描述文本</summary>
		public string desc;
        string[] str;
		/// <summary>脚本文件文字</summary>
        public string[] Str
        {
            get {
                if (this.str == null)
                    {
                        this.str = new string[STR_MAX];
                        for (int i = 0; i < STR_MAX; i++)
                    {
                        this.str[i] = "";
                    }
                }
                return this.str;
                }
            set { this.str = value; }
        }
        public long[] GetSetCode()
        {
            long[] setcodes = new long[SETCODE_MAX];
            for (int i = 0,k = 0; i < SETCODE_MAX; k += 0x10, i++)
            {
                setcodes[i] = (this.setcode >> k) & 0xffff;
            }
            return setcodes;
        }
        public void SetSetCode(params long[] setcodes)
        {
            int i = 0;
            this.setcode = 0;
            if (setcodes != null)
            {
                foreach (long sc in setcodes)
                {
                    this.setcode += (sc << i);
                    i += 0x10;
                }
            }
        }
        public void SetSetCode(params string[] setcodes)
        {
            int i = 0;
            this.setcode = 0;
            if (setcodes != null)
            {
                foreach (string sc in setcodes)
                {
                    long.TryParse(sc, NumberStyles.HexNumber, null, out long temp);
                    this.setcode += (temp << i);
                    i += 0x10;
                }
            }
        }
		public long GetLeftScale()
		{
			return (this.level >> 24) & 0xff;
		}
		public long GetRightScale()
		{
			return (this.level >> 16) & 0xff;
		}
        #endregion

		#region 比较、哈希值、操作符
		/// <summary>
		/// 比较
		/// </summary>
		/// <param name="obj">对象</param>
		/// <returns>结果</returns>
		public override bool Equals(object obj)
		{
			if (obj is Card)
            {
                return this.Equals((Card)obj); // use Equals method below
            }
            else
            {
                return false;
            }
        }
		/// <summary>
		/// 比较卡片，除脚本提示文本
		/// </summary>
		/// <param name="other"></param>
		/// <returns></returns>
        public bool EqualsData(Card other)
		{
			bool equalBool = true;
			if (this.id != other.id)
            {
                equalBool = false;
            }
            else if (this.ot != other.ot)
            {
                equalBool = false;
            }
            else if (this.alias != other.alias)
            {
                equalBool = false;
            }
            else if (this.setcode != other.setcode)
            {
                equalBool = false;
            }
            else if (this.type != other.type)
            {
                equalBool = false;
            }
            else if (this.atk != other.atk)
            {
                equalBool = false;
            }
            else if (this.def != other.def)
            {
                equalBool = false;
            }
            else if (this.level != other.level)
            {
                equalBool = false;
            }
            else if (this.race != other.race)
            {
                equalBool = false;
            }
            else if (this.attribute != other.attribute)
            {
                equalBool = false;
            }
            else if (this.category != other.category)
            {
                equalBool = false;
            }
            else if (!this.name.Equals(other.name))
            {
                equalBool = false;
            }
            else if (!this.desc.Equals(other.desc))
            {
                equalBool = false;
            }

            return equalBool;
		}
		/// <summary>
		/// 比较卡片是否一致？
		/// </summary>
		/// <param name="other">比较的卡片</param>
		/// <returns>结果</returns>
		public bool Equals(Card other)
		{
			bool equalBool=this.EqualsData(other);
			if(!equalBool)
            {
                return false;
            }
            else if (this.str.Length != other.str.Length)
            {
                equalBool = false;
            }
            else
			{
				int l = this.str.Length;
				for (int i = 0; i < l; i++)
				{
					if (!this.str[i].Equals(other.str[i]))
					{
						equalBool = false;
						break;
					}
				}
			}
			return equalBool;

		}
		/// <summary>
		/// 得到哈希值
		/// </summary>
		public override int GetHashCode()
		{
			// combine the hash codes of all members here (e.g. with XOR operator ^)
			int hashCode = this.id.GetHashCode() + this.name.GetHashCode();
			return hashCode;//member.GetHashCode();
		}
		/// <summary>
		/// 比较卡片是否相等
		/// </summary>
		public static bool operator ==(Card left, Card right)
		{
			return left.Equals(right);
		}
        /// <summary>
        /// 是否是某类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
		public bool IsType(CardType type){
			if((this.type & (long)type) == (long)type)
            {
                return true;
            }

            return false;
		}
        /// <summary>
        /// 是否是某系列
        /// </summary>
        /// <param name="sc"></param>
        /// <returns></returns>
		public bool IsSetCode(long sc)
		{
            long settype = sc & 0xfff;
            long setsubtype = sc & 0xf000;
            long setcode = this.setcode;
            while (setcode != 0)
            {
                if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
                {
                    return true;
                }

                setcode >>= 0x10;
            }
            return false;
		}
		/// <summary>
		/// 卡片是否不相等
		/// </summary>
		public static bool operator !=(Card left, Card right)
		{
			return !left.Equals(right);
		}
		#endregion

        #region 卡片文字信息
        /// <summary>
        /// 密码字符串
        /// </summary>
        public string IdString
        {
            get { return this.id.ToString("00000000"); }
        }
        /// <summary>
        /// 字符串化
        /// </summary>
        public override string ToString()
        {
            string str;
            if (this.IsType(CardType.TYPE_MONSTER)){
                str = this.name + "[" + this.IdString + "]\n["
                    + YGOUtil.GetTypeString(this.type) + "] "
                    + YGOUtil.GetRace(this.race) + "/" + YGOUtil.GetAttributeString(this.attribute)
                    + "\n" + this.levelString() + " " + this.atk + "/" + this.def + "\n" + this.redesc();
            }else
            {
                str = this.name +"[" + this.IdString +"]\n["+YGOUtil.GetTypeString(this.type)+"]\n"+ this.redesc();
            }

            return str;
        }
        public string ToShortString(){
            return this.name+" ["+ this.IdString +"]";
        }
        public string ToLongString(){
            return this.ToString();
        }

        string levelString()
        {
            string star = "[";
            long j = this.level & 0xff;
            long i;
            for (i = 0; i < j; i++)
            {
                if (i > 0 && (i % 4) == 0)
                {
                    star += " ";
                }

                star += "★";
            }
            return star + "]";
        }
        string redesc()
        {
            string str = this.desc.Replace(Environment.NewLine, "\n");
            str = Regex.Replace(str, "([。|？|?])", "$1\n");
            str = str.Replace("\n\n", "\n");
            return str;
        }
        #endregion
    }
	
}
