using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace CSGBuilder {
    [Serializable()]
    class Cuboid : Solid {
        public static int counter = 1;

        // A téglatest méretei
        private double width, height, depth;

        #region Public properties
        public double Width {
            get { return width; }
            set { width = value; }
        }

        public double Height {
            get { return height; }
            set { height = value; }
        }

        public double Depth {
            get { return depth; }
            set { depth = value; }
        }
        #endregion

        public Cuboid(double width, double height, double depth, Point3D ct) {
            this.width = width;
            this.height = height;
            this.depth = depth;
            if (ct == null) this.center = new Point3D(0.0, 0.0, 0.0); else this.center = ct;
            // A tengelyek irányvektorai
            this.e1 = new Point3D(width / 2, 0.0, 0.0);
            this.e2 = new Point3D(0.0, height / 2, 0.0);
            this.e3 = new Point3D(0.0, 0.0, depth / 2);
            // A befoglaló téglatest
            this.UpperCorner = new Point3D(width / 2, height / 2, depth / 2);
            this.LowerCorner = new Point3D(-width / 2, -height / 2, -depth / 2);
            // A primitív tesszellációja
            MeshTesselation();            
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context) {
            base.GetObjectData(info, context);
            info.AddValue("Width", width);
            info.AddValue("Height", height);
            info.AddValue("Depth", depth);
        }

        public Cuboid(SerializationInfo info, StreamingContext context) : base(info, context) {
            width = info.GetDouble("Width");
            height = info.GetDouble("Height");
            depth = info.GetDouble("Depth");
        }


        public override string SolidType() {
            return "Cuboid";
        }

        // A kocka tesszellációja
        public override void MeshTesselation() {
            mesh = new BRep();

            // Csúcsok
            #region Vertices
            mesh.Vertices.Add(new Point3D(LowerCorner.X, LowerCorner.Y, LowerCorner.Z)); // 0
            mesh.Vertices.Add(new Point3D(UpperCorner.X, LowerCorner.Y, LowerCorner.Z)); // 1
            mesh.Vertices.Add(new Point3D(UpperCorner.X, UpperCorner.Y, LowerCorner.Z)); // 2
            mesh.Vertices.Add(new Point3D(LowerCorner.X, UpperCorner.Y, LowerCorner.Z)); // 3
            mesh.Vertices.Add(new Point3D(UpperCorner.X, LowerCorner.Y, UpperCorner.Z)); // 4 
            mesh.Vertices.Add(new Point3D(UpperCorner.X, UpperCorner.Y, UpperCorner.Z)); // 5
            mesh.Vertices.Add(new Point3D(LowerCorner.X, UpperCorner.Y, UpperCorner.Z)); // 6
            mesh.Vertices.Add(new Point3D(LowerCorner.X, LowerCorner.Y, UpperCorner.Z)); // 7
            #endregion

            // Élek
            #region Edges
            mesh.Edges.Add(new Edge(0, 1));
            mesh.Edges.Add(new Edge(1, 2));
            mesh.Edges.Add(new Edge(2, 3));
            mesh.Edges.Add(new Edge(3, 0));

            mesh.Edges.Add(new Edge(4, 5));
            mesh.Edges.Add(new Edge(5, 6));
            mesh.Edges.Add(new Edge(6, 7));
            mesh.Edges.Add(new Edge(7, 4));

            mesh.Edges.Add(new Edge(1, 4));
            mesh.Edges.Add(new Edge(2, 5));
            mesh.Edges.Add(new Edge(3, 6));
            mesh.Edges.Add(new Edge(0, 7));
            #endregion

            // Lapok
            #region Faces
            mesh.Faces.Add(new Face(1, 0, 3));
            mesh.Faces.Add(new Face(2, 1, 3));
            mesh.Faces.Add(new Face(4, 1, 5));
            mesh.Faces.Add(new Face(5, 1, 2));
            mesh.Faces.Add(new Face(7, 4, 5));
            mesh.Faces.Add(new Face(7, 5, 6));
            mesh.Faces.Add(new Face(3, 0, 6));
            mesh.Faces.Add(new Face(7, 6, 0));
            mesh.Faces.Add(new Face(0, 1, 7));
            mesh.Faces.Add(new Face(7, 1, 4));
            mesh.Faces.Add(new Face(5, 3, 6));
            mesh.Faces.Add(new Face(2, 3, 5));
            #endregion

            // a lapok további felosztása
            //ProcessLongFaces();
        }

        public override void ChangeParams() {
            NewCuboid ns = new NewCuboid();
            ns.Text = "Modify Cuboid";
            ns.tbWidth.Text = this.Width.ToString();
            ns.tbHeight.Text = this.Height.ToString();
            ns.tbDepth.Text = this.Depth.ToString();
            if (this.center.X != 0.0 || this.center.Y != 0.0 || this.center.Z != 0.0) {
                ns.cbCenter.Checked = false;
                ns.tbCX.Text = this.center.X.ToString();
                ns.tbCY.Text = this.center.Y.ToString();
                ns.tbCZ.Text = this.center.Z.ToString();
            } else ns.cbCenter.Checked = true;
            if (ns.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) return;
            this.width = ns.width;
            this.height = ns.height;
            this.depth = ns.depth;
            if (ns.cbCenter.Checked)
                this.center = new Point3D(0.0, 0.0, 0.0);
            else
                this.center = new Point3D(ns.cx, ns.cy, ns.cz);
            this.e1 = new Point3D(width / 2, 0.0, 0.0);
            this.e2 = new Point3D(0.0, height / 2, 0.0);
            this.e3 = new Point3D(0.0, 0.0, depth / 2);
            // A befoglaló téglatest
            this.UpperCorner = new Point3D(width / 2, height / 2, depth / 2);
            this.LowerCorner = new Point3D(-width / 2, -height / 2, -depth / 2);
            // A primitív tesszellációja
            base.ChangeParams();
        }
    }
}
