/*
 * 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;
            long temp;
            if (setcodes != null)
            {
                foreach (string sc in setcodes)
                {
                    long.TryParse(sc, NumberStyles.HexNumber, null, out temp);
                    this.setcode += (temp << i);
                    i += 0x10;
                }
            }
        }
		public long GetLeftScale()
		{
			return (this.level >> 0x18) & 0xff;
		}
		public long GetRightScale()
		{
			return (this.level >> 0x10) & 0xff;
		}
        #endregion

		#region 比较、哈希值、操作符
		/// <summary>
		/// 比较
		/// </summary>
		/// <param name="obj">对象</param>
		/// <returns>结果</returns>
		public override bool Equals(object obj)
		{
			if (obj is Card)
				return 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=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 = id.GetHashCode() + 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 = 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 id.ToString("00000000"); }
        }
        /// <summary>
        /// 字符串化
        /// </summary>
        public override string ToString()
        {
            string str = "";
            if (IsType(CardType.TYPE_MONSTER)){
                str = name + "[" + idString + "]\n["
                    + YGOUtil.GetTypeString(type) + "] "
                    + YGOUtil.GetRace(race) + "/" + YGOUtil.GetAttributeString(attribute)
                    + "\n" + levelString() + " " + atk + "/" + def + "\n" + redesc();
            }else
                str = name +"[" +idString +"]\n["+YGOUtil.GetTypeString(type)+"]\n"+redesc();
            return str;
        }
        public string ToShortString(){
            return this.name+" ["+idString+"]";
        }
        public string ToLongString(){
            return ToString();
        }

        string levelString()
        {
            string star = "[";
            long i = 0, j = level & 0xff;
            for (i = 0; i < j; i++)
            {
                if (i > 0 && (i % 4) == 0)
                    star += " ";
                star += "★";
            }
            return star + "]";
        }
        string redesc()
        {
            string str = desc.Replace(Environment.NewLine, "\n");
            str = Regex.Replace(str, "([。|？|?])", "$1\n");
            str = str.Replace("\n\n", "\n");
            return str;
        }
        #endregion
    }
	
}
