//Get the next variable frame
    public VarFrame getNextFrame(string varName)
    {
        foreach (CustAnim anim in animations)
        {
            if (anim.name.ToUpper() == currentAnim.ToUpper())
            {
                foreach (VarFrame frame in anim.varFrames)
                {
                    if (frame.varName == varName)
                    {
                        //This frame has to be for us
                        if (frame.frameTime >= currTime)
                        {
                            return(frame);
                        }
                    }
                }

                break;
            }
        }

        //Debug.Log("Animation " + currentAnim + " not found or animation does not contain variable " + varName);
        VarFrame newFrame = new VarFrame();

        newFrame.animName = "NA";

        return(newFrame);
    }
    //Get the previous variable frame
    public VarFrame getPreviousFrame(string varName)
    {
        foreach (CustAnim anim in animations)
        {
            if (anim.name.ToUpper() == currentAnim.ToUpper())
            {
                VarFrame prevFrame = new VarFrame();

                foreach (VarFrame frame in anim.varFrames)
                {
                    if (frame.varName == varName)
                    {
                        //This frame has to be for us
                        if (frame.frameTime <= currTime)
                        {
                            if ((frame.creationFrame && currTime < 32f) || currTime >= anim.duration)
                            {
                                //This is within the first frame of existence, likely a starting time, or otherwise the last frame where we "stay" unless we loop
                                return(frame);
                            }
                            else
                            {
                                //Store this one for later, for now we can assume the file is in chronological order until we have a better JSON or XML format
                                prevFrame = frame;
                            }
                        }
                        else
                        {
                            //We went too far now, return the previous one
                            return(prevFrame);
                        }
                    }
                }

                break;
            }
        }

        //Debug.Log("Animation " + currentAnim + " not found or animation does not contain variable " + varName);
        VarFrame newFrame = new VarFrame();

        newFrame.animName = "NA";

        return(newFrame);
    }
    //Add a variable keyframe to the animation
    public void AddVarFrame(string animName, VarFrame frame)
    {
        bool foundAnim = false;

        foreach (CustAnim anim in animations)
        {
            if (anim.name.ToUpper() == animName.ToUpper())
            {
                if (!anim.variables.ContainsKey(frame.varName))
                {
                    //Creation frame!
                    frame.creationFrame = true;
                    anim.variables.Add(frame.varName, frame.value);
                }

                anim.varFrames.Add(frame);

                foundAnim = true;
                break;
            }
        }

        if (!foundAnim)
        {
            CustAnim anim = new CustAnim();
            anim.name = animName;

            if (!anim.variables.ContainsKey(frame.varName))
            {
                //Creation frame!
                frame.creationFrame = true;
                anim.variables.Add(frame.varName, frame.value);
            }

            anim.varFrames.Add(frame);

            animations.Add(anim);
        }
    }
    //Parse the data from file into animation data
    private void parseLines(List <string> data)
    {
        foreach (string line in data)
        {
            string[] split = line.Split(',');

            if (split.Length > 12)
            {
                //Key frame
                KeyFrame frame = new KeyFrame();

                if (split.Length > 13)
                {
                    //For a new object
                    int id = 0;
                    int.TryParse(split[0], out id);
                    frame.objID = id;

                    frame.objDesc  = split[1];
                    frame.animName = split[2];

                    int childOf = 0;
                    int.TryParse(split[3], out childOf);
                    frame.childOf = childOf;

                    int frameTime = 0;
                    int.TryParse(split[4], out frameTime);
                    frame.frameTime = frameTime;

                    int instant = 0;
                    int.TryParse(split[5], out instant);
                    if (instant > 0)
                    {
                        frame.instant = true;
                    }

                    float pX = 0f;
                    float pY = 0f;
                    float pZ = 0f;

                    float.TryParse(split[6], out pX);
                    float.TryParse(split[7], out pY);
                    float.TryParse(split[8], out pZ);

                    frame.position = new Vector3(pX, pY, pZ);

                    float rX = 0f;
                    float rY = 0f;
                    float rZ = 0f;

                    float.TryParse(split[9], out rX);
                    float.TryParse(split[10], out rY);
                    float.TryParse(split[11], out rZ);

                    frame.rotation = new Vector3(rX, rY, rZ);

                    float sX = 0f;
                    float sY = 0f;
                    float sZ = 0f;

                    float.TryParse(split[12], out sX);
                    float.TryParse(split[13], out sY);
                    float.TryParse(split[14], out sZ);

                    frame.scale = new Vector3(sX, sY, sZ);

                    myAnim.AddKeyFrame(frame.animName, frame);
                }
                else
                {
                    //For an existing object
                    int id = 0;
                    int.TryParse(split[0], out id);
                    frame.objID = id;

                    frame.animName = split[1];

                    int frameTime = 0;
                    int.TryParse(split[2], out frameTime);
                    frame.frameTime = frameTime;

                    int instant = 0;
                    int.TryParse(split[3], out instant);
                    if (instant > 0)
                    {
                        frame.instant = true;
                    }

                    float pX = 0f;
                    float pY = 0f;
                    float pZ = 0f;

                    float.TryParse(split[4], out pX);
                    float.TryParse(split[5], out pY);
                    float.TryParse(split[6], out pZ);

                    frame.position = new Vector3(pX, pY, pZ);

                    float rX = 0f;
                    float rY = 0f;
                    float rZ = 0f;

                    float.TryParse(split[7], out rX);
                    float.TryParse(split[8], out rY);
                    float.TryParse(split[9], out rZ);

                    frame.rotation = new Vector3(rX, rY, rZ);

                    float sX = 0f;
                    float sY = 0f;
                    float sZ = 0f;

                    float.TryParse(split[10], out sX);
                    float.TryParse(split[11], out sY);
                    float.TryParse(split[12], out sZ);

                    frame.scale = new Vector3(sX, sY, sZ);

                    myAnim.AddKeyFrame(frame.animName, frame);
                }
            }
            else if (split.Length > 4)
            {
                //Variable frame
                VarFrame frame = new VarFrame();
                frame.varName  = split[0];
                frame.animName = split[1];

                int   frameTime = 0;
                int   instant   = 0;
                float value     = 0f;

                int.TryParse(split[2], out frameTime);
                frame.frameTime = frameTime;

                int.TryParse(split[3], out instant);
                if (instant > 0)
                {
                    frame.instant = true;
                }

                float.TryParse(split[4], out value);
                frame.value = value;

                myAnim.AddVarFrame(split[1], frame);
            }
            else if (split.Length > 2)
            {
                //Animation configuration
                string animName = split[0];

                int loopVal = 0;
                int.TryParse(split[1], out loopVal);
                bool loop = false;
                if (loopVal > 0)
                {
                    loop = true;
                }

                string goToAnim = split[2];

                if (goToAnim.ToUpper() == "NA")
                {
                    goToAnim = "";
                }

                myAnim.AnimConfig(animName, loop, goToAnim);
            }
        }

        myAnim.isLoaded = true;
        Debug.Log(data[0]);//Done loading
    }
    //Update all code to do with the animation itself
    public void update()
    {
        foreach (CustAnim anim in animations)
        {
            if (anim.name.ToUpper() == currentAnim.ToUpper())
            {
                //This is our animation
                foreach (KeyValuePair <int, GameObject> pair in anim.assignedObjects)
                {
                    //Animate each object
                    KeyFrame prev = getPreviousFrame(pair.Value, pair.Key);
                    KeyFrame next = getNextFrame(pair.Value, pair.Key);

                    if (prev.animName != "NA" && next.animName != "NA")
                    {
                        //We can only animate if the frames exist

                        if (prev.creationFrame)
                        {
                            if (prev.childOf > 0)
                            {
                                if (anim.assignedObjects.ContainsKey(prev.childOf))
                                {
                                    //Also make sure we are parented properly
                                    pair.Value.transform.parent = anim.assignedObjects[prev.childOf].transform;
                                }
                            }

                            //Set the base value to start
                            pair.Value.transform.localPosition    = prev.position;
                            pair.Value.transform.localEulerAngles = prev.rotation;
                            pair.Value.transform.localScale       = prev.scale;
                        }

                        if (next.instant)
                        {
                            //We don't interpolate, we just stay at the previous frame values
                            pair.Value.transform.localPosition    = prev.position;
                            pair.Value.transform.localEulerAngles = prev.rotation;
                            pair.Value.transform.localScale       = prev.scale;
                        }
                        else
                        {
                            //Smooth interpolation between previous and next frame
                            float percentage = (currTime - prev.frameTime) / (next.frameTime - prev.frameTime);
                            if (float.IsNaN(percentage))
                            {
                                percentage = 0f;
                            }

                            pair.Value.transform.localPosition    = Vector3.Lerp(prev.position, next.position, percentage);
                            pair.Value.transform.localEulerAngles = Vector3.Lerp(prev.rotation, next.rotation, percentage);
                            pair.Value.transform.localScale       = Vector3.Lerp(prev.scale, next.scale, percentage);
                        }
                    }
                }

                //Animate our variables
                List <string> modVars = new List <string>();
                List <float>  valVars = new List <float>();

                foreach (KeyValuePair <string, float> pair in anim.variables)
                {
                    VarFrame prev = getPreviousFrame(pair.Key);
                    VarFrame next = getNextFrame(pair.Key);

                    if (prev.animName != "NA" && next.animName != "NA")
                    {
                        if (next.instant)
                        {
                            //Stay at previous value
                            modVars.Add(pair.Key);
                            valVars.Add(prev.value);
                        }
                        else
                        {
                            //Smooth interpolation between previous and next frame
                            float percentage = (currTime - prev.frameTime) / (next.frameTime - prev.frameTime);
                            if (float.IsNaN(percentage))
                            {
                                percentage = 0f;
                            }

                            modVars.Add(pair.Key);
                            valVars.Add(Mathf.Lerp(prev.value, next.value, percentage));
                        }
                    }
                }

                for (int i = 0; i < modVars.Count; i++)
                {
                    anim.variables[modVars[i]] = valVars[i];
                }

                //Timing and transitions
                if (isPlaying)
                {
                    //Advance time and update
                    currTime += 1000f * animSpeed * Time.deltaTime;
                }

                if (currTime >= anim.duration)
                {
                    if (anim.loop)
                    {
                        currTime = 0f; //Restart the animation
                    }
                    else if (anim.goToAnim != "")
                    {
                        setAnim(anim.goToAnim); //Set the animation we are going to
                    }
                    else
                    {
                        isPlaying = false;         //Done playing
                        currTime  = anim.duration; //Set to end frame
                    }
                }

                break;
            }
        }
    }