using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using ProtoBuf;

namespace NetVision {

    /// <summary>
    /// 画面操作をコマンドとして保持する構造体データ
    /// </summary>
    [ProtoContract]
    public struct Command {


        /// <summary>
        /// コマンドタイプ
        /// </summary>
        [ProtoMember(1)]
        public CommandType Type { get; set; }

        /// <summary>
        /// 対象のカードID
        /// </summary>
        [ProtoMember(2)]
        public int CardId { get; set; }

        /// <summary>
        /// 移動先のエリア
        /// </summary>
        [ProtoMember(3)]
        public AreaType ToArea { get; set; }

        /// <summary>
        /// 送信するメッセージ
        /// </summary>
        [ProtoMember(4)]
        public string Message { get; set; }

        /// <summary>
        /// アクティブ/スリープ
        /// </summary>
        [ProtoMember(5)]
        public bool Active { get; set; }

        /// <summary>
        /// 表裏
        /// </summary>
        [ProtoMember(6)]
        public bool FaceSide { get; set; }

        /// <summary>
        /// 変身
        /// </summary>
        [ProtoMember(7)]
        public bool Transformed { get; set; }

        /// <summary>
        /// 値
        /// </summary>
        [ProtoMember(8)]
        public int Value { get; set; }

        /// <summary>
        /// プレイヤーのシャドウ
        /// </summary>
        [ProtoMember(9)]
        public PlayerShadow Player { get; set; }

        /// <summary>
        /// X座標
        /// </summary>
        [ProtoMember(10)]
        public float X { get; set; }

        /// <summary>
        /// Y座標
        /// </summary>
        [ProtoMember(11)]
        public float Y { get; set; }

        /// <summary>
        /// 移動先の座標
        /// </summary>
        public PointF Location {
            get { return new PointF(X, Y); }
            set { X = value.X; Y = value.Y; }
        }

        /// <summary>
        /// プレイヤーを切り替える
        /// </summary>
        public void FlipPlayer(){ Remote = !Remote; }

        /// <summary>
        /// 記録用の上下判定
        /// </summary>
        public bool Mine { get; set; }

        /// <summary>
        /// 自分自身のコマンド
        /// </summary>
        [ProtoMember(12)]
        public bool Remote { get; set; }

        /// <summary>
        /// カード
        /// </summary>
        public CardBox Card {
            set {
                CardId = value.Id;
            }
        }

        /// <summary>
        /// 複数のカードID
        /// </summary>
        [ProtoMember(13)]
        public List<int> CardIds { get; set; }

        /// <summary>
        /// 複数のカードをセット
        /// </summary>
        public List<CardBox> Cards {
            set {
                CardIds = new List<int>();
                for (int i = 0; i < value.Count; i++) {
                    CardIds.Add( value[i].Id );
                }
            }
        }

    }

    /// <summary>
    /// シリアライズ用のプレイヤー情報構造体
    /// </summary>
    [ProtoContract]
    public struct PlayerShadow {

        /// <summary>
        /// プレイヤー名
        /// </summary>
        [ProtoMember(1)]
        public string PlayerName { get; set; }

        /// <summary>
        /// ライフ
        /// </summary>
        [ProtoMember(2)]
        public int Life { get; set; }

        /// <summary>
        /// 状態
        /// </summary>
        [ProtoMember(3)]
        public PlayerState State { get; set; }

        /// <summary>
        /// カード内容
        /// </summary>
        [ProtoMember(4)]
        public Dictionary<AreaType, List<CardShadow>> Cards { get; set; }

    }


    /// <summary>
    /// シリアライズ用のカード情報構造体
    /// </summary>
    [ProtoContract]
    public struct CardShadow {

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

        /// <summary>
        /// カードナンバー
        /// </summary>
        [ProtoMember(2)]
        public string No { get; set; }

        /// <summary>
        /// アクティブ状態
        /// </summary>
        [ProtoMember(3)]
        public bool Active { get; set; }

        /// <summary>
        /// 表裏
        /// </summary>
        [ProtoMember(4)]
        public bool FaceSide { get; set; }

        /// <summary>
        /// 変身状態
        /// </summary>
        [ProtoMember(5)]
        public bool Transformed { get; set; }

        /// <summary>
        /// 仮想X座標
        /// </summary>
        [ProtoMember(6)]
        public float X { get; set; }

        /// <summary>
        /// 仮想Y座標
        /// </summary>
        [ProtoMember(7)]
        public float Y { get; set; }

        /// <summary>
        /// 裏向きカード名
        /// </summary>
        [ProtoMember(8)]
        public string BackInfo { get; set; }

        /// <summary>
        /// 仮想座標
        /// </summary>
        public PointF Location {
            get { return new PointF(X, Y); }
            set { X = value.X; Y = value.Y; }
        }

    }

    /// <summary>
    /// コマンド保存用構造体
    /// </summary>
    [ProtoContract]
    public struct CommandList {

        [ProtoMember(1)]
        public List<Command> Items { get; set; }

    }

}
