using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using nft.framework.drawing;
using Microsoft.Xna.Framework.Graphics;
using DefaultEffect = StockEffects.DefaultEffect;

namespace nft.xna
{
    interface IDrawable
    {
        void RenderSelf(XnaSurface surface, DefaultEffect ef);
    }

    public class X3DObject : I3DObject, IDrawable
    {

        protected UInt32 _id = 0;
        protected object _tag;
        protected XnaFilter filter;
        protected float _bias = 0f;
        private XnaTexture texture;

        public X3DObject(UInt32 id, XnaTexture texture, object tag)
        {
            this._id = id;
            this._tag = tag;
            this.texture = texture;
            texture.ImageSrc.AddRef();
        }

        public X3DObject(UInt32 id, XnaTexture texture)
            : this(id, texture, null)
        {
        }

        public Texture2D Texture
        {
            get
            {
                return texture.ImageSrc.Texture2D;
            }
        }
        #region I3DObject implementation
        public UInt32 ID {
            get { return _id; }
            set { _id = value; }
        }

        public object Tag
        {
            get
            {
                return _tag;
            }
            set
            {
                _tag = value;
            }
        }

        public IEffectFilter Effect
        {
            get
            {
                return filter;
            }
            set
            {
                filter = (XnaFilter)value;
            }
        }

        public float DepthBias { 
            get { return _bias; }
            set { _bias = value;  }
        }
        #endregion

        public virtual void RenderSelf(XnaSurface surface, DefaultEffect ef)
        {
        }

        #region IDisposable 定型
        public virtual void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(Boolean disposing)
        {
            if (disposing && texture!=null)
            {
                texture.ImageSrc.ReleaseRef();
                texture = null;
            }
        }

        public bool IsDisposed
        { get { return texture == null; } }

        ~X3DObject()
        {
            Dispose(false);
        }
        #endregion
    }

    public class BillBoard : X3DObject, IBillboard
    {
        public BillBoard(UInt32 id, XnaTexture texture, object tag)
            : base(id, texture, tag)
        {
        }

        UInt32 id;
        Structure _anchor;
        PointF3D _offset;
        public ICubicStructure Anchor
        {
            get
            {
                return _anchor;
            }
            set
            {
                _anchor = (Structure)value;
            }
        }

        public PointF3D Offset
        {
            get
            {
                return _offset;
            }
            set
            {
                _offset = value;
            }
        }
    }
}
