{-# LANGUAGE UnicodeSyntax, FlexibleContexts #-}
module GraphRewriting.Layout.RotPortSpec
	(module GraphRewriting.Layout.RotPortSpec,
	 module GraphRewriting.Layout.Position,
	 module GraphRewriting.Layout.Rotation,
	 module GraphRewriting.Layout.PortSpec,
	 module GraphRewriting.Layout.Geometry,
	 module Data.Vector.V2,
	 module Data.View)
where


import GraphRewriting.Graph
import GraphRewriting.Graph.Read
import GraphRewriting.Layout.Position
import GraphRewriting.Layout.Rotation
import GraphRewriting.Layout.PortSpec
import GraphRewriting.Layout.Geometry
import Data.Vector.V2
import Data.View
import Control.Monad


rotPortSpec  (PortSpec n, View Rotation n)  n  [(Vector2, Vector2)]
rotPortSpec n = map (\(v, u)  (rot v, rot u)) (portSpec n)
	where rot = rotate (examine rotation n)

relRotPortPos  (PortSpec n, View Rotation n)  n  [Vector2]
relRotPortPos = map fst . rotPortSpec

absRotPortSpec  (PortSpec n, View Position n, View Rotation n)  n  [(Vector2, Vector2)]
absRotPortSpec n = map (\(p,d)  (examine position n + p, d)) $ rotPortSpec n

absRotPortPos  (PortSpec n, View Position n, View Rotation n)  n  [Vector2]
absRotPortPos = map fst . absRotPortSpec

angularMomentum  (View Position n, PortSpec n, View Rotation n, View [Port] n)  Node  WithGraph n Momentum
angularMomentum n = do
	nv  readNode n
	let npos = examine position nv
	let edgePortions e = do
		let nps = propOfPort portDir e nv
		ns  mapM readNode =<< adverseNodes n e
		let nsps = concatMap (propOfPort absRotPortPos e) ns
		let angles = [angle np (nsp - npos) | np  nps, nsp  nsps]
		return $ map (approach . Rotation) angles
	liftM (momSum . concat) (mapM edgePortions =<< attachedEdges n)