#-------------------------------------------------------------------------------
# Name:        YJ_Spline_ik
# Purpose:     Create_spline_ik
#
# Author:      YangJie
#
# Created:     08/04/2014
#Email:        691633493@
#-------------------------------------------------------------------------------
from maya.cmds import*
from YJ_Rig_Pub import*
from YJ_Ctrl_Colour import*
from YJ_ParentShape import*

#starJnt,endJnt,judge,Ctrl_Nub = SpineIK_List[0],SpineIK_List[-1],1,Spine_Ctrl_Nub
#StarBaseJnt,EndBaseJnt,Ctrl_Nub  = YJ_judge_get_sp_jnt('hh','hh',0,0)
#AllBaseJntList=[u'joint1_skin', u'joint2_skin', u'joint3_skin', u'joint4_skin', u'joint5_skin', u'joint6_skin']
def YJ_CreateSplineIK_All(starJnt,endJnt,judge,Ctrl_Nub):
    StarBaseJnt,EndBaseJnt,Ctrl_Nub = YJ_judge_get_sp_jnt(starJnt,endJnt,judge,Ctrl_Nub)
    AllBaseJntList_O=YJ_GetBaseJntList(StarBaseJnt,EndBaseJnt)
    StarSplineIkJnt=AllBaseJntList_O[0]
    EndSplineIkJnt=AllBaseJntList_O[-1]
    YJ_IK_Name=StarSplineIkJnt+'_IKHandle'
    YJ_IK_Effector_Name=YJ_IK_Name+'_effector'

    YJ_CreateSplineIK(YJ_IK_Name,StarSplineIkJnt,EndSplineIkJnt)
    YJ_IK_Effector_Name,YJ_IK_Curve_NameZerGrp,YJ_IK_Curve_Name=YJ_get_curveAndEfftorName(YJ_IK_Name)
    Grp_Name,Ctrl_List=YJ_CreateSpline_Ctrl(StarBaseJnt,StarSplineIkJnt,YJ_IK_Curve_Name,Ctrl_Nub)
    ZeroGrp_List=YJ_Shape_SP_Ctrl_Zero_grp(Ctrl_List,YJ_IK_Curve_Name)
    All_grp = YJ_CleanSplineLayer(ZeroGrp_List,Grp_Name,YJ_IK_Name,StarSplineIkJnt,YJ_IK_Curve_NameZerGrp)
####

    YJ_Create_Scale(AllBaseJntList_O,YJ_IK_Curve_Name,Ctrl_List)

    YJ_CreatSpline_Advanced_twist(StarSplineIkJnt,EndSplineIkJnt,YJ_IK_Name,Ctrl_List)

    return Ctrl_List,ZeroGrp_List,All_grp








def YJ_judge_get_sp_jnt(StarBaseJnt,EndBaseJnt,judge,Ctrl_Nub):
    if judge == 1:
        StarBaseJnt,EndBaseJnt,Ctrl_Nub = StarBaseJnt,EndBaseJnt,Ctrl_Nub
    elif judge == 0:
        StarBaseJnt = textField('Spline_IK_star_tf',q=1 ,tx = 1)
        EndBaseJnt = textField('Spline_IK_end_tf',q=1 ,tx = 1)
        Ctrl_NubT = textField('Spline_Ctrl_Nub_tf',q=1 ,tx = 1)
        Ctrl_Nub=int(Ctrl_NubT)
    return StarBaseJnt,EndBaseJnt,Ctrl_Nub

def YJ_CreateSplineIK(YJ_IK_Name,StarSplineIkJnt,EndSplineIkJnt):
    curveName=StarSplineIkJnt+'Curve'
    YJ_IK_Effector_Name=YJ_IK_Name+'_effector'
    ikHandle(n=YJ_IK_Name, sj=StarSplineIkJnt, ee=EndSplineIkJnt,scv=0,solver='ikSplineSolver')

def YJ_get_curveAndEfftorName(YJ_IK_Name):
    YJ_IK_Effector_Name=YJ_IK_Name+'_effector'
    YJ_IK_Curve_Name=YJ_IK_Name+'Curve'
    EffectorG=ikHandle(YJ_IK_Name, q=1,ee=1)
    EffectorN=str(EffectorG)
    rename( EffectorN, YJ_IK_Effector_Name)
    CurveG=ikHandle(YJ_IK_Name, q=1,c=1)
    CurveLS=str(CurveG)
    CurveL=CurveLS.split('|')
    CurveN=CurveL[-2]
    rename( CurveN, YJ_IK_Curve_Name )
    YJ_IK_Curve_NameZerGrp = YJRigZeroGrp([YJ_IK_Curve_Name])[0]
    return YJ_IK_Effector_Name,YJ_IK_Curve_NameZerGrp,YJ_IK_Curve_Name




