using CommonLang;
using CommonLang.IO;
using CommonLang.Net;
using CommonLang.Xml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace CommonUI.Data
{
    public class UIEditorMeta
    {
        public const string UERoot_ClassName = "com.g2d.studio.ui.edit.gui.UERoot";
        public const string UEButton_ClassName = "com.g2d.studio.ui.edit.gui.UEButton";
        public const string UEToggleButton_ClassName = "com.g2d.studio.ui.edit.gui.UEToggleButton";
        public const string UEImageBox_ClassName = "com.g2d.studio.ui.edit.gui.UEImageBox";
        public const string UELabel_ClassName = "com.g2d.studio.ui.edit.gui.UELabel";
        public const string UECanvas_ClassName = "com.g2d.studio.ui.edit.gui.UECanvas";
        public const string UETextInput_ClassName = "com.g2d.studio.ui.edit.gui.UETextInput";
        public const string UETextInputMultiline_ClassName = "com.g2d.studio.ui.edit.gui.UETextInputMultiline";
        public const string UETextBox_ClassName = "com.g2d.studio.ui.edit.gui.UETextBox";
        public const string UETextBoxHtml_ClassName = "com.g2d.studio.ui.edit.gui.UETextBoxHtml";
        public const string UEFileNode_ClassName = "com.g2d.studio.ui.edit.gui.UEFileNode";
        public const string UEScrollPan_ClassName = "com.g2d.studio.ui.edit.gui.UEScrollPan";
        public const string UEGauge_ClassName = "com.g2d.studio.ui.edit.gui.UEGauge";
        public const string UECheckBox_ClassName = "com.g2d.studio.ui.edit.gui.UECheckBox";

        public static readonly UIEditorMetaExternalizableFactory ExternalizableFactory = new UIEditorMetaExternalizableFactory();

        public static UIComponentMeta CreateComponent(string name)
        {
            switch (name)
            {
                case UERoot_ClassName: return new UERootMeta();
                case UEButton_ClassName: return new UETextButtonMeta();
                case UEToggleButton_ClassName: return new UEToggleButtonMeta();
                case UEImageBox_ClassName: return new UEImageBoxMeta();
                case UECheckBox_ClassName: return new UECheckBoxMeta();
                case UELabel_ClassName: return new UELabelMeta();
                case UECanvas_ClassName: return new UECanvasMeta();
                case UEGauge_ClassName: return new UEGaugeMeta();
                case UEFileNode_ClassName: return new UEFileNodeMeta();
                case UEScrollPan_ClassName: return new UEScrollPanMeta();
                case UETextBox_ClassName: return new UETextBoxMeta();
                case UETextBoxHtml_ClassName: return new UETextBoxHtmlMeta();
                case UETextInput_ClassName: return new UETextInputMeta();
                case UETextInputMultiline_ClassName: return new UETextInputMultilineMeta();
                default: return new UECanvasMeta();
            }
        }
        public static UIComponentMeta CreateFromXml(XmlDocument xml)
        {
            return CreateFromXml(xml.DocumentElement);
        }

        public static UIComponentMeta CreateFromXml(XmlNode xml)
        {
            UIComponentMeta ui = CreateComponent(xml.Name);
            if (ui != null)
            {
                ui.DecodeFromXML(xml);
            }
            return ui;
        }

        public static UILayoutMeta CreateLayout(XmlNode e)
        {
            if (e != null)
            {
                UILayoutMeta layout = new UILayoutMeta();
                layout.DecodeFromXML(e);
                return layout;
            }
            return null;
        }

        public static UIComponentMeta CreateFromStream(Stream stream)
        {
            InputStream input = new InputStream(stream, ExternalizableFactory);
            object ret = input.GetExtAny();
            return ret as UIComponentMeta;
        }

        public static void SaveToBin(UIComponentMeta meta, Stream stream)
        {
            OutputStream output = new OutputStream(stream, ExternalizableFactory);
            output.PutExt(meta);
            stream.Flush();
        }

        public static UIComponentMeta CreateFromBin(byte[] data)
        {
            using (MemoryStream bais = new MemoryStream(data))
            {
                return CreateFromStream(bais);
            }
        }

        public static byte[] SaveToBin(UIComponentMeta meta)
        {
            using (MemoryStream bais = new MemoryStream())
            {
                SaveToBin(meta, bais);
                return bais.ToArray();
            }
        }
    }

    public class UIEditorMetaExternalizableFactory : IExternalizableFactory
    {
        public const int UILayoutMeta_TypeID = 1;
        public const int UERoot_TypeID = 2;
        public const int UEButton_TypeID = 3;
        public const int UEToggleButton_TypeID = 4;
        public const int UEImageBox_TypeID = 5;
        public const int UELabel_TypeID = 6;
        public const int UECanvas_TypeID = 7;
        public const int UETextInput_TypeID = 8;
        public const int UETextInputMultiline_TypeID = 15;
        public const int UETextBox_TypeID = 9;
        public const int UETextBoxHtml_TypeID = 10;
        public const int UEFileNode_TypeID = 11;
        public const int UEScrollPan_TypeID = 12;
        public const int UEGauge_TypeID = 13;
        public const int UECheckBox_TypeID = 14;

        private HashMap<int, Type> MapIDToType = new HashMap<int, Type>();
        private HashMap<Type, int> MapTypeToID = new HashMap<Type, int>();

        public UIEditorMetaExternalizableFactory()
        {
            this.Regist(typeof(UILayoutMeta), UILayoutMeta_TypeID);

            this.Regist(typeof(UERootMeta), UERoot_TypeID);
            this.Regist(typeof(UETextButtonMeta), UEButton_TypeID);
            this.Regist(typeof(UEToggleButtonMeta), UEToggleButton_TypeID);
            this.Regist(typeof(UEImageBoxMeta), UEImageBox_TypeID);
            this.Regist(typeof(UELabelMeta), UELabel_TypeID);
            this.Regist(typeof(UECanvasMeta), UECanvas_TypeID);
            this.Regist(typeof(UETextInputMeta), UETextInput_TypeID);
            this.Regist(typeof(UETextInputMultilineMeta), UETextInputMultiline_TypeID);
            this.Regist(typeof(UETextBoxMeta), UETextBox_TypeID);
            this.Regist(typeof(UETextBoxHtmlMeta), UETextBoxHtml_TypeID);
            this.Regist(typeof(UEFileNodeMeta), UEFileNode_TypeID);
            this.Regist(typeof(UEScrollPanMeta), UEScrollPan_TypeID);
            this.Regist(typeof(UEGaugeMeta), UEGauge_TypeID);
            this.Regist(typeof(UECheckBoxMeta), UECheckBox_TypeID);
        }
        private void Regist(Type type, int id)
        {
            MapTypeToID.Add(type, id);
            MapIDToType.Add(id, type);
        }
        public int GetTypeID(Type type)
        {
            int ret;
            if (!MapTypeToID.TryGetValue(type, out ret))
            {
                throw new Exception("Can not resolve Type : " + type.FullName);
            }
            return ret;
        }
        public Type GetType(int id)
        {
            Type ret;
            if (!MapIDToType.TryGetValue(id, out ret))
            {
                throw new Exception("Can not resolve ID : " + id);
            }
            return ret;
        }
    }


    //----------------------------------------------------------------------------------------------------------

    public class UILayoutMeta : IExternalizable
    {
        public UILayoutStyle Style;
        public uint BackColorARGB;
        public uint BorderColorARGB;
        public int ClipSize;
        public bool Repeat;

        public string ImageName;
        public string AtlasName;
        public string SpriteName;

        public virtual void DecodeFromXML(XmlNode e)
        {
            this.Style = UILayoutStyle.NULL;
            string value;
            if (XmlUtil.TryGetAttribute(e, "style", out value))
            {
                this.Style = (UILayoutStyle)Enum.Parse(typeof(UILayoutStyle), value);
            }
            if (XmlUtil.TryGetAttribute(e, "bgc", out value))
            {
                this.BackColorARGB = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "bdc", out value))
            {
                this.BorderColorARGB = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "clip", out value))
            {
                this.ClipSize = int.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "repeat", out value))
            {
                this.Repeat = bool.Parse(value);
            }
            this.ImageName = XmlUtil.GetAttribute(e, "img");
            this.AtlasName = XmlUtil.GetAttribute(e, "atlas");
            this.SpriteName = XmlUtil.GetAttribute(e, "sprite");
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutEnum32(Style);
            output.PutU32(BackColorARGB);
            output.PutU32(BorderColorARGB);
            output.PutS32(ClipSize);
            output.PutBool(Repeat);
            output.PutUTF(ImageName);
            output.PutUTF(AtlasName);
            output.PutUTF(SpriteName);
        }
        public void ReadExternal(IInputStream input)
        {
            this.Style = input.GetEnum32<UILayoutStyle>();
            this.BackColorARGB = input.GetU32();
            this.BorderColorARGB = input.GetU32();
            this.ClipSize = input.GetS32();
            this.Repeat = input.GetBool();
            this.ImageName = input.GetUTF();
            this.AtlasName = input.GetUTF();
            this.SpriteName = input.GetUTF();
        }
    }

    /// <summary>
    /// 控件
    /// </summary>
    public class UIComponentMeta : IExternalizable
    {
        public UIComponentMeta Parent { get; private set; }

        public string ClassName;
        public string EditorName;

        public float X;
        public float Y;
        public float Width;
        public float Height;

        public bool Visible;

        public string UserData;
        public int UserTag;

        public UILayoutMeta Layout;
        public UILayoutMeta DisableLayout;

        public bool Enable;
        public bool EnableChilds;

        public UIAnchor EditorAnchor;
        public string Attributes;

        public List<UIComponentMeta> Childs = new List<UIComponentMeta>(1);

        private Properties m_AttributeMap;

        public string GetAttribute(string key)
        {
            return GetAttributsMap().Get(key);
        }
        public Properties GetAttributsMap()
        {
            if (m_AttributeMap == null)
            {
                m_AttributeMap = new Properties();
                string[] texts = this.Attributes.Split(';');
                foreach(string s in texts){
                    m_AttributeMap.ParseText(s, "=");
                }
               // m_AttributeMap.ParseText(this.Attributes, "=");
            }
            return m_AttributeMap;
        }

        public virtual void DecodeFromXML(XmlNode e)
        {
            this.ClassName = e.Name;

            this.Width = float.Parse(e.Attributes["width"].Value);
            this.Height = float.Parse(e.Attributes["height"].Value);

            this.X = float.Parse(e.Attributes["x"].Value);
            this.Y = float.Parse(e.Attributes["y"].Value);

            this.Visible = bool.Parse(e.Attributes["visible"].Value);
            this.EditorName = e.Attributes["name"].Value;

            this.UserData = e.Attributes["userData"].Value;
            this.UserTag = int.Parse(e.Attributes["userTag"].Value);

            this.Layout = UIEditorMeta.CreateLayout(XmlUtil.FindChild(e, "layout"));
            this.DisableLayout = UIEditorMeta.CreateLayout(XmlUtil.FindChild(e, "disable_layout"));

            this.Enable = bool.Parse(e.Attributes["enable"].Value);
            this.EnableChilds = bool.Parse(e.Attributes["enable_childs"].Value);

            this.Attributes = XmlUtil.GetAttribute(e, "Attributes");

            string uiAnchor = XmlUtil.GetAttribute(e, "uiAnchor");
            if (uiAnchor != null)
            {
                this.EditorAnchor = (UIAnchor)Enum.Parse(typeof(UIAnchor), uiAnchor, true);
            }

            XmlNode childs = XmlUtil.FindChild(e, "childs");
            if (childs != null)
            {
                int len = childs.ChildNodes.Count;
                for (int i = 0; i < len; ++i)
                {
                    XmlNode child = (XmlNode)childs.ChildNodes[i];
                    UIComponentMeta cui = UIEditorMeta.CreateFromXml(child);
                    if (cui != null)
                    {
                        cui.Parent = this;
                        this.Childs.Add(cui);
                    }
                }
            }
        }

        public virtual void WriteExternal(IOutputStream output)
        {
            output.PutUTF(ClassName);
            output.PutUTF(EditorName);

            output.PutF32(X);
            output.PutF32(Y);
            output.PutF32(Width);
            output.PutF32(Height);

            output.PutBool(Visible);

            output.PutUTF(UserData);
            output.PutS32(UserTag);

            output.PutExt(Layout);
            output.PutExt(DisableLayout);

            output.PutBool(Enable);
            output.PutBool(EnableChilds);

            output.PutEnum32(EditorAnchor);
            output.PutUTF(Attributes);

            output.PutList<UIComponentMeta>(Childs, output.PutExt);
        }

        public virtual void ReadExternal(IInputStream input)
        {
            this.ClassName = input.GetUTF();
            this.EditorName = input.GetUTF();

            this.X = input.GetF32();
            this.Y = input.GetF32();
            this.Width = input.GetF32();
            this.Height = input.GetF32();

            this.Visible = input.GetBool();

            this.UserData = input.GetUTF();
            this.UserTag = input.GetS32();

            this.Layout = input.GetExt<UILayoutMeta>();
            this.DisableLayout = input.GetExt<UILayoutMeta>();

            this.Enable = input.GetBool();
            this.EnableChilds = input.GetBool();

            this.EditorAnchor = input.GetEnum32<UIAnchor>();
            this.Attributes = input.GetUTF();


            this.Childs = input.GetListAny<UIComponentMeta>();

            for (int i = 0; i < Childs.Count; ++i)
            {
                Childs[i].Parent = this;
            }

        }

        public T FindChildAs<T>(Predicate<T> select, bool recursive = true) where T : UIComponentMeta
        {
            foreach (UIComponentMeta ui in Childs)
            {
                if ((ui is T) && select(ui as T))
                {
                    return (ui as T);
                }
            }
            if (recursive)
            {
                foreach (UIComponentMeta ui in Childs)
                {
                    T ret = ui.FindChildAs<T>(select, recursive);
                    if (ret != null)
                    {
                        return ret;
                    }
                }
            }
            return null;
        }
        public T FindChildByName<T>(string name, bool recursive = true) where T : UIComponentMeta
        {
            Predicate<T> select = (t) =>
            {
                return string.Equals(name, t.EditorName);
            };
            return FindChildAs<T>(select, recursive);
        }

    }

    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 编辑器根节点
    /// </summary>
    public class UERootMeta : UIComponentMeta { }
    /// <summary>
    /// 编辑器容器
    /// </summary>
    public class UECanvasMeta : UIComponentMeta { }
    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 图片框
    /// </summary>
    public class UEImageBoxMeta : UIComponentMeta
    {
        public string imagePath;
        public string imageAtlas;

        public float x_rotate, x_scaleX, x_scaleY;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Decode_Image(e);
        }
        protected virtual void Decode_Image(XmlNode e)
        {
            this.imagePath = XmlUtil.GetAttribute(e, "imagePath");
            this.imageAtlas = XmlUtil.GetAttribute(e, "imageAtlas");
            string value;
            if (XmlUtil.TryGetAttribute(e, "x_rotate", out value))
            {
                this.x_rotate = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "x_scaleX", out value))
            {
                this.x_scaleX = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "x_scaleY", out value))
            {
                this.x_scaleY = float.Parse(value);
            }
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutUTF(imagePath);
            output.PutUTF(imageAtlas);
            output.PutF32(x_rotate);
            output.PutF32(x_scaleX);
            output.PutF32(x_scaleY);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.imagePath = input.GetUTF();
            this.imageAtlas = input.GetUTF();
            this.x_rotate = input.GetF32();
            this.x_scaleX = input.GetF32();
            this.x_scaleY = input.GetF32();
        }
    }
    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 文本输入框
    /// </summary>
    public abstract class UETextInputBaseMeta : UIComponentMeta
    {
        public string Text;

        public string textFontName;
        public FontStyle textFontStyle;
        public int textFontSize;

        public uint textColor;

        public bool isPassword;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Decode_Text(e);
        }
        private void Decode_Text(XmlNode e)
        {
            string value;
            if (XmlUtil.TryGetAttribute(e, "textFont", out value))
            {
                string[] info = value.Split(',');
                this.textFontName = info[0];
                this.textFontSize = int.Parse(info[1]);
                this.textFontStyle = (FontStyle)Enum.ToObject(typeof(FontStyle), int.Parse(info[2]));
            }
            if (XmlUtil.TryGetAttribute(e, "textFontSize", out value))
            {
                this.textFontSize = int.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "textColor", out value))
            {
                this.textColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "isPassword", out value))
            {
                this.isPassword = bool.Parse(value);
            }
            this.Text = XmlUtil.GetAttribute(e, "Text");
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutUTF(Text);
            output.PutUTF(textFontName);
            output.PutEnum32(textFontStyle);
            output.PutS32(textFontSize);
            output.PutU32(textColor);
            output.PutBool(isPassword);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.Text = input.GetUTF();
            this.textFontName = input.GetUTF();
            this.textFontStyle = input.GetEnum32<FontStyle>();
            this.textFontSize = input.GetS32();
            this.textColor = input.GetU32();
            this.isPassword = input.GetBool();
        }
    }
    
    public class UETextInputMeta : UETextInputBaseMeta
    {

    }
    public class UETextInputMultilineMeta : UETextInputBaseMeta
    {

    }

    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 多行文本
    /// </summary>
    abstract public class UETextBoxBaseMeta : UIComponentMeta
    {
        public int text_size;
        public uint textColor;
        public uint text_shadow_dcolor;
        public float text_shadow_alpha;
        public float text_shadow_x, text_shadow_y;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Decode_Text(e);
        }
        private void Decode_Text(XmlNode e)
        {
            string value;
            if (XmlUtil.TryGetAttribute(e, "text_size", out value))
            {
                this.text_size = int.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "textColor", out value))
            {
                this.textColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "text_shadow_x", out value))
            {
                this.text_shadow_x = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "text_shadow_y", out value))
            {
                this.text_shadow_y = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "text_shadow_dcolor", out value))
            {
                this.text_shadow_dcolor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "text_shadow_alpha", out value))
            {
                this.text_shadow_alpha = float.Parse(value);
            }
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutS32(text_size);
            output.PutU32(textColor);
            output.PutU32(text_shadow_dcolor);
            output.PutF32(text_shadow_alpha);
            output.PutF32(text_shadow_x);
            output.PutF32(text_shadow_y);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.text_size = input.GetS32();
            this.textColor = input.GetU32();
            this.text_shadow_dcolor = input.GetU32();
            this.text_shadow_alpha = input.GetF32();
            this.text_shadow_x = input.GetF32();
            this.text_shadow_y = input.GetF32();
        }
    }
    /// <summary>
    /// 普通多行文本
    /// </summary>
    public class UETextBoxMeta : UETextBoxBaseMeta
    {
        public string Text;
        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Text = XmlUtil.GetAttribute(e, "Text", false);
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutUTF(Text);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.Text = input.GetUTF();
        }
    }
    /// <summary>
    /// 多行富文本
    /// </summary>
    public class UETextBoxHtmlMeta : UETextBoxBaseMeta
    {
        public string HtmlText;
        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.HtmlText = XmlUtil.GetAttribute(e, "HtmlText", false);
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutUTF(HtmlText);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.HtmlText = input.GetUTF();
        }
    }
    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 文件节点
    /// </summary>
    public class UEFileNodeMeta : UIComponentMeta
    {
        public string fileName;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.fileName = e.Attributes["fileName"].Value;
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutUTF(fileName);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.fileName = input.GetUTF();
        }
    }
    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 滚动框
    /// </summary>
    public class UEScrollPanMeta : UIComponentMeta
    {
        public bool EnableElasticity;
        public bool EnableScrollH, EnableScrollV;
        public float BorderSize;
        public bool ShowSlider;

        public float scroll_fade_time_max;

        public UILayoutMeta layout_scroll_v, layout_scroll_h;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.EnableElasticity = bool.Parse(e.Attributes["EnableElasticity"].Value);

            this.EnableScrollH = bool.Parse(e.Attributes["EnableScrollH"].Value);
            this.EnableScrollV = bool.Parse(e.Attributes["EnableScrollV"].Value);

            this.BorderSize = float.Parse(e.Attributes["BorderSize"].Value);
            this.ShowSlider = bool.Parse(e.Attributes["ShowSlider"].Value);

            this.scroll_fade_time_max = float.Parse(e.Attributes["scroll_fade_time_max"].Value);

            this.layout_scroll_v = UIEditorMeta.CreateLayout(XmlUtil.FindChild(e, "layout_scroll_v"));
            this.layout_scroll_h = UIEditorMeta.CreateLayout(XmlUtil.FindChild(e, "layout_scroll_h"));
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutBool(this.EnableElasticity);
            output.PutBool(this.EnableScrollH);
            output.PutBool(this.EnableScrollV);
            output.PutF32(this.BorderSize);
            output.PutBool(this.ShowSlider);
            output.PutF32(this.scroll_fade_time_max);
            output.PutExt(this.layout_scroll_v);
            output.PutExt(this.layout_scroll_h);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.EnableElasticity = input.GetBool();
            this.EnableScrollH = input.GetBool();
            this.EnableScrollV = input.GetBool();
            this.BorderSize = input.GetF32();
            this.ShowSlider = input.GetBool();
            this.scroll_fade_time_max = input.GetF32();
            this.layout_scroll_v = input.GetExt<UILayoutMeta>();
            this.layout_scroll_h = input.GetExt<UILayoutMeta>();
        }
    }
    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 抽象文本
    /// </summary>
    abstract public class UETextComponentMeta : UIComponentMeta
    {
        public string text;
        public TextAnchor text_anchor;
        public string textFontName;
        public FontStyle textFontStyle;
        public int textFontSize;
        public uint textColor;
        public uint textBorderColor;
        public float textBorderAlpha;
        public float text_offset_x, text_offset_y;

        public string ImageFont;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Decode_Text(e);
        }

        private void Decode_Text(XmlNode e)
        {
            this.text = XmlUtil.GetAttribute(e, "text", false);
            string value;
            if (XmlUtil.TryGetAttribute(e, "text_anchor", out value))
            {
                this.text_anchor = (TextAnchor)Enum.Parse(typeof(TextAnchor), value, true);
            }
            if (XmlUtil.TryGetAttribute(e, "textFont", out value))
            {
                string[] info = value.Split(',');
                this.textFontName = info[0];
                this.textFontSize = int.Parse(info[1]);
                this.textFontStyle = (FontStyle)Enum.ToObject(typeof(FontStyle), int.Parse(info[2]));
            }
            if (XmlUtil.TryGetAttribute(e, "textFontSize", out value))
            {
                this.textFontSize = int.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "textColor", out value))
            {
                this.textColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "textBorderColor", out value))
            {
                this.textBorderColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "textBorderAlpha", out value))
            {
                this.textBorderAlpha = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "text_offset_x", out value))
            {
                this.text_offset_x = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "text_offset_y", out value))
            {
                this.text_offset_y = float.Parse(value);
            }
            this.ImageFont = XmlUtil.GetAttribute(e, "ImageFont");
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutUTF(this.text);
            output.PutEnum32(this.text_anchor);
            output.PutUTF(this.textFontName);
            output.PutEnum32(this.textFontStyle);
            output.PutS32(this.textFontSize);
            output.PutU32(this.textColor);
            output.PutU32(this.textBorderColor);
            output.PutF32(this.textBorderAlpha);
            output.PutF32(this.text_offset_x);
            output.PutF32(this.text_offset_y);
            output.PutUTF(this.ImageFont);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.text = input.GetUTF();
            this.text_anchor = input.GetEnum32<TextAnchor>();
            this.textFontName = input.GetUTF();
            this.textFontStyle = input.GetEnum32<FontStyle>();
            this.textFontSize = input.GetS32();
            this.textColor = input.GetU32();
            this.textBorderColor = input.GetU32();
            this.textBorderAlpha = input.GetF32();
            this.text_offset_x = input.GetF32();
            this.text_offset_y = input.GetF32();
            this.ImageFont = input.GetUTF();
        }
    }
    /// <summary>
    /// 文本标签
    /// </summary>
    public class UELabelMeta : UETextComponentMeta
    {
        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
        }
    }
    /// <summary>
    /// 进度
    /// </summary>
    public class UEGaugeMeta : UETextComponentMeta
    {
        public double gaugeMax, gaugeMin, gaugeValue;
        public GaugeOrientation render_orientation;
        public bool showPercent;

        public UILayoutMeta custom_layout_up;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Decode_Gauge(e);
        }
        private void Decode_Gauge(XmlNode e)
        {
            string value;
            if (XmlUtil.TryGetAttribute(e, "gaugeMax", out value))
            {
                this.gaugeMax = double.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "gaugeMin", out value))
            {
                this.gaugeMin = double.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "gaugeValue", out value))
            {
                this.gaugeValue = double.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "render_orientation", out value))
            {
                this.render_orientation = (GaugeOrientation)Enum.Parse(typeof(GaugeOrientation), value, true);
            }
            if (XmlUtil.TryGetAttribute(e, "showPercent", out value))
            {
                this.showPercent = bool.Parse(value);
            }
            this.custom_layout_up = UIEditorMeta.CreateLayout(XmlUtil.FindChild(e, "custom_layout_up"));
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutF64(this.gaugeMax);
            output.PutF64(this.gaugeMin);
            output.PutF64(this.gaugeValue);
            output.PutEnum32(this.render_orientation);
            output.PutBool(this.showPercent);
            output.PutExt(this.custom_layout_up);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.gaugeMax = input.GetF64();
            this.gaugeMin = input.GetF64();
            this.gaugeValue = input.GetF64();
            this.render_orientation = input.GetEnum32<GaugeOrientation>();
            this.showPercent = input.GetBool();
            this.custom_layout_up = input.GetExt<UILayoutMeta>();
        }
    }
    /// <summary>
    /// 单选框
    /// </summary>
    public class UECheckBoxMeta : UETextComponentMeta
    {
        public bool is_checked;
        public string imagePathChecked, imagePathUnchecked;
        public string imageAtlasChecked, imageAtlasUnchecked;
        public ImageAnchor imageAnchor;
        public float imageOffsetX, imageOffsetY;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.Decode_ImageText(e);
            string value;
            if (XmlUtil.TryGetAttribute(e, "checked", out value))
            {
                this.is_checked = bool.Parse(value);
            }
        }

        private void Decode_ImageText(XmlNode e)
        {
            string value;
            if (XmlUtil.TryGetAttribute(e, "imageAtlasUnchecked", out value))
            {
                this.imageAtlasUnchecked = value;
            }
            else if (XmlUtil.TryGetAttribute(e, "imagePathUnchecked", out value))
            {
                this.imagePathUnchecked = value;
            }
            if (XmlUtil.TryGetAttribute(e, "imageAtlasChecked", out value))
            {
                this.imageAtlasChecked = value;
            }
            else if (XmlUtil.TryGetAttribute(e, "imagePathChecked", out value))
            {
                this.imagePathChecked = value;
            }
            if (XmlUtil.TryGetAttribute(e, "imageAnchor", out value))
            {
                this.imageAnchor = (ImageAnchor)Enum.Parse(typeof(ImageAnchor), value, true);
            }
            if (XmlUtil.TryGetAttribute(e, "imageOffsetX", out value))
            {
                this.imageOffsetX = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "imageOffsetY", out value))
            {
                this.imageOffsetY = float.Parse(value);
            }
        }

        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutBool(this.is_checked);
            output.PutUTF(this.imagePathChecked);
            output.PutUTF(this.imagePathUnchecked);
            output.PutUTF(this.imageAtlasChecked);
            output.PutUTF(this.imageAtlasUnchecked);
            output.PutEnum32(this.imageAnchor);
            output.PutF32(this.imageOffsetX);
            output.PutF32(this.imageOffsetY);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            this.is_checked = input.GetBool();
            this.imagePathChecked = input.GetUTF();
            this.imagePathUnchecked = input.GetUTF();
            this.imageAtlasChecked = input.GetUTF();
            this.imageAtlasUnchecked = input.GetUTF();
            this.imageAnchor = input.GetEnum32<ImageAnchor>();
            this.imageOffsetX = input.GetF32();
            this.imageOffsetY = input.GetF32();
        }
    }
    //----------------------------------------------------------------------------------------------------------
    /// <summary>
    /// 抽象按钮
    /// </summary>
    abstract public class UEButtonMeta : UIComponentMeta
    {
        public UILayoutMeta layout_down;

        public string text;
        public string textDown;
        public TextAnchor text_anchor;
        public string textFontName;
        public FontStyle textFontStyle;
        public int textFontSize;
        public uint unfocusTextColor;
        public uint focusTextColor;
        public uint textBorderColor;
        public float textBorderAlpha;
        public float text_offset_x, text_offset_y;

        public string imageTextUp, imageTextDown;
        public string imageAtlasUp, imageAtlasDown;
        public ImageAnchor imageAnchor;
        public float imageOffsetX, imageOffsetY;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            this.layout_down = UIEditorMeta.CreateLayout(XmlUtil.FindChild(e, "layout_down"));
            this.Decode_Text(e);
            this.Decode_ImageText(e);
        }

        private void Decode_Text(XmlNode e)
        {
            this.text = XmlUtil.GetAttribute(e, "text", false);
            this.textDown = XmlUtil.GetAttribute(e, "textDown", false);
            string value;
            if (XmlUtil.TryGetAttribute(e, "text_anchor", out value))
            {
                this.text_anchor = (TextAnchor)Enum.Parse(typeof(TextAnchor), value, true);
            }
            if (XmlUtil.TryGetAttribute(e, "textFont", out value))
            {
                string[] info = value.Split(',');
                this.textFontName = info[0];
                this.textFontSize = int.Parse(info[1]);
                this.textFontStyle = (FontStyle)Enum.ToObject(typeof(FontStyle), int.Parse(info[2]));
            }
            if (XmlUtil.TryGetAttribute(e, "textSize", out value))
            {
                this.textFontSize = int.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "unfocusTextColor", out value))
            {
                this.unfocusTextColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "focusTextColor", out value))
            {
                this.focusTextColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "textBorderColor", out value))
            {
                this.textBorderColor = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
            }
            if (XmlUtil.TryGetAttribute(e, "textBorderAlpha", out value))
            {
                this.textBorderAlpha = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "text_offset_x", out value))
            {
                this.text_offset_x = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "text_offset_y", out value))
            {
                this.text_offset_y = float.Parse(value);
            }
        }

        private void Decode_ImageText(XmlNode e)
        {
            string value;
            if (XmlUtil.TryGetAttribute(e, "imageAtlasUp", out value))
            {
                this.imageAtlasUp = value;
            }
            else if (XmlUtil.TryGetAttribute(e, "imageTextUp", out value))
            {
                this.imageTextUp = value;
            }
            if (XmlUtil.TryGetAttribute(e, "imageAtlasDown", out value))
            {
                this.imageAtlasDown = value;
            }
            else if (XmlUtil.TryGetAttribute(e, "imageTextDown", out value))
            {
                this.imageTextDown = value;
            }
            if (XmlUtil.TryGetAttribute(e, "imageAnchor", out value))
            {
                this.imageAnchor = (ImageAnchor)Enum.Parse(typeof(ImageAnchor), value, true);
            }
            if (XmlUtil.TryGetAttribute(e, "imageOffsetX", out value))
            {
                this.imageOffsetX = float.Parse(value);
            }
            if (XmlUtil.TryGetAttribute(e, "imageOffsetY", out value))
            {
                this.imageOffsetY = float.Parse(value);
            }
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);

            output.PutExt(layout_down);

            output.PutUTF(text);
            output.PutUTF(textDown);
            output.PutEnum32(text_anchor);
            output.PutUTF(textFontName);
            output.PutEnum32(textFontStyle);
            output.PutS32(textFontSize);

            output.PutU32(unfocusTextColor);
            output.PutU32(focusTextColor);
            output.PutU32(textBorderColor);
            output.PutF32(textBorderAlpha);
            output.PutF32(text_offset_x);
            output.PutF32(text_offset_y);

            output.PutUTF(imageTextUp);
            output.PutUTF(imageTextDown);
            output.PutUTF(imageAtlasUp);
            output.PutUTF(imageAtlasDown);
            output.PutEnum32(imageAnchor);
            output.PutF32(imageOffsetX);
            output.PutF32(imageOffsetY);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);

            layout_down = input.GetExt<UILayoutMeta>();

            text = input.GetUTF();
            textDown = input.GetUTF();
            text_anchor = input.GetEnum32<TextAnchor>();
            textFontName = input.GetUTF();
            textFontStyle = input.GetEnum32<FontStyle>();
            textFontSize = input.GetS32();

            unfocusTextColor = input.GetU32();
            focusTextColor = input.GetU32();
            textBorderColor = input.GetU32();
            textBorderAlpha = input.GetF32();
            text_offset_x = input.GetF32();
            text_offset_y = input.GetF32();

            imageTextUp = input.GetUTF();
            imageTextDown = input.GetUTF();
            imageAtlasUp = input.GetUTF();
            imageAtlasDown = input.GetUTF();
            imageAnchor = input.GetEnum32<ImageAnchor>();
            imageOffsetX = input.GetF32();
            imageOffsetY = input.GetF32();
        }
    }
    /// <summary>
    /// 按钮
    /// </summary>
    public class UETextButtonMeta : UEButtonMeta
    {
        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
        }
    }
    /// <summary>
    /// 状态按钮
    /// </summary>
    public class UEToggleButtonMeta : UEButtonMeta
    {
        public bool isChecked;

        public override void DecodeFromXML(XmlNode e)
        {
            base.DecodeFromXML(e);
            string value;
            if (XmlUtil.TryGetAttribute(e, "isChecked", out value))
            {
                this.isChecked = bool.Parse(value);
            }
        }
        public override void WriteExternal(IOutputStream output)
        {
            base.WriteExternal(output);
            output.PutBool(isChecked);
        }
        public override void ReadExternal(IInputStream input)
        {
            base.ReadExternal(input);
            isChecked = input.GetBool();
        }
    }
    //----------------------------------------------------------------------------------------------------------
}