#include "stdafx.h"

#ifdef STRICT							// Already defined by stdafx,
#undef STRICT							// so we avoid warning linking msg
#endif
#ifdef _MBCS							// The same as above
#undef _MBCS
#endif


#include "LegMirrorPanel.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


// Reverse Animation Tools

void LegMirrorPanel::DoReverse()
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    HINSTANCE loc_hInstance = AfxGetResourceHandle ();
    
    ReverseAnimation(m_ip->GetRootNode());
    ReverseExpressions(m_ip->GetRootNode());
    
    m_ip->ForceCompleteRedraw();
    
    
}



void LegMirrorPanel::ReverseAnimation(INode *nde)
{
    
    
    ReverseKeys(nde);
    
    
    for(int i=0;i<nde->NumberOfChildren();i++)
    {
        ReverseAnimation(nde->GetChildNode(i));
    }
}

void LegMirrorPanel::ReverseKeys(INode *nde)
{
    
    Control *tm_con,*pos_con,*rot_con,*xp_con,*yp_con,*zp_con,*xr_con,*yr_con,*zr_con;
    IKeyControl *ikc;
    
    tm_con = nde->GetTMController();
    if(tm_con!=NULL)
    {
        pos_con = tm_con->GetPositionController();
        rot_con = tm_con->GetRotationController();
        
        if(rot_con)
        {
            xr_con=rot_con->GetXController();
            if(xr_con!=NULL)
            {
                ikc = GetKeyControlInterface(xr_con);
                if(ikc)
                    ReverseControl(ikc,xr_con->ClassID());
            }
            
            yr_con=rot_con->GetYController();
            if(yr_con!=NULL)
            {
                ikc = GetKeyControlInterface(yr_con);
                if(ikc)
                    ReverseControl(ikc,yr_con->ClassID());
            }
            
            zr_con=rot_con->GetZController();
            if(zr_con!=NULL)
            {
                ikc = GetKeyControlInterface(zr_con);
                if(ikc)
                    ReverseControl(ikc,zr_con->ClassID());
            }
            
            ikc = GetKeyControlInterface(rot_con);
            if(ikc)
                ReverseControl(ikc,rot_con->ClassID());
        }
        
        
        
        if(pos_con)
        {
            xp_con=pos_con->GetXController();
            if(xp_con!=NULL)
            {
                ikc = GetKeyControlInterface(xp_con);
                if(ikc)
                    ReverseControl(ikc,xp_con->ClassID());
            }
            
            yp_con=pos_con->GetYController();
            if(yp_con!=NULL)
            {
                ikc = GetKeyControlInterface(yp_con);
                if(ikc)
                    ReverseControl(ikc,yp_con->ClassID());
            }
            
            zp_con=pos_con->GetZController();
            if(zp_con!=NULL)
            {
                ikc = GetKeyControlInterface(zp_con);
                if(ikc)
                    ReverseControl(ikc,zp_con->ClassID());
            }
            ikc = GetKeyControlInterface(pos_con);
            if(ikc)
                ReverseControl(ikc,pos_con->ClassID());
        }
        
    }
    
}

void LegMirrorPanel::ReverseControl(IKeyControl *ikc,Class_ID id)
{
    
    int key_number,MaxKeys;
    MaxKeys=ikc->GetNumKeys();
    
    
    IKey *kpt;
    
    if (id == Class_ID(LININTERP_FLOAT_CLASS_ID,0))
    {
        kpt=(IKey *)new ILinFloatKey;
    }
    else if (id == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0))
    {
        kpt=(IKey *)new IBezFloatKey;
    }
    else if (id == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0))
    {	
        kpt=(IKey *)new ITCBFloatKey;
    }	
    else if (id == Class_ID(LININTERP_POSITION_CLASS_ID,0))
    {
        kpt=(IKey *)new ILinPoint3Key;
    }
    else if (id == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID,0))
    {
        kpt=(IKey *)new IBezPoint3Key;
    }
    else if (id == Class_ID(TCBINTERP_POSITION_CLASS_ID,0))
    {
        kpt=(IKey *)new ITCBPoint3Key;
    }
    else if (id == Class_ID(LININTERP_ROTATION_CLASS_ID,0))
    {
        kpt=(IKey *)new ILinRotKey;
    }
    else if (id == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID,0))
    {
        kpt=(IKey *)new IBezQuatKey;
    }
    else if (id == Class_ID(TCBINTERP_ROTATION_CLASS_ID,0))
    {
        kpt=(IKey *)new ITCBRotKey;
    }
    else if (id == Class_ID(HYBRIDINTERP_POINT3_CLASS_ID,0))
    {
        kpt=(IKey *)new IBezPoint3Key;
    }
    else if (id == Class_ID(TCBINTERP_POINT3_CLASS_ID,0))
    {
        kpt=(IKey *)new ITCBPoint3Key;
    }
    
    TimeValue ftime;
    Interval ivl;
    
    ivl=m_ip->GetAnimRange();
    ftime=ivl.End();
    
    
    //Reorder Keys;
    for(key_number=0;key_number<MaxKeys;key_number++)
    {
        ikc->GetKey(key_number,kpt);
        kpt->time=ftime-kpt->time;
        DWORD it,ot;
        it=GetInTanType(kpt->flags);
        ot=GetOutTanType(kpt->flags);
        SetInTanType(kpt->flags,ot);
        SetOutTanType(kpt->flags,it);
        ikc->SetKey(key_number,kpt);
    }
    
    ikc->SortKeys();
    
    delete kpt;
    
    //Reverse Tangents
    if(id == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0) || id == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID,0))
        for(key_number=0;key_number<MaxKeys;key_number++)
        {
            if (id == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0))
            {
                IBezFloatKey key;
                float ftmp;
                ikc->GetKey(key_number, &key);
                
                ftmp=key.intan;
                key.intan=key.outtan;
                key.outtan=ftmp;
                ikc->SetKey(key_number, &key);
            }
            else if (id == Class_ID(HYBRIDINTERP_POSITION_CLASS_ID,0))
            {
                IBezPoint3Key key;
                ikc->GetKey(key_number, &key);
                
                Point3 ftmp;
                ftmp=key.intan;
                key.intan=key.outtan;
                key.outtan=ftmp;
                
                ikc->SetKey(key_number, &key);
            }
        }			// end of for i				
        
        
}

