using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;

namespace PongGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager _graphics;
        SpriteBatch _spriteBatch;

        // Game World

        SpriteFont font;

        Texture2D ballTexture;
        Rectangle ballRectangle;
        float ballX;
        float ballY;
        float ballXSpeed = 3;
        float ballYSpeed = 3;

        Texture2D lPaddleTexture;
        Rectangle lPaddleRectangle;
        float lPaddleSpeed = 6;
        float lPaddleY;
        int lPlayerScore;

        Texture2D rPaddleTexture;
        Rectangle rPaddleRectangle;
        float rPaddleY;
        int rPlayerScore;

        // Distance of paddles from screen edge
        int margin;

        // Game score message
        string message = "0:0";

        // Sound effects
        SoundEffect dingSound;
        SoundEffect explodeSound;


        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            _graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
            _graphics.IsFullScreen = true;

        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            font = Content.Load<SpriteFont>("MessageFont");

            ballTexture = Content.Load<Texture2D>("ball");
            lPaddleTexture = Content.Load<Texture2D>("lpaddle");
            rPaddleTexture = Content.Load<Texture2D>("rpaddle");

            ballRectangle = new Rectangle(
                0, 0,
                GraphicsDevice.Viewport.Width / 20,
                GraphicsDevice.Viewport.Width / 20);

            ballX = GraphicsDevice.Viewport.Width / 2;
            ballY = GraphicsDevice.Viewport.Height / 2;

            margin = GraphicsDevice.Viewport.Width / 20;

            lPaddleRectangle = new Rectangle(
                margin, 0,
                GraphicsDevice.Viewport.Width / 20,
                GraphicsDevice.Viewport.Height / 5);

            rPaddleRectangle = new Rectangle(
                GraphicsDevice.Viewport.Width - lPaddleRectangle.Width - margin, 0,
                GraphicsDevice.Viewport.Width / 20,
                GraphicsDevice.Viewport.Height / 5);

            lPaddleY = lPaddleRectangle.Y;
            rPaddleY = rPaddleRectangle.Y;

            //dingSound = Content.Load<SoundEffect>("ding");
            //explodeSound = Content.Load<SoundEffect>("explode");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            ballX = ballX + ballXSpeed;
            ballY = ballY + ballYSpeed;

            if (ballX < 0)
            {
                rPlayerScore++;
                message = lPlayerScore.ToString() + ":" + rPlayerScore.ToString();
                ballXSpeed = -ballXSpeed;
                //explodeSound.Play();
            }

            if (ballX + ballRectangle.Width > GraphicsDevice.Viewport.Width)
            {
                lPlayerScore++;
                message = lPlayerScore.ToString() + ":" + rPlayerScore.ToString();
                ballXSpeed = -ballXSpeed;
                //explodeSound.Play();
            }

            if (ballY < 0 || ballY + ballRectangle.Height > GraphicsDevice.Viewport.Height)
            {
                ballYSpeed = -ballYSpeed;
                //dingSound.Play();
            }

            ballRectangle.X = (int)(ballX + 0.5f);
            ballRectangle.Y = (int)(ballY + 0.5f);

            // Use touch to control the left paddle

            TouchCollection touches = TouchPanel.GetState();

            if (touches.Count > 0)
            {
                if (touches[0].Position.Y > GraphicsDevice.Viewport.Height / 2)
                {
                    TouchLocation x = touches[0];
                    lPaddleY = lPaddleY + lPaddleSpeed;
                }
                else
                {
                    lPaddleY = lPaddleY - lPaddleSpeed;
                }
            }

            lPaddleRectangle.Y = (int)(lPaddleY + 0.5f);

            // Make the right paddle always follow the ball

            rPaddleRectangle.Y = ballRectangle.Y;

            // Ball - Bat collisons

            if (ballRectangle.Intersects(lPaddleRectangle))
            {
                ballXSpeed = -ballXSpeed;
                //dingSound.Play();
            }

            if (ballRectangle.Intersects(rPaddleRectangle))
            {
                ballXSpeed = -ballXSpeed;
                //dingSound.Play();
            }


            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);


            _spriteBatch.Begin();

            float messageWidth = font.MeasureString(message).X;

            _spriteBatch.DrawString(
                font,
                message,
                new Vector2((GraphicsDevice.Viewport.Width - messageWidth) / 2, margin),
                Color.White);

            _spriteBatch.Draw(ballTexture, ballRectangle, Color.White);
            _spriteBatch.Draw(lPaddleTexture, lPaddleRectangle, Color.White);
            _spriteBatch.Draw(rPaddleTexture, rPaddleRectangle, Color.White);

            _spriteBatch.End();


            base.Draw(gameTime);
        }
    }
}