def YJ_CreateSpline_Ctrl(StarBaseJnt,StarSplineIkJnt,YJ_IK_Curve_Name,Ctrl_Nub):
    step=100/(Ctrl_Nub-1)
    PercentL=[]
    for i in range(0,101,step):
        PercentL.append(i)
    PercentL[-1]=100
    Grp_Name= StarBaseJnt+'ZeroGrp'
    group( em=True, name= Grp_Name)
    YJ_MoveOrRotateToTargetWd(StarSplineIkJnt,Grp_Name,'t','t')
    YJ_MoveOrRotateToTargetWd(StarSplineIkJnt,Grp_Name,'ro','r')
    Nub=1
    Ctrl_List=[]
    for j in PercentL:
        P_percent_Str=str(j)
        name='P_O_CV'+P_percent_Str
        Nub_Str=str(Nub)
        Ctrl_Name='Spline_'+Nub_Str+'_anim'
        Nub=Nub+1
        Pers=j/100.0
        Piv=pointOnCurve( YJ_IK_Curve_Name, pr=Pers, p=True ,top=1)
        joint(n=Ctrl_Name, p=Piv )
        Ctrl_List.append(Ctrl_Name)
    EndCtrl= Ctrl_List[-1]
    StarCtrl=Ctrl_List[0]
    joint(StarCtrl,e=1,oj='xyz',sao='yup',ch=1,zso=1)
    joint(EndCtrl,e=1,oj='none',ch=0,zso=1)
    return Grp_Name,Ctrl_List









def YJ_Shape_SP_Ctrl_Zero_grp(Ctrl_List,YJ_IK_Curve_Name):
    ZeroGrp_List=YJRigZeroGrp(Ctrl_List)
    skinCluster(Ctrl_List, YJ_IK_Curve_Name,tsb=True,mi=3,omi=1)
    for i in Ctrl_List:
        CurveName=i+'CV'
        setAttr (i+".drawStyle" ,2)
        YJ_Creat_Ctrl("Cur1",CurveName)
        YJ_Parent_Shape(CurveName,i,0,0)
    return  ZeroGrp_List




def YJ_CleanSplineLayer(ZeroGrp_List,Grp_Name,YJ_IK_Name,StarSplineIkJnt,YJ_IK_Curve_NameZerGrp):
    for i in ZeroGrp_List:
        YJ_Try_Parent(i,Grp_Name)
    All_grp=Grp_Name+'_All_Grp'
    group( em=True, name=All_grp)
    YJ_Try_Parent(Grp_Name,All_grp)
    YJ_Try_Parent(YJ_IK_Curve_NameZerGrp,All_grp)
    YJ_Try_Parent(YJ_IK_Name,All_grp)
    YJ_Try_Parent(StarSplineIkJnt,All_grp)
    setAttr(YJ_IK_Name+".visibility",0)
    return All_grp




#
def YJ_Create_Scale(Jnt_List,YJ_IK_Curve_Name,Ctrl_List):
    Point_List ,Dis_List = YJ_Create_DisNode(Jnt_List)
    YJ_Connect_DisNode(Point_List,Dis_List,YJ_IK_Curve_Name)
    MD_List, Con_List=YJ_Create_MDNode(Jnt_List)
    YJ_Connect_Dis_TO_MD(Dis_List,MD_List)
    YJ_Connect_MD_TO_Con(Con_List,MD_List)
    ConJnt_List,Tran_List=YJ_Get_Trans_of_ConJnt_List(Jnt_List)
    YJ_SetValue_for_Con(Con_List,Tran_List)
    YJ_Connect_Con_TO_JntT(Con_List,ConJnt_List)
    StrAttr=YJ_Create_Stretch_Attr(Ctrl_List)
    YJ_Connect_Stretch_To_Con(StrAttr,Con_List)

#
def YJ_Create_DisNode(AllBaseJntList):
    DisNub=len(AllBaseJntList)
    Point_List=[]
    for p in range(0,DisNub):
        star_p=p
        end_p=p+1
        if end_p <= (DisNub-1):
            Point_List.append((star_p,end_p))

    Dis_List=[]
    Node_NB= DisNub-1
    for i in range(0,Node_NB):
        name="Dis_"+str(i)+"BT"
        createNode('distanceBetween',n=name)
        Dis_List.append(name)

    return  Point_List ,Dis_List

def YJ_Connect_DisNode(Point_List,Dis_List,YJ_IK_Curve_Name):
    ListNub=len(Point_List)
    Cureve_shape=listRelatives(YJ_IK_Curve_Name,s=1)
    Cureve_shape_Name=Cureve_shape[0]
    for i in range(0,ListNub):
        EP_Star ='.editPoints'+ "["+str(Point_List[i][0])+"]"
        EP_End = '.editPoints'+ "["+str(Point_List[i][1])+"]"
        DisNode=Dis_List[i]
        connectAttr( Cureve_shape_Name+EP_Star,DisNode+".point1")
        connectAttr( Cureve_shape_Name+EP_End,DisNode+".point2")


