using System;
using System.Text;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using ProtoBuf;
using Newtonsoft.Json;
using Microsoft.VisualBasic;

namespace NetVision {




    /// <summary>
    /// カード情報
    /// </summary>
    [Serializable()]
    [ProtoContract]
    public struct CardInfo {

        #region 基本フィールド

        /// <summary>
        /// カードID
        /// </summary>
        [ProtoMember(1)]
        public string No { get; set; }

        /// <summary>
        /// カード名
        /// </summary>
        [ProtoMember(2)]
        public string Name { get; set; }

        /// <summary>
        /// カードの種類
        /// </summary>
        [ProtoMember(3)]
        public CardType Type { get; set; }
        
        /// <summary>
        /// グレイズ
        /// </summary>
        [ProtoMember(4)]
        public string Glaze { get; set; }
        
        /// <summary>
        /// ノード
        /// </summary>
        [ProtoMember(5)]
        public string Node { get; set; }

        /// <summary>
        /// コスト
        /// </summary>
        [ProtoMember(6)]
        public string Cost { get; set; }

        /// <summary>
        /// 使用者
        /// </summary>
        [ProtoMember(7)]
        public string User { get; set; }

        /// <summary>
        /// 種族
        /// </summary>
        [ProtoMember(8)]
        public string Class { get; set; }

        /// <summary>
        /// 戦術
        /// </summary>
        [ProtoMember(9)]
        public string Skill { get; set; }

        /// <summary>
        /// 維持コスト
        /// </summary>
        [ProtoMember(10)]
        public string Upkeep { get; set; }

        /// <summary>
        /// 能力
        /// </summary>
        [ProtoMember(11)]
        public string Ability { get; set; }

        /// <summary>
        /// 攻撃
        /// </summary>
        [ProtoMember(12)]
        public string Attack { get; set; }

        /// <summary>
        /// 耐久
        /// </summary>
        [ProtoMember(13)]
        public string Toughness { get; set; }

        /// <summary>
        /// フレーバー
        /// </summary>
        [ProtoMember(14)]
        public string Text { get; set; }

        /// <summary>
        /// イラストレーター
        /// </summary>
        [ProtoMember(15)]
        public string Illustration { get; set; }

        /// <summary>
        /// ファイル
        /// </summary>
        [ProtoMember(16)]
        public string FileName { get; set; }

        /// <summary>
        /// 範囲
        /// </summary>
        [ProtoMember(17)]
        public string Range { get; set; }


        /// <summary>
        /// 期間
        /// </summary>
        [ProtoMember(18)]
        public string Time { get; set; }

        #endregion


        #region 便利フィールド

        /// <summary>
        /// 場に出るときのタイプ
        /// </summary>
        [JsonIgnore()]
        public PlayingType PlayingType {
            get {
                if (Type == CardType.Character) { return PlayingType.Character; }
                if (Skill.Contains("【幻想生物】")) { return PlayingType.Phantasmal; }
                if (Skill.Contains("【装備／場】")) { return PlayingType.FieldsEquip; }
                if (Skill.Contains("【世界呪符】")) { return PlayingType.WorldsAmulet; }
                if (Skill.Contains("【装備】")) { return PlayingType.Equip; }
                if (Skill.Contains("【呪符】")) { return PlayingType.Amulet; }
                return PlayingType.Moment;
            }
        }

        /// <summary>
        /// ノードを数値で取得
        /// </summary>
        [JsonIgnore()]
        public int NodeNum {
            get { return CardInfo.String2Int(Node); }
        }

        /// <summary>
        /// コストを数値で取得
        /// </summary>
        [JsonIgnore()]
        public int CostNum {
            get { return CardInfo.String2Int(Cost); }
        }

        /// <summary>
        /// 攻撃力を数値で取得
        /// </summary>
        [JsonIgnore()]
        public int AttackNum {
            get { return CardInfo.String2Int(Attack); }
        }

        /// <summary>
        /// 防御力を数値で取得
        /// </summary>
        [JsonIgnore()]
        public int ToughnessNum {
            get { return CardInfo.String2Int(Toughness); }
        }

        /// <summary>
        /// 文字表現を数値に
        /// </summary>
        /// <param name="str">対象の文字列</param>
        /// <returns>数値</returns>
        private static int String2Int( string str ) {
            if (str == "-") { return 99; }
            if (str.Contains("X") || str == "") { return 0; }
            
            return int.Parse(str);
        }

        /// <summary>
        /// 短い名前
        /// </summary>
        [JsonIgnore()]
        public string ShortName {
            get {
                string sname = Name;
                if (Name == null) { return ""; }
                Regex reg = new Regex("「(.+)」");
                if (reg.IsMatch(Name)) { sname = reg.Match(Name).Groups[1].Value; }
                sname = Strings.StrConv(sname, VbStrConv.Narrow, 0);
                return sname;
            }
        }

        /// <summary>
        /// 戦闘能力
        /// </summary>
        [JsonIgnore()]
        public string BattleStatus {
            get { return Attack + "/" + Toughness; }
        }

        /// <summary>
        /// 適度に改行したテキスト
        /// </summary>
        /// <param name="break_num">開業する文字数</param>
        /// <returns>テキスト</returns>
        public string GetBreakedText( int break_num ) {
            string[] ab = Ability.Split(new string[] { @"\n" }, StringSplitOptions.RemoveEmptyEntries);
            StringBuilder str = new StringBuilder(Skill != "" ? Skill + "\n\n" : "");
            for (int j = 0; j < ab.Length; j++) {
                for (int i = 1; i <= ab[j].Length / break_num; i++) {
                    ab[j] = ab[j].Insert(i * break_num, "\n");
                }
                str.AppendLine(ab[j] + "\n");
            }
            return str.ToString();
        }



        #endregion


    }


}
