using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace ProjektZKomponentem
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Prostopadloscian : Microsoft.Xna.Framework.DrawableGameComponent
    {
        GraphicsDevice gd;
        BasicEffect efekt;
        VertexBuffer buforWerteksów;

        //public bool AutomatycznyRuch = false;
        public Matrix World
        {
            get
            {
                return efekt.World;
            }
            set
            {
                efekt.World = value;
            }
        }

        public Texture2D Texture
        {
            get
            {
                return efekt.Texture;
            }
            set
            {
                efekt.Texture = value;
            }
        }


        public Prostopadloscian(Game game,BasicEffect efekt,float dx,float dy,float dz,Color? kolor)
            : base(game)
        {
            dx /= 2;
            dy /= 2;
            dz /= 2;

            gd = game.GraphicsDevice;
            this.efekt = (BasicEffect)efekt.Clone();

            Vector3[] punkty = new Vector3[8]
            {
                new Vector3(-dx,-dy,dz), //0
                new Vector3(dx,-dy,dz),  //1
                new Vector3(dx,dy,dz),   //2
                new Vector3(-dx,dy,dz),  //3
                new Vector3(-dx,-dy,-dz),
                new Vector3(dx,-dy,-dz),
                new Vector3(dx,dy,-dz),
                new Vector3(-dx,dy,-dz)
            };

            Vector2 t00 = new Vector2(0, 0);
            Vector2 t01 = new Vector2(0, 1);
            Vector2 t10 = new Vector2(1, 0);
            Vector2 t11 = new Vector2(1, 1);

            Color kolor1 = (kolor == null) ? Color.Cyan : kolor.Value;
            Color kolor2 = (kolor == null) ? Color.Magenta : kolor.Value;
            Color kolor3 = (kolor == null) ? Color.Yellow : kolor.Value;

            VertexPositionColorNormalTexture[] werteksy = new VertexPositionColorNormalTexture[6 * 4]
            {
                //przednia ściana
                new VertexPositionColorNormalTexture(punkty[3],kolor1,Vector3.UnitZ,t01),
                new VertexPositionColorNormalTexture(punkty[2],kolor1,Vector3.UnitZ,t11),
                new VertexPositionColorNormalTexture(punkty[0],kolor1,Vector3.UnitZ,t00),
                //new VertexPositionColorNormal(punkty[0],kolor1),
                //new VertexPositionColorNormal(punkty[2],kolor1),
                new VertexPositionColorNormalTexture(punkty[1],kolor1,Vector3.UnitZ,t10),

                //tylnia ściana
                new VertexPositionColorNormalTexture(punkty[7],kolor1,-Vector3.UnitZ,t00),
                new VertexPositionColorNormalTexture(punkty[4],kolor1,-Vector3.UnitZ,t01),
                new VertexPositionColorNormalTexture(punkty[6],kolor1,-Vector3.UnitZ,t10),
                //new VertexPositionColorNormal(punkty[6],kolor1),
                //new VertexPositionColorNormal(punkty[4],kolor1),
                new VertexPositionColorNormalTexture(punkty[5],kolor1,-Vector3.UnitZ,t11),

                //górna ściana
                new VertexPositionColorNormalTexture(punkty[3],kolor2,Vector3.UnitY,t00),
                new VertexPositionColorNormalTexture(punkty[7],kolor2,Vector3.UnitY,t01),
                new VertexPositionColorNormalTexture(punkty[2],kolor2,Vector3.UnitY,t10),
                //new VertexPositionColorNormal(punkty[2],kolor2),
                //new VertexPositionColorNormal(punkty[7],kolor2),
                new VertexPositionColorNormalTexture(punkty[6],kolor2,Vector3.UnitY,t11),

                //dolna ściana
                new VertexPositionColorNormalTexture(punkty[0],kolor2,-Vector3.UnitY,t00),
                new VertexPositionColorNormalTexture(punkty[1],kolor2,-Vector3.UnitY,t01),
                new VertexPositionColorNormalTexture(punkty[4],kolor2,-Vector3.UnitY,t10),
                //new VertexPositionColorNormal(punkty[4],kolor2),
                //new VertexPositionColorNormal(punkty[1],kolor2),
                new VertexPositionColorNormalTexture(punkty[5],kolor2,-Vector3.UnitY,t11),

                //lewa ściana
                new VertexPositionColorNormalTexture(punkty[3],kolor3,-Vector3.UnitX,t00),
                new VertexPositionColorNormalTexture(punkty[0],kolor3,-Vector3.UnitX,t01),
                new VertexPositionColorNormalTexture(punkty[7],kolor3,-Vector3.UnitX,t10),
                //new VertexPositionColorNormal(punkty[7],kolor3),
                //new VertexPositionColorNormal(punkty[0],kolor3),
                new VertexPositionColorNormalTexture(punkty[4],kolor3,-Vector3.UnitX,t11),

                //prawa ściana
                new VertexPositionColorNormalTexture(punkty[1],kolor3,Vector3.UnitX,t00),
                new VertexPositionColorNormalTexture(punkty[2],kolor3,Vector3.UnitX,t01),
                new VertexPositionColorNormalTexture(punkty[5],kolor3,Vector3.UnitX,t10),
                //new VertexPositionColorNormal(punkty[5],kolor3),
                //new VertexPositionColorNormal(punkty[2],kolor3),
                new VertexPositionColorNormalTexture(punkty[6],kolor3,Vector3.UnitX,t11)
            };

            buforWerteksów = new VertexBuffer(
                gd,
                VertexPositionColorNormalTexture.VertexDeclaration,
                werteksy.Count(),
                BufferUsage.WriteOnly);
            buforWerteksów.SetData(werteksy);
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            /*
            if (AutomatycznyRuch)
            {
                efekt.World *=
                    Matrix.CreateRotationX(gameTime.ElapsedGameTime.Milliseconds / 2000.0f) *
                    Matrix.CreateRotationY(gameTime.ElapsedGameTime.Milliseconds / 2000.0f);
                    //Matrix.CreateRotationZ(gameTime.ElapsedGameTime.Milliseconds / 2000.0f);
            }
            */

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            gd.SetVertexBuffer(buforWerteksów);
            foreach (EffectPass p in efekt.CurrentTechnique.Passes)
            {
                p.Apply();
                //gd.DrawPrimitives(PrimitiveType.TriangleList, 0, 6 * 2);
                for(int i=0;i<6;++i) gd.DrawPrimitives(PrimitiveType.TriangleStrip, i*4, 2);
            }
            
            base.Draw(gameTime);
        }
    }
}
