using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace MegaManRipoff.MainGameClasses
{
    /// <summary>
    /// The base class for all tiles.
    /// </summary>
    public class Tile
    {
        #region Member Variables

        /// <summary>
        /// The default width of the tile.
        /// </summary>
        public const int DEFAULT_WIDTH = 32;

        /// <summary>
        /// The default height of the tile.
        /// </summary>
        public const int DEFAULT_HEIGHT = 32;

        /// <summary>
        /// The default amount of friction that tiles give. This is used to give friction
        /// whilst an entity is airborne so that the user has extra control over the
        /// player's movements.
        /// </summary>
        public const float DEFAULT_FRICTION = 0.7f;

        /// <summary>
        /// The currently loaded tileset that all tiles in the current level
        /// will use.
        /// </summary>
        static Texture2D _texture;

        /// <summary>
        /// The position of the tile.
        /// </summary>
        protected Vector2 _position;

        /// <summary>
        /// The tile's hitbox.
        /// </summary>
        protected Rectangle _hitbox;

        /// <summary>
        /// The top-left position of the tile graphic inside the tileset.
        /// </summary>
        protected Point _textureOrigin;

        /// <summary>
        /// The amount of friction the tile gives to entities moving on top
        /// of it.
        /// </summary>
        protected float _friction;

        /// <summary>
        /// Determines if entities are able to collide with this tile.
        /// </summary>
        protected bool _isSolid;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the area this tile occupies.
        /// </summary>
        public Rectangle Hitbox
        {
            get { return _hitbox; }
        }

        /// <summary>
        /// Gets the amount of friction the tile gives to entities moving
        /// on top of it.
        /// </summary>
        public float Friction
        {
            get { return _friction; }
        }

        /// <summary>
        /// Gets whether or not entities are able to collide with this tile.
        /// </summary>
        public bool IsSolid
        {
            get { return _isSolid; }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new tile.
        /// </summary>
        /// <param name="position">The position to create the tile.</param>
        /// <param name="textureOrigin">The origin of the tile's graphic
        /// in the tileset.</param>
        protected Tile(Vector2 position, Point textureOrigin)
        {
            _position = position;
            _textureOrigin = textureOrigin;
            _hitbox = new Rectangle((int)_position.X, (int)_position.Y, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }

        /// <summary>
        /// Creates a new tile.
        /// </summary>
        /// <param name="position">The position to create the tile.</param>
        /// <param name="textureOrigin">The origin of the tile's graphic
        /// in the tileset.</param>
        /// <param name="hitbox">The tile's hitbox, relative to its position.</param>
        protected Tile(Vector2 position, Point textureOrigin, Rectangle hitbox)
        {
            _position = position;
            _textureOrigin = textureOrigin;

            //Offset the hitbox by the position of the tile, and then set it.
            hitbox.Offset((int)_position.X, (int)_position.Y);
            _hitbox = hitbox;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Loads the assets required for the tiles.
        /// </summary>
        /// <param name="content">The path for the tile's texture, relative to the
        /// Content directory.</param>
        public static void LoadContent(ContentManager content, string assetPath)
        {
            _texture = content.Load<Texture2D>(assetPath);
        }

        /// <summary>
        /// Draws the tile.
        /// </summary>
        /// <param name="spriteBatch">The sprite batch to draw to.</param>
        public virtual void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(_texture,
                             _position,
                             new Rectangle((int)_textureOrigin.X, (int)_textureOrigin.Y, DEFAULT_WIDTH, DEFAULT_HEIGHT),
                             Color.White,
                             0,
                             Vector2.Zero,
                             1,
                             SpriteEffects.None,
                             0.4f);
        }

        #endregion
    }
}
