#-*-coding:utf-8 -*-
from maya import mel
from maya import cmds
import pymel.core as pm
import os
import json
import datetime as dt
from . import modeling
from . import common
from . import lang
from . import weight

def main(mesh=None, pop_zero_poly=False):
    cmds.selectMode(o=True)
    #pop_zero_poly→ゼロポリゴンメッシュを発見した場合に警告メッセージを出すかどうか
    msg01 = lang.Lang(
        en='There is a zero polygon object : ',
        ja=u'ゼロポリゴンのメッシュが存在します : ')   
    msg02 = lang.Lang(
        en='As it is in selected state, please process accordingly\n(Recommended to delete)',
        ja=u'選択状態になっているので適宜処理してください \n(削除推奨)')   
    if mesh is None:
        selection = cmds.ls(sl=True)
        selection_l = cmds.ls(sl=True, l=True)
    else:
        selection = mesh
        selection_l = cmds.ls(mesh, l=True)
    zero_mesh = modeling.cehck_zero_poly_object(mesh=selection, pop_msg=False)
    #リストタイプじゃなかったらリストに変換する
    if not isinstance(selection, list):
        temp = selection
        selection = []
        selection.append(temp)
    clusterCopy = modeling.ClusterCopy()
    engine = 'maya'
    for node, node_l in zip(selection, selection_l):
        if node in zero_mesh:
            print 'Skip Zero Triangle Mesh :', node
            continue
        #メッシュノードを含むオブジェクトのみ処理する。
        meshnode = cmds.listRelatives(node_l, s=True, pa=True, type='mesh', fullPath=True)
        if meshnode:
            defCls = clusterCopy.copy(node)
            bs_dict = store_blend_shape(node)
            #ブレンドシェイプを保存
            copyWeight(node_l, engine=engine )
            freezeModeling(node_l, engine=engine )
            if defCls:
                clusterCopy.paste(node)
            set_blend_shape(node, bs_dict)
    cmds.select(cl=True)
    for s in selection:
        try:
            cmds.select(s, add=True)
        except Exception as e:
            print e.message
    if zero_mesh and pop_zero_poly:
        msg = msg01.output()+str(len(zero_mesh))
        msg += '\n'+msg02.output()
        for p in zero_mesh:
            msg+='\n[ '+p+' ]'
        cmds.confirmDialog( title="Warning", message=msg )
        cmds.select(zero_mesh, r=True)
        
#ブレンドシェイプ情報を保存
def store_blend_shape(mesh):
    shapes = cmds.listRelatives(mesh, s=True, f=True)
    skin = cmds.ls(cmds.listHistory(shapes), type='skinCluster')
    if skin:
        connections = cmds.listConnections(skin, s=True, d=False)
    else:
        connections = cmds.listConnections(shapes, s=True, d=False)
    blend_shapes = cmds.ls(connections, l=True, type='blendShape')
    bs_dict = {}
    if blend_shapes:
        for bs in blend_shapes:
            shape_target = cmds.ls(cmds.listConnections(bs, s=True, d=False), l=True, type='transform')
            bs_dict[bs]=shape_target
        return bs_dict
    return
    
def set_blend_shape(mesh, bs_dict):
    if not bs_dict:
        return
    for bs, shape_target in bs_dict.items():
        cmds.blendShape(shape_target+[mesh], name=bs, frontOfChain=True)
    
def repareDagSetMember(node):
    #Dagセットメンバーの接続を修正する、シンメトリウェイトできないとき用。
    shadingEngin = get_shading_engines(node)
    if shadingEngin == []:
        return
    shapes = cmds.listRelatives(node, s=True, pa=True, type='mesh')
    connections = cmds.listConnections(shapes[0], d=True, s=False, p=True, c=True)
    for con in connections:
        if shadingEngin[0]+'.dagSetMembers' in con:
            conAttr = con
            listIndex = connections.index(con)
            disconAttr = connections[listIndex-1]
            cmds.disconnectAttr(disconAttr, conAttr)
    cmds.connectAttr(shapes[0]+'.instObjGroups[0]', conAttr, f=True)
    