void LegMirrorPanel::ReverseExpressions(INode *nde)
{
    
    for(int i=0;i<nde->NumberOfChildren();i++)
    {
        ReverseExpressions(nde->GetChildNode(i));
    }
    
    CString str(nde->GetName());
    //if( IsHandle(str)) return;
    //   !IsJoint(str)) return;
    
    
    Control *tm_con,*pos_con,*rot_con,*xp_con,*yp_con,*zp_con,*xr_con,*yr_con,*zr_con;
    
    tm_con = nde->GetTMController();
    if(tm_con!=NULL)
    {
        pos_con = tm_con->GetPositionController();
        rot_con = tm_con->GetRotationController();
        
        
        if(pos_con)
        {
            xp_con=pos_con->GetXController();
            if(xp_con!=NULL)
            {
                if(!GetKeyControlInterface(xp_con)  &&
                    IsExprControl(xp_con) )
                {
                    //				ReverseExpControl((ExprControl *)xp_con);
                }
            }
            
            yp_con=pos_con->GetYController();
            if(yp_con!=NULL)
            {
                if(!GetKeyControlInterface(yp_con)  && 
                    IsExprControl(yp_con) )
                {
                    ReverseExpControl((ExprControl *)yp_con);
                }
            }
            
            zp_con=pos_con->GetZController();
            if(zp_con!=NULL)
            {
                if(!GetKeyControlInterface(zp_con)  && 
                    IsExprControl(zp_con) )
                {
                    //				ReverseExpControl((ExprControl *)zp_con);
                }
            }
        }
        
        
        if(rot_con)
        {
            xr_con=rot_con->GetXController();
            if(xr_con!=NULL)
            {
                if(!GetKeyControlInterface(xr_con) && 
                    IsExprControl(xr_con) )
                {
                    //				ReverseExpControl((ExprControl *)xr_con);
                }
            }
            
            yr_con=rot_con->GetYController();
            if(yr_con!=NULL)
            {
                if(!GetKeyControlInterface(yr_con) &&
                    IsExprControl(yr_con) )
                {
                    //				ReverseExpControl((ExprControl *)yr_con);
                }
            }
            
            zr_con=rot_con->GetZController();
            if(zr_con!=NULL)
            {
                if(!GetKeyControlInterface(zr_con) && 
                    IsExprControl(zr_con) )
                {
                    //				ReverseExpControl((ExprControl *)zr_con);
                }
            }
        }
        
    }
    
    
}

void LegMirrorPanel::ReverseExpControl(ExprControl *expc)
{
    
    CString es(expc->expr.getExprStr());
    
    int i;
    
    for(i=0;i<es.GetLength();i++)
    {
        if(es[i]=='+')
        {
            es.SetAt(i,'-');
        }
        else
            if(es[i]=='-')
            {
                es.SetAt(i,'+');
            }
    }
    
    expc->expr.load((char *)(LPCTSTR)es);
    
    
    
}

bool LegMirrorPanel::IsReversable(INode *nde)
{
    if(!nde->GetTMController()) return false;
    if( nde->GetTMController()->ClassID()==Class_ID(PRS_CONTROL_CLASS_ID,0))
        return true;
    else
        return false;
}
