using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

namespace MojaDrugaGraMonoGame
{
    class Prostopadloscian : DrawableGameComponent
    {
        GraphicsDevice gd;
        BasicEffect efekt;
        VertexBuffer buforWerteksow;

        public Matrix World
        {
            set
            {
                efekt.World = value;
            }
            get
            {
                return efekt.World;
            }
        }

        public Matrix View
        {
            set
            {
                efekt.View = value;
            }
            get
            {
                return efekt.View;
            }
        }

        public bool TextureEnabled
        {
            set
            {
                efekt.TextureEnabled = value;
            }
            get
            {
                return efekt.TextureEnabled;
            }
        }

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

        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),
                new Vector3(dx, -dy, dz),
                new Vector3(dx, dy, dz),
                new Vector3(-dx, dy, dz),
                new Vector3(-dx, -dy, -dz),
                new Vector3(dx, -dy, -dz),
                new Vector3(dx, dy, -dz),
                new Vector3(-dx, dy, -dz)                
            };

            Color kolor1 = kolor ?? Color.Cyan;
            Color kolor2 = kolor ?? Color.Magenta;
            Color kolor3 = kolor ?? Color.Yellow;

            float f13 = 1f / 3f;
            float f23 = 2f / 3f;
            float f12 = 0.5f;

            VertexPositionNormalTextureColor[] werteksy = new VertexPositionNormalTextureColor[6 * 4]
            {
                //przednia ściana
                new VertexPositionNormalTextureColor(punkty[3], Vector3.UnitZ, new Vector2(0, 0), kolor1),
                new VertexPositionNormalTextureColor(punkty[2], Vector3.UnitZ, new Vector2(f13, 0), kolor1),
                new VertexPositionNormalTextureColor(punkty[0], Vector3.UnitZ, new Vector2(0, f12), kolor1),
                new VertexPositionNormalTextureColor(punkty[1], Vector3.UnitZ, new Vector2(f13, f12), kolor1),
                //tylna ściana
                new VertexPositionNormalTextureColor(punkty[7], -Vector3.UnitZ, new Vector2(f23, 0), kolor1),
                new VertexPositionNormalTextureColor(punkty[4], -Vector3.UnitZ, new Vector2(f23, f12), kolor1),
                new VertexPositionNormalTextureColor(punkty[6], -Vector3.UnitZ, new Vector2(f13, 0), kolor1),
                new VertexPositionNormalTextureColor(punkty[5], -Vector3.UnitZ, new Vector2(f13, f12), kolor1),
                
                //górna ściana
                new VertexPositionNormalTextureColor(punkty[3], Vector3.UnitY, new Vector2(f23, f12), kolor2),
                new VertexPositionNormalTextureColor(punkty[7], Vector3.UnitY, new Vector2(f23, 0), kolor2),
                new VertexPositionNormalTextureColor(punkty[2], Vector3.UnitY, new Vector2(1, f12), kolor2),
                new VertexPositionNormalTextureColor(punkty[6], Vector3.UnitY, new Vector2(1, 0), kolor2),
                //dolna ściana
                new VertexPositionNormalTextureColor(punkty[0], -Vector3.UnitY, new Vector2(0, f12), kolor2),
                new VertexPositionNormalTextureColor(punkty[1], -Vector3.UnitY, new Vector2(f13, f12), kolor2),
                new VertexPositionNormalTextureColor(punkty[4], -Vector3.UnitY, new Vector2(0, 1), kolor2),
                new VertexPositionNormalTextureColor(punkty[5], -Vector3.UnitY, new Vector2(f13, 1), kolor2),
                
                //lewa ściana
                new VertexPositionNormalTextureColor(punkty[3], -Vector3.UnitX, new Vector2(f23, f12), kolor3),
                new VertexPositionNormalTextureColor(punkty[0], -Vector3.UnitX, new Vector2(f23, 1), kolor3),
                new VertexPositionNormalTextureColor(punkty[7], -Vector3.UnitX, new Vector2(f13, f12), kolor3),
                new VertexPositionNormalTextureColor(punkty[4], -Vector3.UnitX, new Vector2(f13, 1), kolor3),
                //prawa ściana
                new VertexPositionNormalTextureColor(punkty[1], Vector3.UnitX, new Vector2(f23, 1), kolor3),
                new VertexPositionNormalTextureColor(punkty[2], Vector3.UnitX, new Vector2(f23, f12), kolor3),
                new VertexPositionNormalTextureColor(punkty[5], Vector3.UnitX, new Vector2(1, 1), kolor3),
                new VertexPositionNormalTextureColor(punkty[6], Vector3.UnitX, new Vector2(1, f12), kolor3)
            };

            buforWerteksow = new VertexBuffer(
                gd,
                VertexPositionNormalTextureColor.VertexDeclaration,
                werteksy.Length,
                BufferUsage.WriteOnly);
            buforWerteksow.SetData<VertexPositionNormalTextureColor>(werteksy);
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            gd.SetVertexBuffer(buforWerteksow);

            foreach (EffectPass pass in efekt.CurrentTechnique.Passes)
            {
                pass.Apply();
                for (int i = 0; i < 6; ++i)
                    gd.DrawPrimitives(PrimitiveType.TriangleStrip, 4 * i, 2);
            }

            base.Draw(gameTime);
        }
    }
}
