package tf.bug.fancade import tf.bug.shinji.{Arrow, ArrowLoop, Cartesian, Monoidal} object Fanscript { sealed trait Pin sealed trait Number extends Pin sealed trait Bool extends Pin sealed trait Vector extends Pin sealed trait Rotation extends Pin sealed trait Obj extends Pin sealed trait Constraint extends Pin sealed trait Pull extends Pin sealed trait T extends Pin sealed trait ×[A <: Pin, B <: Pin] extends Pin sealed trait →[A <: Pin, B <: Pin] case class Id[A <: Pin]() extends (A → A) case class AndThen[A <: Pin, B <: Pin, C <: Pin](f: A → B, g: B → C) extends (A → C) case class Swap[A <: Pin, B <: Pin]() extends ((A × B) → (B × A)) case class Deunit[A <: Pin]() extends (A → (T × A)) case class Unit[A <: Pin]() extends ((T × A) → A) case class Associate[A <: Pin, B <: Pin, C <: Pin]() extends (((A × B) × C) → (A × (B × C))) case class Duplicate[A <: Pin]() extends (A → (A × A)) case class Terminate[A <: Pin]() extends (A → T) case class Bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → B, g: C → D) extends ((A × C) → (B × D)) case class Loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)) extends (A → B) case object Z extends (T → Pull) object Builtin { case class NumberValue(number: Float) extends (T → Number) case class VectorValue(x: Float, y: Float, z: Float) extends (T → Vector) case class RotationValue(x: Float, y: Float, z: Float) extends (T → Rotation) case object TrueValue extends (T → Bool) case object FalseValue extends (T → Bool) case object InspectNumber extends ((Number × Pull) → Pull) case object InspectVector extends ((Vector × Pull) → Pull) case object InspectRotation extends ((Rotation × Pull) → Pull) case object InspectTruth extends ((Bool × Pull) → Pull) case object InspectObject extends ((Obj × Pull) → Pull) case object Win extends (Pull → Pull) case object Lose extends (Pull → Pull) case object SetScore extends ((Number × Pull) → Pull) case object SetCamera extends ((Vector × Rotation × Number × Pull) → Pull) case object SetLight extends ((Vector × Rotation × Pull) → Pull) case object ScreenSize extends (T → (Number × Number)) case object Accelerometer extends (T → Vector) case object CurrentFrame extends (T → Number) case object GetPosition extends (Obj → (Vector × Rotation)) case object SetPosition extends ((Obj × Vector × Rotation × Pull) → Pull) case object Raycast extends ((Vector × Vector) → (Bool × Vector × Obj)) case object GetSize extends (Obj → (Vector × Vector)) case object SetVisible extends ((Obj × Bool × Pull) → Pull) case object CreateObject extends ((Obj × Pull) → (Obj × Pull)) case object DestroyObject extends ((Obj × Pull) → Pull) case class PlaySound(loop: Boolean, sample: SoundSample) extends ((Number × Number × Pull) → (Number × Pull)) case object StopSound extends ((Number × Pull) → Pull) case object VolumePitch extends ((Number × Number × Number × Pull) → Pull) case object AddForce extends ((Obj × Vector × Vector × Vector × Vector × Pull) → Pull) case object GetVelocity extends (Obj → (Vector × Vector)) case object SetVelocity extends ((Obj × Vector × Vector × Pull) → Pull) case object SetLocked extends ((Obj × Vector × Vector × Pull) → Pull) case object SetMass extends ((Obj × Number × Pull) → Pull) case object SetFriction extends ((Obj × Number × Pull) → Pull) case object SetBounciness extends ((Obj × Number × Pull) → Pull) case object SetGravity extends ((Vector × Pull) → Pull) case object AddConstraint extends ((Obj × Obj × Vector × Pull) → (Constraint × Pull)) case object LinearLimits extends ((Constraint × Vector × Vector × Pull) → Pull) case object AngularLimits extends ((Constraint × Vector × Vector × Pull) → Pull) case object LinearSpring extends ((Constraint × Vector × Vector × Pull) → Pull) case object AngularSpring extends ((Constraint × Vector × Vector × Pull) → Pull) case object LinearMotor extends ((Constraint × Vector × Vector × Pull) → Pull) case object AngularMotor extends ((Constraint × Vector × Vector × Pull) → Pull) case object If extends ((Bool × Pull × Pull × Pull) → Pull) case object OnPlay extends ((Pull × Pull) → Pull) case object LateUpdate extends ((Pull × Pull) → Pull) case object BoxArt extends ((Pull × Pull) → Pull) case class OnTouch(event: TouchEvent, finger: TouchFinger) extends ((Pull × Pull) → (Number × Number × Pull)) case object OnSwipe extends ((Pull × Pull) → (Vector × Pull)) case object OnCollision extends ((Obj × Pull × Pull) → (Obj × Number × Vector × Pull)) case object Loop extends ((Number × Number × Pull × Pull) → (Number × Pull)) case object Negate extends (Number → Number) case object Inverse extends (Rotation → Rotation) case object AddNumbers extends ((Number × Number) → Number) case object AddVectors extends ((Vector × Vector) → Vector) case object SubtractNumbers extends ((Number × Number) → Number) case object SubtractVectors extends ((Vector × Vector) → Vector) case object Multiply extends ((Number × Number) → Number) case object Scale extends ((Vector × Number) → Vector) case object Rotate extends ((Vector × Rotation) → Vector) case object Combine extends ((Rotation × Rotation) → Rotation) case object Divide extends ((Number × Number) → Number) case object Power extends ((Number × Number) → Number) case object EqualNumbers extends ((Number × Number) → Bool) case object EqualVectors extends ((Vector × Vector) → Bool) case object EqualObjects extends ((Obj × Obj) → Bool) case object EqualTruths extends ((Bool × Bool) → Bool) case object LessThan extends ((Number × Number) → Bool) case object GreaterThan extends ((Number × Number) → Bool) case object And extends ((Bool × Bool) → Bool) case object Or extends ((Bool × Bool) → Bool) case object Not extends (Bool → Bool) case object Random extends ((Number × Number) → Number) case object RandomSeed extends ((Number × Pull) → Pull) case object Min extends ((Number × Number) → Number) case object Max extends ((Number × Number) → Number) case object Sin extends (Number → Number) case object Cos extends (Number → Number) case object Round extends (Number → Number) case object Floor extends (Number → Number) case object Ceiling extends (Number → Number) case object Absolute extends (Number → Number) case object Modulo extends ((Number × Number) → Number) case object Logarithm extends ((Number × Number) → Number) case object BreakVector extends (Vector → (Number × Number × Number)) case object MakeVector extends ((Number × Number × Number) → Vector) case object Normalize extends (Vector → Vector) case object DotProduct extends ((Vector × Vector) → Vector) case object CrossProduct extends ((Vector × Vector) → Vector) case object BreakRotation extends (Rotation → (Number × Number × Number)) case object MakeRotation extends ((Number × Number × Number) → Rotation) case object Distance extends ((Vector × Vector) → Number) case object LERP extends ((Rotation × Rotation × Number) → Rotation) case object AxisAngle extends ((Vector × Number) → Rotation) case object ScreenToWorld extends ((Number × Number) → (Vector × Vector)) case object WorldToScreen extends (Vector → (Number × Number)) case object LineVsPlane extends ((Vector × Vector × Vector × Vector) → Vector) case object LookRotation extends ((Vector × Vector) → Rotation) case class GetNumber(name: String) extends (T → Number) case class GetObject(name: String) extends (T → Obj) case class GetVector(name: String) extends (T → Vector) case class GetRotation(name: String) extends (T → Rotation) case class GetTruth(name: String) extends (T → Bool) case class GetConstraint(name: String) extends (T → Constraint) case class SetNumber(name: String) extends ((Number × Pull) → Pull) case class SetObject(name: String) extends ((Obj × Pull) → Pull) case class SetVector(name: String) extends ((Vector × Pull) → Pull) case class SetRotation(name: String) extends ((Rotation × Pull) → Pull) case class SetTruth(name: String) extends ((Bool × Pull) → Pull) case class SetConstraint(name: String) extends ((Constraint × Pull) → Pull) case object SetNumberRef extends ((Number × Number × Pull) → Pull) case object SetObjectRef extends ((Obj × Obj × Pull) → Pull) case object SetVectorRef extends ((Vector × Vector × Pull) → Pull) case object SetRotationRef extends ((Rotation × Rotation × Pull) → Pull) case object SetTruthRef extends ((Bool × Bool × Pull) → Pull) case object SetConstraintRef extends ((Constraint × Constraint × Pull) → Pull) case object ListNumber extends ((Number × Number) → Number) case object ListObject extends ((Obj × Number) → Obj) case object ListVector extends ((Vector × Number) → Vector) case object ListRotation extends ((Rotation × Number) → Rotation) case object ListTruth extends ((Bool × Number) → Bool) case object ListConstraint extends ((Constraint × Number) → Constraint) case object Increment extends ((Number × Pull) → Pull) case object Decrement extends ((Number × Pull) → Pull) } implicit lazy val fanscript: Cartesian[Pin, →, T, ×] with ArrowLoop[Pin, →, T, ×, →] = new Cartesian[Pin, →, T, ×] with ArrowLoop[Pin, →, T, ×, →] { override def id[A <: Pin]: A → A = Id[A]() override def duplicate[A <: Pin]: A → (A × A) = Duplicate[A]() override def terminate[A <: Pin]: A → T = Terminate[A]() override def swap[A <: Pin, B <: Pin]: (A × B) → (B × A) = Swap() override def lift[A <: Pin, B <: Pin](f: A → B): A → B = f override def strongProfunctorCategory: Monoidal[Pin, →, T, ×] = this override def first[A <: Pin, B <: Pin, C <: Pin]: (A → B) ⇒ ((A × C) → (B × C)) = Bimap[A, B, C, C](_, id[C]) override def second[A <: Pin, B <: Pin, C <: Pin]: (A → B) ⇒ ((C × A) → (C × B)) = (f: A → B) => { val firstf: (A × C) → (B × C) = first[A, B, C](f) AndThen(Swap(), AndThen(firstf, Swap())) } override def loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)): A → B = Loop(f) override def associateRight[A <: Pin, B <: Pin, C <: Pin]: ((A × B) × C) → (A × (B × C)) = Associate[A, B, C]() override def unitorLeft[A <: Pin]: (T × A) → A = Unit() override def deunitorLeft[A <: Pin]: A → (T × A) = Deunit() override def compose[A <: Pin, B <: Pin, C <: Pin](f: B → C, g: A → B): A → C = AndThen(g, f) override def andThen[A <: Pin, B <: Pin, C <: Pin](f: A → B, g: B → C): A → C = AndThen(f, g) override def bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → C, g: B → D): (A × B) → (C × D) = Bimap(f, g) } }