def YJ_Create_MDNode(Jnt_List):
    DisNub=len(Jnt_List)
    Node_NB= DisNub-1
    MD_List=[]
    Con_List=[]
    for i in range(0,Node_NB):
        name="Spline_"+str(i)+"_D"
        Con_Name = "Spline_"+str(i)+"_Con"
        createNode('multiplyDivide',n=name)
        setAttr (name+".operation" ,2)
        createNode('condition',n=Con_Name)
        setAttr (Con_Name+".secondTerm" ,1)
        MD_List.append(name)
        Con_List.append(Con_Name)
    return  MD_List, Con_List


def YJ_Connect_Dis_TO_MD(Dis_List,MD_List):
    ListNub=len(MD_List)
    for i in range(0,ListNub):
        connectAttr( Dis_List[i]+'.distance',MD_List[i]+".input1X")


def YJ_Connect_MD_TO_Con(Con_List,MD_List):
    ListNub=len(MD_List)
    for i in range(0,ListNub):
        connectAttr( MD_List[i]+'.outputX',Con_List[i]+".colorIfTrueR")

def YJ_Connect_Con_TO_JntT(Con_List,ConJnt_List):
    ListNub=len(Con_List)
    for i in range(0,ListNub):
        connectAttr( Con_List[i]+'.outColorR',ConJnt_List[i]+".tx")



def YJ_Get_Trans_of_ConJnt_List(AllBaseJntList):
    ConJnt_List = YJ_getNewList(AllBaseJntList)
    ConJnt_List.remove(ConJnt_List[0])
    ListNub=len(ConJnt_List)
    Tran_List=[]
    for i in ConJnt_List:
        Tran=getAttr(i+'.tx')
        Tran_List.append(Tran)

    return  ConJnt_List,Tran_List

def YJ_SetValue_for_Con(Con_List,Tran_List):
    Cycle_Nub=len(Con_List)
    for i in range(0,Cycle_Nub):
        setAttr(Con_List[i]+".colorIfFalseR" ,2)


def YJ_Create_Stretch_Attr(Ctrl_List):
    Attr_Ctrl=Ctrl_List[0]
    addAttr(Attr_Ctrl, longName='Stretch',at='double', min=0,max=1,dv=1 )
    setAttr(Attr_Ctrl+'.Stretch',keyable=1)
    StrAttr=Attr_Ctrl+'.Stretch'
    return StrAttr

def YJ_Connect_Stretch_To_Con(StrAttr,Con_List):
    for i in Con_List:
        connectAttr( StrAttr,i+".firstTerm")




###

def YJ_CreatSpline_Advanced_twist(StarSplineIkJnt,EndSplineIkJnt,YJ_IK_Name,Ctrl_List):
    StarLoc,EndLoc =YJ_createSpineLoc(StarSplineIkJnt,EndSplineIkJnt)
    YJ_SetSpineIKTwist(YJ_IK_Name,StarLoc,EndLoc)
    YJ_clean_Sp_loc(StarLoc,EndLoc,Ctrl_List)




def YJ_createSpineLoc(starJnt,endJnt):
    StarLoc=spaceLocator(n=starJnt+'_Loc01' )[-1]
    YJ_MoveOrRotateToTargetWd(starJnt,StarLoc,'t','t')
    YJ_MoveOrRotateToTargetWd(starJnt,StarLoc,'ro','r')
    EndLoc=spaceLocator(n=starJnt+'_Loc02' )[-1]
    YJ_MoveOrRotateToTargetWd(endJnt,EndLoc,'t','t')
    YJ_MoveOrRotateToTargetWd(endJnt,EndLoc,'ro','r')
    return StarLoc,EndLoc

def YJ_SetSpineIKTwist(InIk,StarObj,EndObj):
    setAttr( InIk+'.dTwistControlEnable',1)
    setAttr(InIk+'.dWorldUpType',4)
    connectAttr(StarObj+'.worldMatrix[0]', InIk+'.dWorldUpMatrix',f=1)
    connectAttr(EndObj+'.worldMatrix[0]', InIk+'.dWorldUpMatrixEnd',f=1)



def YJ_clean_Sp_loc(StarLoc,EndLoc,Ctrl_List):
    Star_Ctrl= Ctrl_List[0]
    End_Ctrl = Ctrl_List[-1]
    YJ_Try_Parent(StarLoc,Star_Ctrl)
    YJ_Try_Parent(EndLoc,End_Ctrl)
    setAttr(StarLoc+".visibility",0)
    setAttr(EndLoc+".visibility",0)