
/****************************************************************************/
/*Copyright (c) 2011, Florent DEVILLE.                                      */
/*All rights reserved.                                                      */
/*                                                                          */
/*Redistribution and use in source and binary forms, with or without        */
/*modification, are permitted provided that the following conditions        */
/*are met:                                                                  */
/*                                                                          */
/* - Redistributions of source code must retain the above copyright         */
/*notice, this list of conditions and the following disclaimer.             */
/* - Redistributions in binary form must reproduce the above                */
/*copyright notice, this list of conditions and the following               */
/*disclaimer in the documentation and/or other materials provided           */
/*with the distribution.                                                    */
/* - The names of its contributors cannot be used to endorse or promote     */
/*products derived from this software without specific prior written        */
/*permission.                                                               */
/* - The source code cannot be used for commercial purposes without         */
/*its contributors' permission.                                             */
/*                                                                          */
/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       */
/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         */
/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS         */
/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE            */
/*COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,       */
/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,      */
/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;          */
/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER          */
/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT        */
/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN         */
/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           */
/*POSSIBILITY OF SUCH DAMAGE.                                               */
/****************************************************************************/

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace GE.Visualisation
{
    class Texture
    {
        /// <summary>
        /// The texture object
        /// </summary>
        protected Texture2D m_texture;

        protected const float m_defaultDepth = 0.5f;

        protected string m_name;

        protected string m_filename;

        /// <summary>
        /// Constructor
        /// </summary>
        public Texture() { }

        /// <summary>
        /// Load a texture
        /// </summary>
        /// <param name="content">content manager</param>
        /// <param name="assetName">texture name</param>
        /// <returns>true if succeeded or else false</returns>
        public bool loadTexture(ContentManager content, string assetName)
        {
            try
            {
                m_texture = content.Load<Texture2D>(assetName);
                m_name = assetName;
            }
            catch
            {
                return false;
            }

            return true;
        }

        public bool loadTexture(GraphicsDevice device, string filename)
        {
            System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open);
            m_texture = Texture2D.FromStream(device, fs);
            fs.Close();
            return true;
        }

        /// <summary>
        /// Display the texture
        /// </summary>
        /// <param name="sprite">SpriteBatch object</param>
        /// <param name="position">position</param>
        public void display(SpriteBatch sprite, Vector2 position)
        {
            Rectangle dest = new Rectangle((int)position.X, (int)position.Y, m_texture.Width, m_texture.Height);
            sprite.Draw(m_texture, dest, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, m_defaultDepth);
        }

        /// <summary>
        /// Display a texture with transparancy
        /// </summary>
        /// <param name="sprite">spritebatch object</param>
        /// <param name="position">position of the texture</param>
        /// <param name="alpha">alpha value for the alpha blending (0 to 255)</param>
        public void display(SpriteBatch sprite, Vector2 position, int alpha)
        {
            Rectangle dest = new Rectangle((int)position.X, (int)position.Y, m_texture.Width, m_texture.Height);
            sprite.Draw(m_texture, dest, null, new Color(255, 255, 255, alpha), 0, Vector2.Zero, 
                SpriteEffects.None, m_defaultDepth);
        }

        /// <summary>
        /// Display several times the texture.
        /// To be used from particle systems only.
        /// </summary>
        /// <param name="sprite">SpriteBatch object</param>
        /// <param name="xy">coordinates array</param>
        public void display(SpriteBatch sprite, float[] xy, int[] ttl)
        {
            for (int i = 0; i < xy.Length; i += 4)
            {
                if (ttl[i / 4] > 0)
                {
                    Rectangle dest = new Rectangle((int)xy[i], (int)xy[i + 1], m_texture.Width, m_texture.Height);
                    sprite.Draw(m_texture, dest, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, m_defaultDepth);
                }
            }
        }

        /// <summary>
        /// Display the texture (more options)
        /// </summary>
        /// <param name="sprite">Spritebatch object</param>
        /// <param name="position">position (relative to rotation center)</param>
        /// <param name="rotationCenter">the rotation center</param>
        /// <param name="orientation">the rotation angle (in radians)</param>
        /// <param name="scale">thee scale factor</param>
        public void display(SpriteBatch sprite, Vector2 position, Vector2 rotationCenter, float orientation,
            Vector2 scale)
        {
            //Rectangle dest = new Rectangle((int)position.X, (int)position.Y, m_texture.Width, m_texture.Height);
            
            sprite.Draw(m_texture, position, null, Color.White, orientation, rotationCenter, scale, 
                SpriteEffects.None, m_defaultDepth);
        }

        /// <summary>
        /// Display the texture (more options)
        /// </summary>
        /// <param name="sprite">Spritebatch object</param>
        /// <param name="position">position (relative to rotation center)</param>
        /// <param name="rotationCenter">the rotation center</param>
        /// <param name="orientation">the rotation angle (in radians)</param>
        /// <param name="scale">thee scale factor</param>
        /// <param name="alpha">tha alpha value for alpha blending</param>
        public void display(SpriteBatch sprite, Vector2 position, Vector2 rotationCenter, float orientation,
            Vector2 scale, int alpha)
        {
            Rectangle dest = new Rectangle((int)position.X, (int)position.Y, m_texture.Width, m_texture.Height);
            sprite.Draw(m_texture, position, null, new Color(255, 255, 255, (byte)alpha), orientation, rotationCenter, scale,
                SpriteEffects.None, m_defaultDepth);
        }

        /// <summary>
        /// Display the texture (more options)
        /// </summary>
        /// <param name="sprite">Spritebatch object</param>
        /// <param name="position">position (relative to rotation center)</param>
        /// <param name="rotationCenter">the rotation center</param>
        /// <param name="orientation">the rotation angle (in radians)</param>
        /// <param name="scale">thee scale factor</param>
        /// <param name="depth">the depth of the texture. 0 for front and 1 for back</param>
        public void display(SpriteBatch sprite, Vector2 position, Vector2 rotationCenter, float orientation,
            Vector2 scale, float depth)
        {
            Rectangle dest = new Rectangle((int)position.X, (int)position.Y, m_texture.Width, m_texture.Height);
            sprite.Draw(m_texture, position, null, Color.White, orientation, rotationCenter, scale,
                SpriteEffects.None, depth);
        }

        /// <summary>
        /// Name of the texture
        /// </summary>
        public string Name { get { return m_name; } }

        /// <summary>
        /// Filename of the texture
        /// </summary>
        public string Filename { get { return m_filename; } }

        /// <summary>
        /// Texture width
        /// </summary>
        public int Width { get { return m_texture.Width; } }

        /// <summary>
        /// Texture height
        /// </summary>
        public int Height { get { return m_texture.Height; } }
    }
}
