import pymel.core as pm
import ast
from pymel.core import datatypes

from mgear.shifter import component

from mgear.core import node, applyop, vector
from mgear.core import attribute, transform, primitive


class Component(component.Main):
    """Shifter component Class"""

    # =====================================================
    # OBJECTS
    # =====================================================
    def addObjects(self):
        """Add all the objects needed to create the component."""

        # joint Description Names
        jd_names = ast.literal_eval(
            self.settings["jointNamesDescription_custom"]
        )
        jdn_ball = jd_names[0]

        self.up_axis = pm.upAxis(q=True, axis=True)

        self.div_count = len(self.guide.apos) - 5

        plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]]
        self.normal = self.getNormalFromPos(plane)
        self.binormal = self.getBiNormalFromPos(plane)

        # Heel ---------------------------------------------
        # bank pivot

        t = transform.getTransformLookingAt(
            self.guide.pos["heel"],
            self.guide.apos[-4],
            self.normal,
            "xz",
            self.negate,
        )

        t = transform.setMatrixPosition(t, self.guide.pos["inpivot"])

        self.in_npo = primitive.addTransform(
            self.root, self.getName("in_npo"), t
        )

        self.in_piv = primitive.addTransform(
            self.in_npo, self.getName("in_piv"), t
        )

        t = transform.setMatrixPosition(t, self.guide.pos["outpivot"])

        self.out_piv = primitive.addTransform(
            self.in_piv, self.getName("out_piv"), t
        )

        # heel
        t = transform.getTransformLookingAt(
            self.guide.pos["heel"],
            self.guide.apos[-4],
            self.normal,
            "xz",
            self.negate,
        )

        self.heel_loc = primitive.addTransform(
            self.out_piv, self.getName("heel_loc"), t
        )

        attribute.setRotOrder(self.heel_loc, "YZX")
        self.heel_ctl = self.addCtl(
            self.heel_loc,
            "heel_ctl",
            t,
            self.color_ik,
            "sphere",
            w=self.size * 0.1,
            tp=self.parentCtlTag,
        )

        attribute.setKeyableAttributes(self.heel_ctl, self.r_params)

        # Tip ----------------------------------------------
        if self.up_axis == "y":
            v = datatypes.Vector(
                self.guide.apos[-5].x,
                self.guide.pos["heel"].y,
                self.guide.apos[-5].z,
            )
        else:
            v = datatypes.Vector(
                self.guide.apos[-5].x,
                self.guide.apos[-5].y,
                self.guide.pos["heel"].z,
            )
        t = transform.setMatrixPosition(t, v)
        self.tip_ctl = self.addCtl(
            self.heel_ctl,
            "tip_ctl",
            t,
            self.color_ik,
            "circle",
            w=self.size,
            tp=self.heel_ctl,
        )
        attribute.setKeyableAttributes(self.tip_ctl, self.r_params)

        # Roll ---------------------------------------------
        if self.settings["useRollCtl"]:
            t = transform.getTransformLookingAt(
                self.guide.pos["heel"],
                self.guide.apos[-4],
                self.normal,
                "xz",
                self.negate,
            )
            t = transform.setMatrixPosition(t, self.guide.pos["root"])

            self.roll_np = primitive.addTransform(
                self.root, self.getName("roll_npo"), t
            )

            self.roll_ctl = self.addCtl(
                self.roll_np,
                "roll_ctl",
                t,
                self.color_ik,
                "cylinder",
                w=self.size * 0.5,
                h=self.size * 0.5,
                ro=datatypes.Vector(3.1415 * 0.5, 0, 0),
                tp=self.tip_ctl,
            )

            attribute.setKeyableAttributes(self.roll_ctl, ["rx", "rz"])

        # Backward Controlers ------------------------------
        bk_pos = self.guide.apos[1:-3]
        bk_pos.reverse()
        parent = self.tip_ctl
        self.bk_ctl = []
        self.bk_loc = []
        self.previousTag = self.tip_ctl
        for i, pos in enumerate(bk_pos):

            if i == 0:
                t = transform.getTransform(self.heel_ctl)
                t = transform.setMatrixPosition(t, pos)
            else:
                direction = bk_pos[i - 1]
                t = transform.getTransformLookingAt(
                    pos, direction, self.normal, "xz", self.negate
                )

            bk_loc = primitive.addTransform(
                parent, self.getName("bk%s_loc" % i), t
            )
            bk_ctl = self.addCtl(
                bk_loc,
                "bk%s_ctl" % i,
                t,
                self.color_ik,
                "sphere",
                w=self.size * 0.15,
                tp=self.previousTag,
            )
            attribute.setKeyableAttributes(bk_ctl, self.r_params)
            self.previousTag = bk_ctl

            self.bk_loc.append(bk_loc)
            self.bk_ctl.append(bk_ctl)
            parent = bk_ctl

        # FK Reference ------------------------------------
        self.fk_ref = primitive.addTransformFromPos(
            self.bk_ctl[-1], self.getName("fk_ref"), self.guide.apos[0]
        )
        self.fk_npo = primitive.addTransform(
            self.fk_ref,
            self.getName("fk0_npo"),
            transform.getTransform(self.bk_ctl[-1]),
        )

        # Forward Controlers ------------------------------
        self.fk_ctl = []
        self.fk_loc = []
        parent = self.fk_npo
        self.previousTag = self.tip_ctl
        for i, bk_ctl in enumerate(reversed(self.bk_ctl[1:])):
            if i == len(self.bk_ctl) - 2:
                t = transform.getTransform(self.tip_ctl)
                v = transform.getTranslation(bk_ctl)
                t = transform.setMatrixPosition(t, v)
            else:
                t = transform.getTransform(bk_ctl)
            dist = vector.getDistance(
                self.guide.apos[i + 1], self.guide.apos[i + 2]
            )

            fk_loc = primitive.addTransform(
                parent, self.getName("fk%s_loc" % i), t
            )

            po_vec = datatypes.Vector(dist * 0.5 * self.n_factor, 0, 0)
            fk_ctl = self.addCtl(
                fk_loc,
                "fk%s_ctl" % i,
                t,
                self.color_fk,
                "cube",
                w=dist,
                h=self.size * 0.5,
                d=self.size * 0.5,
                po=po_vec,
                tp=self.previousTag,
            )

            self.previousTag = fk_ctl
            attribute.setKeyableAttributes(fk_ctl)
            if i:
                name = jdn_ball + str(i)
            else:
                name = jdn_ball
            self.jnt_pos.append([fk_ctl, name])

            parent = fk_ctl
            self.fk_ctl.append(fk_ctl)
            self.fk_loc.append(fk_loc)

    # =====================================================
    # ATTRIBUTES
    # =====================================================
    def addAttributes(self):
        """Create the anim and setupr rig attributes for the component"""

        # Anim -------------------------------------------
        # Roll Angles
        if not self.settings["useRollCtl"]:
            self.roll_att = self.addAnimParam(
                "roll", "Roll", "double", 0, -180, 180
            )
            self.bank_att = self.addAnimParam(
                "bank", "Bank", "double", 0, -180, 180
            )

        self.angles_att = [
            self.addAnimParam("angle_%s" % i, "Angle %s" % i, "double", -20)
            for i in range(self.div_count)
        ]

        # Setup ------------------------------------------
        self.blend_att = self.addSetupParam(
            "blend", "Fk/Ik Blend", "double", 1, 0, 1
        )

    # =====================================================
    # OPERATORS
    # =====================================================
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """
        # Visibilities -------------------------------------
        try:
            # ik
            if self.settings["useRollCtl"]:
                for shp in self.roll_ctl.getShapes():
                    pm.connectAttr(self.blend_att, shp.attr("visibility"))
            for bk_ctl in self.bk_ctl:
                for shp in bk_ctl.getShapes():
                    pm.connectAttr(self.blend_att, shp.attr("visibility"))

            for shp in self.heel_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))
            for shp in self.tip_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))
        except RuntimeError:
            pm.displayInfo("Visibility already connect")

        # Roll / Bank --------------------------------------
        if self.settings["useRollCtl"]:  # Using the controler
            self.roll_att = self.roll_ctl.attr("rz")
            self.bank_att = self.roll_ctl.attr("rx")

        clamp_node = node.createClampNode(
            [self.roll_att, self.bank_att, self.bank_att],
            [0, -180, 0],
            [180, 0, 180],
        )

        inAdd_nod = node.createAddNode(
            clamp_node.outputB,
            pm.getAttr(self.in_piv.attr("rx")) * self.n_factor,
        )

        pm.connectAttr(clamp_node.outputR, self.heel_loc.attr("rz"))
        pm.connectAttr(clamp_node.outputG, self.out_piv.attr("rx"))
        pm.connectAttr(inAdd_nod.output, self.in_piv.attr("rx"))

        # Reverse Controler offset -------------------------
        angle_outputs = node.createAddNodeMulti(self.angles_att)
        for i, bk_loc in enumerate(reversed(self.bk_loc)):

            if i == 0:  # First
                inpu = self.roll_att
                min_input = self.angles_att[i]

            elif i == len(self.angles_att):  # Last
                sub_nod = node.createSubNode(
                    self.roll_att, angle_outputs[i - 1]
                )
                inpu = sub_nod.output
                min_input = -360

            else:  # Others
                sub_nod = node.createSubNode(
                    self.roll_att, angle_outputs[i - 1]
                )
                inpu = sub_nod.output
                min_input = self.angles_att[i]

            clamp_node = node.createClampNode(inpu, min_input, 0)

            add_node = node.createAddNode(
                clamp_node.outputR, bk_loc.getAttr("rz")
            )

            pm.connectAttr(add_node.output, bk_loc.attr("rz"))

        # Reverse compensation -----------------------------
        for i, fk_loc in enumerate(self.fk_loc):
            bk_ctl = self.bk_ctl[-i - 1]
            bk_loc = self.bk_loc[-i - 1]
            fk_ctl = self.fk_ctl[i]

            # Inverse Rotorder
            o_node = applyop.gear_inverseRotorder_op(bk_ctl, fk_ctl)
            pm.connectAttr(o_node.output, bk_loc.attr("ro"))
            pm.connectAttr(fk_ctl.attr("ro"), fk_loc.attr("ro"))
            attribute.lockAttribute(bk_ctl, "ro")

            # Compensate the backward rotation
            # ik
            addx_node = node.createAddNode(
                bk_ctl.attr("rx"), bk_loc.attr("rx")
            )
            addy_node = node.createAddNode(
                bk_ctl.attr("ry"), bk_loc.attr("ry")
            )
            addz_node = node.createAddNode(
                bk_ctl.attr("rz"), bk_loc.attr("rz")
            )
            addz_node = node.createAddNode(
                addz_node.output, -bk_loc.getAttr("rz") - fk_loc.getAttr("rz")
            )

            neg_node = node.createMulNode(
                [addx_node.output, addy_node.output, addz_node.output],
                [-1, -1, -1],
            )
            add_node = node.createAddNode(
                neg_node.outputY.get() * -1, neg_node.outputY
            )
            ik_outputs = [neg_node.outputX, add_node.output, neg_node.outputZ]

            # fk
            fk_outputs = [0, 0, fk_loc.getAttr("rz")]

            # blend
            blend_node = node.createBlendNode(
                ik_outputs, fk_outputs, self.blend_att
            )
            pm.connectAttr(blend_node.output, fk_loc.attr("rotate"))

        return

    # =====================================================
    # CONNECTOR
    # =====================================================
    def setRelation(self):
        """Set the relation beetween object from guide to rig"""

        self.relatives["root"] = self.fk_ctl[0]
        self.relatives["heel"] = self.fk_ctl[0]
        self.relatives["inpivot"] = self.fk_ctl[0]
        self.relatives["outpivot"] = self.fk_ctl[0]

        self.controlRelatives["root"] = self.fk_ctl[0]
        self.controlRelatives["heel"] = self.fk_ctl[0]
        self.controlRelatives["inpivot"] = self.fk_ctl[0]
        self.controlRelatives["outpivot"] = self.fk_ctl[0]

        self.jointRelatives["root"] = 0
        self.jointRelatives["heel"] = 0
        self.jointRelatives["inpivot"] = 0
        self.jointRelatives["outpivot"] = 0

        for i in range(self.div_count):
            self.relatives["%s_loc" % i] = self.fk_ctl[i]
            self.jointRelatives["%s_loc" % i] = i

        if self.div_count > 0:
            self.relatives["%s_loc" % self.div_count] = self.fk_ctl[-1]
            self.jointRelatives["%s_loc" % self.div_count] = self.div_count - 1

    def addConnection(self):
        """Add more connection definition to the set"""

        self.connections["EPIC_leg_01"] = self.connect_leg_2jnt_01
        self.connections["leg_2jnt_01"] = self.connect_leg_2jnt_01
        self.connections["leg_ms_2jnt_01"] = self.connect_leg_ms_2jnt_01
        self.connections["leg_3jnt_01"] = self.connect_leg_3jnt_01

    def connect_leg_2jnt_01(self):
        """Connector for leg 2jnt"""

        # If the parent component hasn't been generated we skip the connection
        if self.parent_comp is None:
            return

        pm.connectAttr(self.parent_comp.blend_att, self.blend_att)
        pm.parent(self.root, self.parent_comp.ik_ctl)
        pm.parent(self.parent_comp.ik_ref, self.bk_ctl[-1])
        pm.parentConstraint(
            self.parent_comp.tws2_rot, self.fk_ref, maintainOffset=True
        )

        return

    def connect_leg_ms_2jnt_01(self):
        """Connector for leg ms 2jnt"""

        # If the parent component hasn't been generated we skip the connection
        if self.parent_comp is None:
            return

        pm.connectAttr(self.parent_comp.blend_att, self.blend_att)
        pm.parent(self.root, self.parent_comp.ik_ctl)
        pm.parent(self.parent_comp.ik_ref, self.bk_ctl[-1])
        pm.parentConstraint(
            self.parent_comp.tws3_rot, self.fk_ref, maintainOffset=True
        )
        cns = pm.scaleConstraint(
            self.parent_comp.fk_ref,
            self.parent_comp.ik_ref,
            self.fk_ref,
            wal=True,
        )
        bc_node = pm.createNode("blendColors")
        pm.connectAttr(
            bc_node.outputB, cns + ".%sW0" % self.parent_comp.fk_ref
        )
        pm.connectAttr(
            bc_node.outputR, cns + ".%sW1" % self.parent_comp.ik_ref
        )
        pm.connectAttr(self.parent_comp.blend_att, bc_node.blender)

        return

    def connect_leg_3jnt_01(self):
        """Connector for leg 3jnt"""

        # If the parent component hasn't been generated we skip the connection
        if self.parent_comp is None:
            return

        pm.connectAttr(self.parent_comp.blend_att, self.blend_att)
        pm.parent(self.root, self.parent_comp.ik_ctl)
        pm.parent(self.parent_comp.ik_ref, self.bk_ctl[-1])
        pm.parent(self.parent_comp.ik2b_ikCtl_ref, self.bk_ctl[-1])
        pm.parentConstraint(
            self.parent_comp.tws3_rot, self.fk_ref, maintainOffset=True
        )

        return

[((21, 19, 23, 9), 'ast.literal_eval', 'ast.literal_eval', ({(22, 12, 22, 57): "self.settings['jointNamesDescription_custom']"}, {}), "(self.settings['jointNamesDescription_custom'])", False, 'import ast\n'), ((26, 23, 26, 51), 'pymel.core.upAxis', 'pm.upAxis', (), '', True, 'import pymel.core as pm\n'), ((37, 12, 43, 9), 'mgear.core.transform.getTransformLookingAt', 'transform.getTransformLookingAt', ({(38, 12, 38, 34): "self.guide.pos['heel']", (39, 12, 39, 31): 'self.guide.apos[-4]', (40, 12, 40, 23): 'self.normal', (41, 12, 41, 16): '"""xz"""', (42, 12, 42, 23): 'self.negate'}, {}), "(self.guide.pos['heel'], self.guide.apos[-4],\n    self.normal, 'xz', self.negate)", False, 'from mgear.core import attribute, transform, primitive\n'), ((45, 12, 45, 69), 'mgear.core.transform.setMatrixPosition', 'transform.setMatrixPosition', ({(45, 40, 45, 41): 't', (45, 43, 45, 68): "self.guide.pos['inpivot']"}, {}), "(t, self.guide.pos['inpivot'])", False, 'from mgear.core import attribute, transform, primitive\n'), ((55, 12, 55, 70), 'mgear.core.transform.setMatrixPosition', 'transform.setMatrixPosition', ({(55, 40, 55, 41): 't', (55, 43, 55, 69): "self.guide.pos['outpivot']"}, {}), "(t, self.guide.pos['outpivot'])", False, 'from mgear.core import attribute, transform, primitive\n'), ((62, 12, 68, 9), 'mgear.core.transform.getTransformLookingAt', 'transform.getTransformLookingAt', ({(63, 12, 63, 34): "self.guide.pos['heel']", (64, 12, 64, 31): 'self.guide.apos[-4]', (65, 12, 65, 23): 'self.normal', (66, 12, 66, 16): '"""xz"""', (67, 12, 67, 23): 'self.negate'}, {}), "(self.guide.pos['heel'], self.guide.apos[-4],\n    self.normal, 'xz', self.negate)", False, 'from mgear.core import attribute, transform, primitive\n'), ((74, 8, 74, 51), 'mgear.core.attribute.setRotOrder', 'attribute.setRotOrder', ({(74, 30, 74, 43): 'self.heel_loc', (74, 45, 74, 50): '"""YZX"""'}, {}), "(self.heel_loc, 'YZX')", False, 'from mgear.core import attribute, transform, primitive\n'), ((85, 8, 85, 68), 'mgear.core.attribute.setKeyableAttributes', 'attribute.setKeyableAttributes', ({(85, 39, 85, 52): 'self.heel_ctl', (85, 54, 85, 67): 'self.r_params'}, {}), '(self.heel_ctl, self.r_params)', False, 'from mgear.core import attribute, transform, primitive\n'), ((100, 12, 100, 45), 'mgear.core.transform.setMatrixPosition', 'transform.setMatrixPosition', ({(100, 40, 100, 41): 't', (100, 43, 100, 44): 'v'}, {}), '(t, v)', False, 'from mgear.core import attribute, transform, primitive\n'), ((110, 8, 110, 67), 'mgear.core.attribute.setKeyableAttributes', 'attribute.setKeyableAttributes', ({(110, 39, 110, 51): 'self.tip_ctl', (110, 53, 110, 66): 'self.r_params'}, {}), '(self.tip_ctl, self.r_params)', False, 'from mgear.core import attribute, transform, primitive\n'), ((293, 21, 297, 9), 'mgear.core.node.createClampNode', 'node.createClampNode', ({(294, 12, 294, 57): '[self.roll_att, self.bank_att, self.bank_att]', (295, 12, 295, 24): '[0, -180, 0]', (296, 12, 296, 25): '[180, 0, 180]'}, {}), '([self.roll_att, self.bank_att, self.bank_att], [0, -\n    180, 0], [180, 0, 180])', False, 'from mgear.core import node, applyop, vector\n'), ((309, 24, 309, 64), 'mgear.core.node.createAddNodeMulti', 'node.createAddNodeMulti', ({(309, 48, 309, 63): 'self.angles_att'}, {}), '(self.angles_att)', False, 'from mgear.core import node, applyop, vector\n'), ((429, 8, 429, 66), 'pymel.core.connectAttr', 'pm.connectAttr', ({(429, 23, 429, 49): 'self.parent_comp.blend_att', (429, 51, 429, 65): 'self.blend_att'}, {}), '(self.parent_comp.blend_att, self.blend_att)', True, 'import pymel.core as pm\n'), ((430, 8, 430, 53), 'pymel.core.parent', 'pm.parent', ({(430, 18, 430, 27): 'self.root', (430, 29, 430, 52): 'self.parent_comp.ik_ctl'}, {}), '(self.root, self.parent_comp.ik_ctl)', True, 'import pymel.core as pm\n'), ((431, 8, 431, 59), 'pymel.core.parent', 'pm.parent', ({(431, 18, 431, 41): 'self.parent_comp.ik_ref', (431, 43, 431, 58): 'self.bk_ctl[-1]'}, {}), '(self.parent_comp.ik_ref, self.bk_ctl[-1])', True, 'import pymel.core as pm\n'), ((432, 8, 434, 9), 'pymel.core.parentConstraint', 'pm.parentConstraint', (), '', True, 'import pymel.core as pm\n'), ((445, 8, 445, 66), 'pymel.core.connectAttr', 'pm.connectAttr', ({(445, 23, 445, 49): 'self.parent_comp.blend_att', (445, 51, 445, 65): 'self.blend_att'}, {}), '(self.parent_comp.blend_att, self.blend_att)', True, 'import pymel.core as pm\n'), ((446, 8, 446, 53), 'pymel.core.parent', 'pm.parent', ({(446, 18, 446, 27): 'self.root', (446, 29, 446, 52): 'self.parent_comp.ik_ctl'}, {}), '(self.root, self.parent_comp.ik_ctl)', True, 'import pymel.core as pm\n'), ((447, 8, 447, 59), 'pymel.core.parent', 'pm.parent', ({(447, 18, 447, 41): 'self.parent_comp.ik_ref', (447, 43, 447, 58): 'self.bk_ctl[-1]'}, {}), '(self.parent_comp.ik_ref, self.bk_ctl[-1])', True, 'import pymel.core as pm\n'), ((448, 8, 450, 9), 'pymel.core.parentConstraint', 'pm.parentConstraint', (), '', True, 'import pymel.core as pm\n'), ((451, 14, 456, 9), 'pymel.core.scaleConstraint', 'pm.scaleConstraint', (), '', True, 'import pymel.core as pm\n'), ((457, 18, 457, 46), 'pymel.core.createNode', 'pm.createNode', ({(457, 32, 457, 45): '"""blendColors"""'}, {}), "('blendColors')", True, 'import pymel.core as pm\n'), ((458, 8, 460, 9), 'pymel.core.connectAttr', 'pm.connectAttr', ({(459, 12, 459, 27): 'bc_node.outputB', (459, 29, 459, 68): "(cns + '.%sW0' % self.parent_comp.fk_ref)"}, {}), "(bc_node.outputB, cns + '.%sW0' % self.parent_comp.fk_ref)", True, 'import pymel.core as pm\n'), ((461, 8, 463, 9), 'pymel.core.connectAttr', 'pm.connectAttr', ({(462, 12, 462, 27): 'bc_node.outputR', (462, 29, 462, 68): "(cns + '.%sW1' % self.parent_comp.ik_ref)"}, {}), "(bc_node.outputR, cns + '.%sW1' % self.parent_comp.ik_ref)", True, 'import pymel.core as pm\n'), ((464, 8, 464, 67), 'pymel.core.connectAttr', 'pm.connectAttr', ({(464, 23, 464, 49): 'self.parent_comp.blend_att', (464, 51, 464, 66): 'bc_node.blender'}, {}), '(self.parent_comp.blend_att, bc_node.blender)', True, 'import pymel.core as pm\n'), ((475, 8, 475, 66), 'pymel.core.connectAttr', 'pm.connectAttr', ({(475, 23, 475, 49): 'self.parent_comp.blend_att', (475, 51, 475, 65): 'self.blend_att'}, {}), '(self.parent_comp.blend_att, self.blend_att)', True, 'import pymel.core as pm\n'), ((476, 8, 476, 53), 'pymel.core.parent', 'pm.parent', ({(476, 18, 476, 27): 'self.root', (476, 29, 476, 52): 'self.parent_comp.ik_ctl'}, {}), '(self.root, self.parent_comp.ik_ctl)', True, 'import pymel.core as pm\n'), ((477, 8, 477, 59), 'pymel.core.parent', 'pm.parent', ({(477, 18, 477, 41): 'self.parent_comp.ik_ref', (477, 43, 477, 58): 'self.bk_ctl[-1]'}, {}), '(self.parent_comp.ik_ref, self.bk_ctl[-1])', True, 'import pymel.core as pm\n'), ((478, 8, 478, 67), 'pymel.core.parent', 'pm.parent', ({(478, 18, 478, 49): 'self.parent_comp.ik2b_ikCtl_ref', (478, 51, 478, 66): 'self.bk_ctl[-1]'}, {}), '(self.parent_comp.ik2b_ikCtl_ref, self.bk_ctl[-1])', True, 'import pymel.core as pm\n'), ((479, 8, 481, 9), 'pymel.core.parentConstraint', 'pm.parentConstraint', (), '', True, 'import pymel.core as pm\n'), ((89, 16, 93, 13), 'pymel.core.datatypes.Vector', 'datatypes.Vector', ({(90, 16, 90, 37): 'self.guide.apos[-5].x', (91, 16, 91, 40): "self.guide.pos['heel'].y", (92, 16, 92, 37): 'self.guide.apos[-5].z'}, {}), "(self.guide.apos[-5].x, self.guide.pos['heel'].y, self.\n    guide.apos[-5].z)", False, 'from pymel.core import datatypes\n'), ((95, 16, 99, 13), 'pymel.core.datatypes.Vector', 'datatypes.Vector', ({(96, 16, 96, 37): 'self.guide.apos[-5].x', (97, 16, 97, 37): 'self.guide.apos[-5].y', (98, 16, 98, 40): "self.guide.pos['heel'].z"}, {}), "(self.guide.apos[-5].x, self.guide.apos[-5].y, self.guide.\n    pos['heel'].z)", False, 'from pymel.core import datatypes\n'), ((114, 16, 120, 13), 'mgear.core.transform.getTransformLookingAt', 'transform.getTransformLookingAt', ({(115, 16, 115, 38): "self.guide.pos['heel']", (116, 16, 116, 35): 'self.guide.apos[-4]', (117, 16, 117, 27): 'self.normal', (118, 16, 118, 20): '"""xz"""', (119, 16, 119, 27): 'self.negate'}, {}), "(self.guide.pos['heel'], self.guide.apos[-4],\n    self.normal, 'xz', self.negate)", False, 'from mgear.core import attribute, transform, primitive\n'), ((121, 16, 121, 70), 'mgear.core.transform.setMatrixPosition', 'transform.setMatrixPosition', ({(121, 44, 121, 45): 't', (121, 47, 121, 69): "self.guide.pos['root']"}, {}), "(t, self.guide.pos['root'])", False, 'from mgear.core import attribute, transform, primitive\n'), ((139, 12, 139, 71), 'mgear.core.attribute.setKeyableAttributes', 'attribute.setKeyableAttributes', ({(139, 43, 139, 56): 'self.roll_ctl', (139, 58, 139, 70): "['rx', 'rz']"}, {}), "(self.roll_ctl, ['rx', 'rz'])", False, 'from mgear.core import attribute, transform, primitive\n'), ((171, 12, 171, 65), 'mgear.core.attribute.setKeyableAttributes', 'attribute.setKeyableAttributes', ({(171, 43, 171, 49): 'bk_ctl', (171, 51, 171, 64): 'self.r_params'}, {}), '(bk_ctl, self.r_params)', False, 'from mgear.core import attribute, transform, primitive\n'), ((185, 12, 185, 51), 'mgear.core.transform.getTransform', 'transform.getTransform', ({(185, 35, 185, 50): 'self.bk_ctl[-1]'}, {}), '(self.bk_ctl[-1])', False, 'from mgear.core import attribute, transform, primitive\n'), ((200, 19, 202, 13), 'mgear.core.vector.getDistance', 'vector.getDistance', ({(201, 16, 201, 38): 'self.guide.apos[i + 1]', (201, 40, 201, 62): 'self.guide.apos[i + 2]'}, {}), '(self.guide.apos[i + 1], self.guide.apos[i + 2])', False, 'from mgear.core import node, applyop, vector\n'), ((208, 21, 208, 71), 'pymel.core.datatypes.Vector', 'datatypes.Vector', ({(208, 38, 208, 64): 'dist * 0.5 * self.n_factor', (208, 66, 208, 67): '0', (208, 69, 208, 70): '0'}, {}), '(dist * 0.5 * self.n_factor, 0, 0)', False, 'from pymel.core import datatypes\n'), ((223, 12, 223, 50), 'mgear.core.attribute.setKeyableAttributes', 'attribute.setKeyableAttributes', ({(223, 43, 223, 49): 'fk_ctl'}, {}), '(fk_ctl)', False, 'from mgear.core import attribute, transform, primitive\n'), ((330, 25, 330, 65), 'mgear.core.node.createClampNode', 'node.createClampNode', ({(330, 46, 330, 50): 'inpu', (330, 52, 330, 61): 'min_input', (330, 63, 330, 64): '0'}, {}), '(inpu, min_input, 0)', False, 'from mgear.core import node, applyop, vector\n'), ((345, 21, 345, 68), 'mgear.core.applyop.gear_inverseRotorder_op', 'applyop.gear_inverseRotorder_op', ({(345, 53, 345, 59): 'bk_ctl', (345, 61, 345, 67): 'fk_ctl'}, {}), '(bk_ctl, fk_ctl)', False, 'from mgear.core import node, applyop, vector\n'), ((348, 12, 348, 49), 'mgear.core.attribute.lockAttribute', 'attribute.lockAttribute', ({(348, 36, 348, 42): 'bk_ctl', (348, 44, 348, 48): '"""ro"""'}, {}), "(bk_ctl, 'ro')", False, 'from mgear.core import attribute, transform, primitive\n'), ((365, 23, 368, 13), 'mgear.core.node.createMulNode', 'node.createMulNode', ({(366, 16, 366, 70): '[addx_node.output, addy_node.output, addz_node.output]', (367, 16, 367, 28): '[-1, -1, -1]'}, {}), '([addx_node.output, addy_node.output, addz_node.output],\n    [-1, -1, -1])', False, 'from mgear.core import node, applyop, vector\n'), ((378, 25, 380, 13), 'mgear.core.node.createBlendNode', 'node.createBlendNode', ({(379, 16, 379, 26): 'ik_outputs', (379, 28, 379, 38): 'fk_outputs', (379, 40, 379, 54): 'self.blend_att'}, {}), '(ik_outputs, fk_outputs, self.blend_att)', False, 'from mgear.core import node, applyop, vector\n'), ((151, 20, 151, 57), 'mgear.core.transform.getTransform', 'transform.getTransform', ({(151, 43, 151, 56): 'self.heel_ctl'}, {}), '(self.heel_ctl)', False, 'from mgear.core import attribute, transform, primitive\n'), ((152, 20, 152, 55), 'mgear.core.transform.setMatrixPosition', 'transform.setMatrixPosition', ({(152, 48, 152, 49): 't', (152, 51, 152, 54): 'pos'}, {}), '(t, pos)', False, 'from mgear.core import attribute, transform, primitive\n'), ((155, 20, 157, 17), 'mgear.core.transform.getTransformLookingAt', 'transform.getTransformLookingAt', ({(156, 20, 156, 23): 'pos', (156, 25, 156, 34): 'direction', (156, 36, 156, 47): 'self.normal', (156, 49, 156, 53): '"""xz"""', (156, 55, 156, 66): 'self.negate'}, {}), "(pos, direction, self.normal, 'xz', self.negate)", False, 'from mgear.core import attribute, transform, primitive\n'), ((195, 20, 195, 56), 'mgear.core.transform.getTransform', 'transform.getTransform', ({(195, 43, 195, 55): 'self.tip_ctl'}, {}), '(self.tip_ctl)', False, 'from mgear.core import attribute, transform, primitive\n'), ((196, 20, 196, 52), 'mgear.core.transform.getTranslation', 'transform.getTranslation', ({(196, 45, 196, 51): 'bk_ctl'}, {}), '(bk_ctl)', False, 'from mgear.core import attribute, transform, primitive\n'), ((197, 20, 197, 53), 'mgear.core.transform.setMatrixPosition', 'transform.setMatrixPosition', ({(197, 48, 197, 49): 't', (197, 51, 197, 52): 'v'}, {}), '(t, v)', False, 'from mgear.core import attribute, transform, primitive\n'), ((199, 20, 199, 50), 'mgear.core.transform.getTransform', 'transform.getTransform', ({(199, 43, 199, 49): 'bk_ctl'}, {}), '(bk_ctl)', False, 'from mgear.core import attribute, transform, primitive\n'), ((286, 12, 286, 56), 'pymel.core.displayInfo', 'pm.displayInfo', ({(286, 27, 286, 55): '"""Visibility already connect"""'}, {}), "('Visibility already connect')", True, 'import pymel.core as pm\n'), ((135, 19, 135, 55), 'pymel.core.datatypes.Vector', 'datatypes.Vector', ({(135, 36, 135, 48): '3.1415 * 0.5', (135, 50, 135, 51): '0', (135, 53, 135, 54): '0'}, {}), '(3.1415 * 0.5, 0, 0)', False, 'from pymel.core import datatypes\n'), ((317, 26, 319, 17), 'mgear.core.node.createSubNode', 'node.createSubNode', ({(318, 20, 318, 33): 'self.roll_att', (318, 35, 318, 55): 'angle_outputs[i - 1]'}, {}), '(self.roll_att, angle_outputs[i - 1])', False, 'from mgear.core import node, applyop, vector\n'), ((324, 26, 326, 17), 'mgear.core.node.createSubNode', 'node.createSubNode', ({(325, 20, 325, 33): 'self.roll_att', (325, 35, 325, 55): 'angle_outputs[i - 1]'}, {}), '(self.roll_att, angle_outputs[i - 1])', False, 'from mgear.core import node, applyop, vector\n')]