from dataclasses import dataclass
from typing import Optional

from ray import Ray
from surface import Surface
from util import minpos
from vector import Vector


@dataclass
class Plane(Surface):
  refraction_index: float
  r0: Vector
  normal: Vector

  def __post_init__(self):
    self.normal = self.normal.normalize()

  def __and__(self, v: Vector) -> bool:
    return self.normal % (self.r0 - v)

  def __contains__(self, v: Vector) -> bool:
    proj = (self.r0 - v) @ self.normal
    return self & v or proj > 0

  def normal_at(self, r: Vector) -> Vector:
    return self.normal

  def intersect(self, ray: Ray) -> Optional[float]:
    if self.normal % ray.e:
      return None

    t = (self.normal @ (self.r0 - ray.r0)) / (self.normal @ ray.e)

    return minpos([t])