def copyWeight(node, engine='maya'):
    weight.WeightCopyPaste().main(node, mode='copy', saveName=__name__, engine=engine)
    
def freezeModeling(node, engine='maya'):
    #子供のノード退避用ダミーペアレントを用意
    dummy = common.TemporaryReparent().main(mode='create')
    common.TemporaryReparent().main(node,dummyParent=dummy, mode='cut')
    #ヒストリを全削除
    cmds.bakePartialHistory(node,pc=True)
    #ウェイトを書き戻してくる
    weight.WeightCopyPaste().main(node, mode='paste', saveName=__name__, engine=engine)
    #いらないシェイプを消す
    deleteZeroShape(node)
    #親子付けを戻す
    common.TemporaryReparent().main(node, dummyParent=dummy, mode='parent')
    #ダミーペアレントを削除
    common.TemporaryReparent().main(dummyParent=dummy, mode='delete')
        
#接続の無い不要なシェイプを削除
def deleteZeroShape(node):
    meshnode = cmds.listRelatives(node, s=True, pa=True, type='mesh', fullPath=True)
    for mesh in meshnode:
        triNum = cmds.polyEvaluate(mesh, triangle=True)
        historyNode = cmds.listHistory(mesh, f=True)
        if len(historyNode) <= 1:
            cmds.delete(mesh)
        
def save_cluster(node):
    #ノードの中からスキンクラスタを取得してくる#inMesh直上がSkinClusterとは限らないので修正
    srcDeformerCluster = cmds.ls(cmds.listHistory(node),type='cluster')
    if not srcDeformerCluster:
        return#スキンクラスタがなかったら関数抜ける
    #スキンクラスタのパラメータ色々を取得しておく
    srcDeformerCluster = srcDeformerCluster[0]
    attributes = cmds.listAttr(srcDeformerCluster)
    weightList = cmds.getAttr(srcDeformerCluster+'.weightList[0]')
    envelope = cmds.getAttr(srcDeformerCluster+'.envelope')
    clusterMssage = cmds.getAttr(srcDeformerCluster+'.message')
    clusterWeight = cmds.getAttr(srcDeformerCluster+'.weightList[0].weights')
    
def freeze():
    cmds.selectMode(o=True)
    selection = cmds.ls(sl=True, type = 'transform')
    dummy = common.TemporaryReparent().main(mode='create')#モジュールでダミーの親作成
    clusterCopy = modeling.ClusterCopy()
    for sel in selection:
        allChildren = [sel] + cmds.listRelatives(sel, ad=True)#子供を取得して1つのリストにする
        polyMesh = common.search_polygon_mesh(allChildren)
        if polyMesh:
            for mesh in polyMesh:
                common.TemporaryReparent().main(mesh, dummyParent=dummy, mode='cut')
                defCls = clusterCopy.copy(mesh)
                cmds.bakePartialHistory(mesh,pc=True)
                if defCls:
                    clusterCopy.paste(mesh)
                common.TemporaryReparent().main(mesh, dummyParent=dummy, mode='parent')#コピーのおわったメッシュの子供を元に戻す
    common.TemporaryReparent().main(dummyParent=dummy, mode='delete')#ダミー親削除
    cmds.select(selection, r=True)
    
def get_shading_engines(root_node=None):
    en_list = []
    if root_node is None:
        shapes = pm.ls(type="mesh")
    else:
        if isinstance(root_node, (str, unicode)):
            root_node = pm.PyNode(root_node)
        shapes = root_node.listRelatives(ad=True, type="mesh")
    file_nodes = []
    for i in shapes:
        shading_engines = i.shadingGroups()
        en_list+=shading_engines
    return list(set(en_list))