// Path: src/main/java/com/github/atomicblom/weirdinggadget/Logger.java
// public enum Logger
// {
//     INSTANCE;
// 
//     @SuppressWarnings({"NonSerializableFieldInSerializableClass", "InstanceVariableMayNotBeInitialized"})
//     private org.apache.logging.log4j.Logger logger;
// 
//     public static void info(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.INFO, format, args);
//     }
// 
//     public static void log(final Level level, final Throwable exception, final String format, final Object... args)
//     {
//         //noinspection ChainedMethodCall
//         INSTANCE.getLogger().log(level, String.format(format, args), exception);
//     }
// 
//     public static void severe(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.ERROR, format, args);
//     }
// 
//     public static void warning(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.WARN, format, args);
//     }
// 
//     public static void trace(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.TRACE, format, args);
//     }
// 
//     private org.apache.logging.log4j.Logger getLogger()
//     {
//         if (logger == null)
//         {
//             init();
//         }
// 
//         return logger;
//     }
// 
//     private void init()
//     {
//         if (logger == null)
//         {
//             logger = LogManager.getLogger(WeirdingGadgetMod.MODID);
//         }
//     }
// 
//     private void log(final Level level, final String format, final Object... data)
//     {
//         //noinspection ChainedMethodCall
//         getLogger().log(level, String.format(format, data));
//     }
// }


import com.github.atomicblom.weirdinggadget.Logger;
import com.github.atomicblom.weirdinggadget.client.opengex.ogex.*;
package com.github.atomicblom.weirdinggadget.client.opengex;


/**
 * Created by codew on 4/11/2015.
 */
public class Animation
{
    //WARNING: THIS METHOD IS NOT THREAD SAFE. DO NOT GET CREATIVE WITH IT.
    public static float[][] calculateTransforms(OgexScene scene, float animationTime, OgexNode[] nodes, Integer[] nodeParentMap) {
        //long currentAnimationFrameTime = 0;
        //long animationTime = 0;

        final float[][] nodeTransforms = new float[nodes.length][16];
        final float[][] parentTransforms = new float[nodes.length][16];

        for (int nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
            final OgexNode node = nodes[nodeIndex];

            float[] nodeMatrix = OgexMatrixTransform.identity();
            final Integer parentNodeIndex = nodeParentMap[nodeIndex];
            if (parentNodeIndex != null) {
                final float[] parentMatrix = parentTransforms[parentNodeIndex];
                nodeMatrix = parentMatrix.clone();
            }

            for (final OgexAnimation animation : node.getAnimations()) {
                float actualAnimationTime = animation.getBegin() + animationTime;
                while (actualAnimationTime > animation.getEnd()) {
                    actualAnimationTime -= animation.getEnd();
                }

                for (final OgexTrack track : animation) {
                    Object target = track.getTarget();
                    float value = getCurrentValueForTrack(scene, track, actualAnimationTime);

                    if (target instanceof OgexTranslation.ComponentTranslation) {
                        ((OgexTranslation.ComponentTranslation) target).setTranslation(value);
                    } else if (target instanceof OgexRotation.ComponentRotation) {
                        ((OgexRotation.ComponentRotation) target).setAngle(value);
                    } else {
// Path: src/main/java/com/github/atomicblom/weirdinggadget/Logger.java
// public enum Logger
// {
//     INSTANCE;
// 
//     @SuppressWarnings({"NonSerializableFieldInSerializableClass", "InstanceVariableMayNotBeInitialized"})
//     private org.apache.logging.log4j.Logger logger;
// 
//     public static void info(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.INFO, format, args);
//     }
// 
//     public static void log(final Level level, final Throwable exception, final String format, final Object... args)
//     {
//         //noinspection ChainedMethodCall
//         INSTANCE.getLogger().log(level, String.format(format, args), exception);
//     }
// 
//     public static void severe(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.ERROR, format, args);
//     }
// 
//     public static void warning(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.WARN, format, args);
//     }
// 
//     public static void trace(final String format, final Object... args)
//     {
//         INSTANCE.log(Level.TRACE, format, args);
//     }
// 
//     private org.apache.logging.log4j.Logger getLogger()
//     {
//         if (logger == null)
//         {
//             init();
//         }
// 
//         return logger;
//     }
// 
//     private void init()
//     {
//         if (logger == null)
//         {
//             logger = LogManager.getLogger(WeirdingGadgetMod.MODID);
//         }
//     }
// 
//     private void log(final Level level, final String format, final Object... data)
//     {
//         //noinspection ChainedMethodCall
//         getLogger().log(level, String.format(format, data));
//     }
// }


// Path: src/main/java/com/github/atomicblom/weirdinggadget/client/opengex/Animation.java
import com.github.atomicblom.weirdinggadget.Logger;
import com.github.atomicblom.weirdinggadget.client.opengex.ogex.*;

package com.github.atomicblom.weirdinggadget.client.opengex;


/**
 * Created by codew on 4/11/2015.
 */
public class Animation
{
    //WARNING: THIS METHOD IS NOT THREAD SAFE. DO NOT GET CREATIVE WITH IT.
    public static float[][] calculateTransforms(OgexScene scene, float animationTime, OgexNode[] nodes, Integer[] nodeParentMap) {
        //long currentAnimationFrameTime = 0;
        //long animationTime = 0;

        final float[][] nodeTransforms = new float[nodes.length][16];
        final float[][] parentTransforms = new float[nodes.length][16];

        for (int nodeIndex = 0; nodeIndex < nodes.length; nodeIndex++) {
            final OgexNode node = nodes[nodeIndex];

            float[] nodeMatrix = OgexMatrixTransform.identity();
            final Integer parentNodeIndex = nodeParentMap[nodeIndex];
            if (parentNodeIndex != null) {
                final float[] parentMatrix = parentTransforms[parentNodeIndex];
                nodeMatrix = parentMatrix.clone();
            }

            for (final OgexAnimation animation : node.getAnimations()) {
                float actualAnimationTime = animation.getBegin() + animationTime;
                while (actualAnimationTime > animation.getEnd()) {
                    actualAnimationTime -= animation.getEnd();
                }

                for (final OgexTrack track : animation) {
                    Object target = track.getTarget();
                    float value = getCurrentValueForTrack(scene, track, actualAnimationTime);

                    if (target instanceof OgexTranslation.ComponentTranslation) {
                        ((OgexTranslation.ComponentTranslation) target).setTranslation(value);
                    } else if (target instanceof OgexRotation.ComponentRotation) {
                        ((OgexRotation.ComponentRotation) target).setAngle(value);
                    } else {
                        Logger.info("Breakpoint");