{-# LANGUAGE DeriveDataTypeable #-}
{- |
Module      :  $Header$
Description :  definition of the datatype describing
               the abstract FreeCAD terms and and a few tools describing simple
               mathematical operations on those building-blocks (3d vectors,
               rotation matrices, rotation quaternions)
Copyright   :  (c) Robert Savu and Uni Bremen 2011
License     :  GPLv2 or higher, see LICENSE.txt

Maintainer  :  Robert.Savu@dfki.de
Stability   :  experimental
Portability :  portable

Declaration of the abstract datatypes of FreeCAD terms
-}

module FreeCAD.As where

import Data.Data
import qualified Data.Set as Set

data Vector3 =
  Vector3 { x :: Double, y :: Double, z :: Double }
  deriving (Show, Eq, Ord, Typeable, Data)

data Matrix33 = Matrix33 { a11 :: Double , a12 :: Double , a13 :: Double
                            , a21 :: Double , a22 :: Double , a23 :: Double
                            , a31 :: Double , a32 :: Double , a33 :: Double
                         } deriving (Show, Eq, Ord, Typeable, Data)
  -- used as a rotation matrix

data Vector4 = Vector4 { q0 :: Double, q1 :: Double, q2 :: Double, q3 :: Double}
               deriving (Show, Eq, Ord, Typeable, Data)
-- quaternion rotational representation

data Placement = Placement { position :: Vector3, orientation :: Vector4 }
                 deriving (Show, Eq, Ord, Typeable, Data)

{-
--   the placement is determined by 2 vectors:
--   the first one points to the 'center' of the objet in the space
--   the second one determines the orientation of the object in the given space
data Edgelist = []
              | 1:Edgelist
              | 0:Edgelist

  reference from compound objects to 'building-blocks'
  objects made through strings or containment of the other
  objects
-}
data BaseObject = Box Double Double Double -- Height, Width, Length
            | Cylinder Double Double Double -- Angle, Height, Radius
            | Sphere Double Double Double Double -- Angle1,Angle2,Angle3,Radius
            | Cone Double Double Double Double -- Angle,Radius1,Radius2,Height
            | Torus Double Double Double Double Double
            -- Angle1, Angle2, Angle3, Radius1, Radius2
            | Line Double -- length
            | Circle Double Double Double -- StartAngle, EndAngle, Radius
            | Rectangle Double Double -- Height, Length
            deriving (Show, Eq, Ord, Typeable, Data)
          -- TODO: Plane, Vertex, etc..

data Object = BaseObject BaseObject
            | Cut ExtendedObject ExtendedObject
            | Common ExtendedObject ExtendedObject
            | Fusion ExtendedObject ExtendedObject
            | Extrusion ExtendedObject Vector3
            | Section ExtendedObject ExtendedObject
            deriving (Show, Eq, Ord, Typeable, Data)

{- --| Fillet, (Base::String, Edges::Edgelist, Radius::Double)),
            --not enough data in the xml
            --| Chamfer, (Base::String, Edges::Edgelist, Amount::Double)),
            --not enough data in the xml
            --| Mirror, (Base::String, Position2::Vector))
            --mirroring of an object
-}

data ExtendedObject = Placed PlacedObject | Ref String
  deriving (Show, Eq, Ord, Typeable, Data)

data PlacedObject =
  PlacedObject {p :: Placement, o :: Object}
  deriving (Show, Eq, Ord, Typeable, Data)

data NamedObject = NamedObject { name :: String
                   , object :: PlacedObject}
                 | EmptyObject -- for objects that are WIP
                   deriving (Show, Eq, Ord, Typeable, Data)

{- the first parameter is the name of the object as it is stored in the
FreeCAD document. the second parameter determines the placement of the object
(a pair of vectors) the third parameter contains the type of the object and
a list of doubles (numbers) describing the characteristics
of the object (e.g. dimensions, angles, etc) -}

type Document = [NamedObject]

{- | Datatype for FreeCAD Signatures
Signatures are just sets of named objects -}

data Sign = Sign { objects :: Set.Set NamedObject }
  deriving (Show, Eq, Ord, Typeable, Data)
