{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}

{- | Basic Types -}
module Haskengl.Types (DisplayableObject(..), DisplayableObjects(..), Model(..), model, AbsoluteObject(..), Point(..), point) where

-- IMPORTS --

import qualified Graphics.Rendering.OpenGL as GL

import Relude

-- TYPES --

-- io --

type DisplayableObjects = [DisplayableObject]

data DisplayableObject =
  DisplayableObject
    GL.VertexArrayObject -- ^ VAO
    AbsoluteObject
    GL.NumArrayIndices -- ^ The length of the array / number of vertides
    GL.NumComponents -- ^ Dimensionality of the array element; 4 for vec4
    GL.PrimitiveMode -- ^ How to render the VAO

-- model --

-- | state
data Model = Model
               { objects :: DisplayableObjects
               }

-- absolute objects

-- | object with a defined position
data AbsoluteObject
  = AbsoluteObject [AbsoluteObject]
  | AbsolutePoint Point
  | PinnedRelativeObject Point RelativeObject

data Point
  = Point
      { x :: Float
      , y :: Float
      , z :: Float
      , k :: Float
      }

-- | straight line between 2 points
data Line
  = Line Point Point

-- | triangle between 3 points
data Triangle
  = Triangle Point Point Point

-- relative objects

-- | object without a defined position
data RelativeObject
  = RelativeObject [RelativeObject]
  | RelativeHVolume HVolume
  | RelativeVolume Volume
  | RelativeSurface Surface

-- | hyper volume
data HVolume
  = HSphere Float
  | HPrism Float Volume

data Volume
  = Sphere Float
  | Prism Float Surface

data Surface
  = Circle Float
  | Square Float 

-- CONSTRUCTORS --

model :: Model
model =
  Model
    { objects = []
    }

-- absolutes

point :: Point
point =
  Point
    { x = 0
    , y = 0
    , z = 0
    , k = 0
    }

origin :: Point
origin = point

line :: Line
line = Line point point

triangle :: Triangle
triangle = Triangle point point point

-- relatives

hSphere :: HVolume
hSphere = HSphere 1

hPrism :: HVolume
hPrism = HPrism 1 prism

-- Volumes

sphere :: Volume
sphere = Sphere 1 

prism :: Volume
prism = Prism 1 square

circle :: Surface
circle = Circle 1

square :: Surface
square = Square 1
