using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using nft.framework.drawing;
using Microsoft.Xna.Framework.Graphics;
using System.Threading;
using System.IO;
using SysRect = System.Drawing.Rectangle;
using XnaColor = Microsoft.Xna.Framework.Color;
using System.Drawing;
using nft.framework;

namespace nft.xna
{
    public class XnaImageSource : IImageSrc
    {
        Texture2D texture;
        public readonly IFileSource File;
        int refcount;

        public XnaImageSource(IFileSource file)
        {
            this.File = file;            
        }

        /// <summary>
        /// Add reference
        /// </summary>
        public void AddRef()
        {
            if (Interlocked.Increment(ref refcount) == 1)
            {
                // First reference;
                using (Stream stream = File.OpenRead())
                {
                    texture = Texture2D.FromStream(XnaGraphicManager.GraphicsDevice, stream);
                }
            }
        }

        public Texture2D Texture2D
        {
            get { return texture; }
        }

        /// <summary>
        /// Release reference
        /// </summary>
        public void ReleaseRef()
        {
            if (Interlocked.Decrement(ref refcount) == 0)
            {
                // no reference
                if (texture != null)
                {
                    texture.Dispose();
                    texture = null;
                }
            }
        }

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

    
    public class XnaTexture : ITexture
    {
        public readonly XnaImageSource ImageSrc;

        /// <summary>
        /// Empty means that this texture uses whole image.
        /// </summary>
        public readonly SysRect Region;

        public XnaTexture(IImageSrc src, SysRect region)
        {
            this.ImageSrc = (XnaImageSource)src;
            this.Region = region;
        }

        public XnaTexture(IImageSrc src) : this(src, SysRect.Empty)
        {
        }

        public UInt32 GetPixel(int x, int y)
        {
            XnaColor [] color = new XnaColor[1];
            ImageSrc.AddRef();
            int width = ImageSrc.Texture2D.Width;
            ImageSrc.Texture2D.GetData<XnaColor>(color, x + y * width, 1);
            ImageSrc.ReleaseRef();
            return color[0].PackedValue;
        }

        public Size Size{
            get
            {
                return Region.Size;
            }
        }
    }
}
