import mathutils
from mathutils import Vector
import math

class Turtle:
    vx = Vector([1,0,0])
    vy = Vector([0,1,0])
    vz = Vector([0,0,1])
    def rot(self, rot):
        self.orient = self.orient @ rot
        self.orient.normalize()
    def wf(self, dist):
        f = Vector(Turtle.vx)*dist
        f.rotate(self.orient)
        self.pos = self.pos+f
    def follow(self, t):
        self.pos = Vector(t.pos)
        self.orient = mathutils.Quaternion(t.orient)
    def clone(self):
        return Turtle(self.pos, self.orient)
    def __init__(self, pos=None, orient=None):
        if pos is None:
            pos = Vector([0, 0, 0])
        if orient is None:
            orient = mathutils.Quaternion((0, 1, 0), math.radians(-90))
        self.pos = Vector(pos)
        self.orient = mathutils.Quaternion(orient)

class Instruction:
    @staticmethod
    def exec_all(turtle, stack, data, vec_instr):
        for i in vec_instr:
            i.exec(turtle, stack, data)
    def exec(self, turtle, stack, data):
        """
        Updates the turtle and associated data.
        """
        raise NotImplementedError('call to instruction without exec')
