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

namespace CSGBuilder {
    [Serializable()]
    public class Point3D : ISerializable {
        double x, y, z;
        Color color;

        public static Color defaultColor = Color.White;

        public Point3D(double xp, double yp, double zp) {
            x = xp; y = yp; z = zp; color = defaultColor;
        }

        #region ISerializable Members

        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            info.AddValue("X", x);
            info.AddValue("Y", y);
            info.AddValue("Z", z);
            info.AddValue("Color", color);
        }

        public Point3D(SerializationInfo info, StreamingContext context) {
            x = info.GetDouble("X");
            y = info.GetDouble("Y");
            z = info.GetDouble("Z");
            color = (Color)info.GetValue("Color", typeof(Color));
        }

        #endregion

        #region Public properties
        public double X { get { return x; } set { x = value; } }
        public double Y { get { return y; } set { y = value; } }
        public double Z { get { return z; } set { z = value; } }
        public Color Color { get { return color; } set { color = value; } }
        #endregion

        // Két vektor összege
        public static Point3D operator +(Point3D p1, Point3D p2) {
            return new Point3D(p1.X + p2.X, p1.Y + p2.Y, p1.Z + p2.Z);
        }

        // Két vektor különbsége
        public static Point3D operator -(Point3D p1, Point3D p2) {
            return new Point3D(p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z);
        }

        // Egy vektor skalárszorosa
        public static Point3D operator *(Point3D p, double d) {
            return new Point3D(p.X * d, p.Y * d, p.Z * d);
        }

        // Belső szorzat
        public static double operator *(Point3D p1, Point3D p2) {
            return (p1.X * p2.X + p1.Y * p2.Y + p1.Z * p2.Z);
        }

        // Vektoriális szorzat
        public static Point3D operator %(Point3D p1, Point3D p2) {
            return new Point3D(p1.Y * p2.Z - p1.Z * p2.Y, p1.Z * p2.X - p1.X * p2.Z, p1.X * p2.Y - p1.Y * p2.X);
        }

        // Vektor osztva skalárral
        public static Point3D operator /(Point3D p, double d) {
            return new Point3D(p.X / d, p.Y / d, p.Z / d);
        }

        // Vektor hossza
        public double Norm() {
            return System.Math.Sqrt(x * x + y * y + z * z);
        }

        // Vektor normáltja
        public void Normal() {
            double length = Math.Sqrt(x * x + y * y + z * z);
            if (length == 0.0) return;
            x /= length;
            y /= length;
            z /= length;
        }

        public override string ToString() {
            return x.ToString("F2") + ", " + y.ToString("F2") + ", " + z.ToString("F2");
        }

        public Point3D Clone() {
            Point3D p = new Point3D(x, y, z); p.Color = color;
            return p;
        }

    }
}
