void Tools::DisplayAnimation::DisplayChannels( FbxNode* i_node, FbxAnimLayer* i_animLayer, void (*DisplayCurve) (FbxAnimCurve* i_curve), void (*DisplayListCurve) (FbxAnimCurve* i_curve, FbxProperty* i_property), bool isSwitcher )
{
	FbxAnimCurve *animCurve = NULL;

	// Display general curves.
	if (!isSwitcher)
	{
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        TX\n" );
			DisplayCommon::DisplayString( "        TX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        TY\n" );
			DisplayCommon::DisplayString( "        TY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        TZ\n" );
			DisplayCommon::DisplayString( "        TZ" );
			DisplayCurve( animCurve );
		}

		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        RX\n" );
			DisplayCommon::DisplayString( "        RX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        RY\n" );
			DisplayCommon::DisplayString( "        RY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        RZ\n" );
			DisplayCommon::DisplayString( "        RZ" );
			DisplayCurve( animCurve );
		}

		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        SX\n" );
			DisplayCommon::DisplayString( "        SX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        SY\n" );
			DisplayCommon::DisplayString( "        SY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        SZ\n" );
			DisplayCommon::DisplayString( "        SZ" );
			DisplayCurve( animCurve );
		}
	}

	// Display curves specific to a light or marker.
	FbxNodeAttribute *nodeAttribute = i_node->GetNodeAttribute();

	if( nodeAttribute )
	{
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_RED );
		if( animCurve )
		{
			FBXSDK_printf( "        Red\n" );
			DisplayCommon::DisplayString( "        Red" );
			DisplayCurve( animCurve );
		}
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_GREEN );
		if( animCurve )
		{
			FBXSDK_printf( "        Green\n" );
			DisplayCommon::DisplayString( "        Green" );
			DisplayCurve( animCurve );
		}
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_BLUE );
		if( animCurve )
		{
			FBXSDK_printf( "        Blue\n" );
			DisplayCommon::DisplayString( "        Blue" );
			DisplayCurve( animCurve );
		}

		// Display curves specific to a light.
		FbxLight *light = i_node->GetLight();
		if( light )
		{
			animCurve = light->Intensity.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Intensity\n" );
				DisplayCommon::DisplayString( "        Intensity" );
				DisplayCurve( animCurve );
			}

			animCurve = light->OuterAngle.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Outer Angle\n" );
				DisplayCommon::DisplayString( "        Outer Angle" );
				DisplayCurve( animCurve );
			}

			animCurve = light->Fog.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Fog\n" );
				DisplayCommon::DisplayString( "        Fog" );
				DisplayCurve( animCurve );
			}
		}

		// Display curves specific to a camera.
		FbxCamera *camera = i_node->GetCamera();
		if( camera )
		{
			animCurve = camera->FieldOfView.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View\n" );
				DisplayCommon::DisplayString( "        Field of View" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->FieldOfViewX.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View X\n" );
				DisplayCommon::DisplayString( "        Field of View X" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->FieldOfViewY.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View Y\n" );
				DisplayCommon::DisplayString( "        Field of View Y" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->OpticalCenterX.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Optical Center X\n" );
				DisplayCommon::DisplayString( "        Optical Center X" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->OpticalCenterY.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Optical Center Y\n" );
				DisplayCommon::DisplayString( "        Optical Center Y" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->Roll.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Roll\n" );
				DisplayCommon::DisplayString( "        Roll" );
				DisplayCurve( animCurve );
			}
		}

		// Display curves specific to a geometry.
		if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh ||
			nodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbs ||
			nodeAttribute->GetAttributeType() == FbxNodeAttribute::ePatch)
		{
			FbxGeometry *geometry = (FbxGeometry*) nodeAttribute;

			int blendShapeDeformerCount = geometry->GetDeformerCount( FbxDeformer::eBlendShape );
			for( int blendShapeIndex = 0; blendShapeIndex<blendShapeDeformerCount; blendShapeIndex++ )
			{
				FbxBlendShape *blendShape = (FbxBlendShape*)geometry->GetDeformer( blendShapeIndex, FbxDeformer::eBlendShape );

				int blendShapeChannelCount = blendShape->GetBlendShapeChannelCount();
				for( int channelIndex = 0; channelIndex<blendShapeChannelCount; channelIndex++ )
				{
					FbxBlendShapeChannel *channel = blendShape->GetBlendShapeChannel( channelIndex );
					const char *channelName = channel->GetName();

					animCurve = geometry->GetShapeChannel( blendShapeIndex, channelIndex, i_animLayer, true );
					if( animCurve )
					{
						FBXSDK_printf( "        Shape %s\n", channelName );
						DisplayCommon::DisplayString( "        Shape ", channelName );
						DisplayCurve( animCurve );
					}
				}
			}
		}
	}

	// Display curves specific to properties
	FbxProperty lProperty = i_node->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		if( lProperty.GetFlag(FbxPropertyAttr::eUserDefined) )
		{
			FbxString lFbxFCurveNodeName  = lProperty.GetName();
			FbxAnimCurveNode* curveNode = lProperty.GetCurveNode( i_animLayer );

			if( !curveNode )
			{
				lProperty = i_node->GetNextProperty( lProperty );
				continue;
			}

			FbxDataType dataType = lProperty.GetPropertyDataType();
			if( dataType.GetType() == eFbxBool || dataType.GetType() == eFbxDouble || dataType.GetType() == eFbxFloat || dataType.GetType() == eFbxInt )
			{
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				};

				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
						DisplayCurve( animCurve );
				}
			}
			else if( dataType.GetType() == eFbxDouble3 || dataType.GetType() == eFbxDouble4 || dataType.Is(FbxColor3DT) || dataType.Is(FbxColor4DT) )
			{
				char* componentName1 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_RED : (char*)"X";
				char* componentName2 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_GREEN : (char*)"Y";
				char* componentName3 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_BLUE  : (char*)"Z";
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				}
				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName1 );
						DisplayCurve( animCurve );
					}
				}

				for( int c = 0; c < curveNode->GetCurveCount(1U); c++ )
				{
					animCurve = curveNode->GetCurve(1U, c);
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName2 );
						DisplayCurve( animCurve );
					}
				}

				for( int c = 0; c < curveNode->GetCurveCount(2U); c++ )
				{
					animCurve = curveNode->GetCurve( 2U, c );
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName3 );
						DisplayCurve( animCurve );
					}
				}
			}
			else if( dataType.GetType() == eFbxEnum )
			{
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				};
				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
						DisplayListCurve( animCurve, &lProperty );
				}
			}
		}

		lProperty = i_node->GetNextProperty( lProperty );
	} // while
}
void Tools::DisplayGenericInfo::DisplayProperties( FbxObject *i_object )
{
	DisplayCommon::DisplayString( "Name: ", (char *)i_object->GetName() );

	// Display all the properties
	int i, count = 0;
	FbxProperty lProperty = i_object->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		count++;
		lProperty = i_object->GetNextProperty( lProperty );
	}

	FbxString lTitleStr = "    Property Count: ";

	if( count == 0 )
		return; // there are no properties to display

	DisplayCommon::DisplayInt( lTitleStr.Buffer(), count );

	i = 0;
	lProperty = i_object->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		// exclude user properties
		FbxString string;
		DisplayCommon::DisplayInt( "        Property ", i );
		string = lProperty.GetLabel();
		DisplayCommon::DisplayString( "            Display Name: ", string );
		string = lProperty.GetName();
		DisplayCommon::DisplayString( "            Internal Name: ", string.Buffer() );
		string = lProperty.GetPropertyDataType().GetName();
		DisplayCommon::DisplayString( "            Type: ",string.Buffer() );
		if (lProperty.HasMinLimit())
			DisplayCommon::DisplayDouble( "            Min Limit: ", lProperty.GetMinLimit() );
		if (lProperty.HasMaxLimit())
			DisplayCommon::DisplayDouble( "            Max Limit: ", lProperty.GetMaxLimit() );
		DisplayCommon::DisplayBool( "            Is Animatable: ", lProperty.GetFlag(FbxPropertyAttr::eAnimatable) );

		switch( lProperty.GetPropertyDataType().GetType() )
		{
		case eFbxBool:
			DisplayCommon::DisplayBool( "            Default Value: ", lProperty.Get<FbxBool>() );
			break;

		case eFbxDouble:
			DisplayCommon::DisplayDouble( "            Default Value: ", lProperty.Get<FbxDouble>() );
			break;

		case eFbxDouble4:
			{
				FbxColor lDefault;
				char buffer[64];

				lDefault = lProperty.Get<FbxColor>();
				FBXSDK_sprintf( buffer, 64, "R=%f, G=%f, B=%f, A=%f", lDefault.mRed, lDefault.mGreen, lDefault.mBlue, lDefault.mAlpha );
				DisplayCommon::DisplayString( "            Default Value: ", buffer );
			}
			break;

		case eFbxInt:
			DisplayCommon::DisplayInt( "            Default Value: ", lProperty.Get<FbxInt>() );
			break;

		case eFbxDouble3:
			{
				FbxDouble3 lDefault;
				char buffer[64];

				lDefault = lProperty.Get<FbxDouble3>();
				FBXSDK_sprintf( buffer, 64, "X=%f, Y=%f, Z=%f", lDefault[0], lDefault[1], lDefault[2] );
				DisplayCommon::DisplayString( "            Default Value: ", buffer );
			}
			break;

			//case FbxEnumDT:
			//    DisplayInt("            Default Value: ", lProperty.Get<FbxEnum>());
			//    break;

		case eFbxFloat:
			DisplayCommon::DisplayDouble( "            Default Value: ", lProperty.Get<FbxFloat>() );
			break;

		case eFbxString:
			string = lProperty.Get<FbxString>();
			DisplayCommon::DisplayString( "            Default Value: ", string.Buffer() );
			break;

		default:
			DisplayCommon::DisplayString( "            Default Value: UNIDENTIFIED" );
			break;
		}
		i++;
		lProperty = i_object->GetNextProperty( lProperty );
	}
}