void ApplicationEngine::Initialize(int width, int height)
{
    m_trackballRadius = width / 3;
    m_screenSize = ivec2(width, height);
    m_centerPoint = m_screenSize / 2;
    string path = m_resourceManager->GetResourcePath();
    
    vector<ISurface*> surfaces(SurfaceCount);

    FLTetrahedronWithBoundsDivisions* FLTWBD = new FLTetrahedronWithBoundsDivisions(2.5, GL_LINES);
    
    surfaces[0] = new FLTetrahedronQuaternaryPhaseDiagram(path + "/nimninco.ABCD", 2.5, GL_TRIANGLES);
    
    surfaces[1] = FLTWBD;

    surfaces[2] = new FLText3D("ni", (FLTWBD->topVertex.Position) - (FLTWBD->translateOriginToCenterOfMassVector));
     
    surfaces[3] = new FLText3D("mn", (FLTWBD->rightVertex.Position) - (FLTWBD->translateOriginToCenterOfMassVector));

    surfaces[4] = new FLText3D("in", (FLTWBD->leftVertex.Position) - (FLTWBD->translateOriginToCenterOfMassVector));
    
    surfaces[5] = new FLText3D("co", (FLTWBD->frontVertex.Position) - (FLTWBD->translateOriginToCenterOfMassVector));
    
    m_renderingEngine->Initialize(surfaces);
    for (int i = 0; i < SurfaceCount; i++)
        delete surfaces[i];
}
void ApplicationEngine::Initialize(int width, int height)
{
    m_trackballRadius = width / 3;
    m_buttonSize.y = height / 10;
    m_buttonSize.x = 4 * m_buttonSize.y / 3;
    m_screenSize = ivec2(width, height - m_buttonSize.y);
    m_centerPoint = m_screenSize / 2;
    
    vector<ISurface*> surfaces(SurfaceCount);
    string path = m_resourceManager->GetResourcePath();
    surfaces[0] = new ObjSurface(path + "/micronapalmv2.obj");
    surfaces[1] = new ObjSurface(path + "/Ninja.obj");
    surfaces[2] = new Torus(1.4, 0.3);
    surfaces[3] = new TrefoilKnot(1.8f);
    surfaces[4] = new KleinBottle(0.2f);
    surfaces[5] = new MobiusStrip(1);
    m_renderingEngine->Initialize(surfaces);
    for (int i = 0; i < SurfaceCount; i++)
        delete surfaces[i];
}
void ApplicationEngine::Render() const
{
    vector<Visual> visuals(SurfaceCount);
    
    visuals[0].Color = vec3(255.0f, 1.0f, 1.0f);
    visuals[0].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[0].Orientation = m_orientation;
    visuals[0].RenderMode = GL_TRIANGLES;
    
    visuals[1].Color = vec3(0.0f, 0.0f, 128.0f);
    visuals[1].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[1].Orientation = m_orientation;
    visuals[1].RenderMode = GL_LINES; // must be the same as in Initialize
    
    visuals[2].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[2].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[2].Orientation = m_orientation;
    visuals[2].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    visuals[3].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[3].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[3].Orientation = m_orientation;
    visuals[3].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    visuals[4].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[4].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[4].Orientation = m_orientation;
    visuals[4].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    visuals[5].Color = vec3(0.0f, 128.0f, 0.0f);
    visuals[5].ViewportSize = ivec2(m_screenSize.x, m_screenSize.y);
    visuals[5].Orientation = m_orientation;
    visuals[5].RenderMode = GL_TRIANGLES; // must be the same as in Initialize
    
    
    m_renderingEngine->Render(visuals);
}
void ApplicationEngine::Render() const
{
    vector<Visual> visuals(SurfaceCount);
    
    if (!m_animation.Active) {
        PopulateVisuals(&visuals[0]);
    } else {
        float t = m_animation.Elapsed / m_animation.Duration;
        
        for (int i = 0; i < SurfaceCount; i++) {
            
            const Visual& start = m_animation.StartingVisuals[i];
            const Visual& end = m_animation.EndingVisuals[i];
            Visual& tweened = visuals[i];
            
            tweened.Color = start.Color.Lerp(t, end.Color);
            tweened.LowerLeft = start.LowerLeft.Lerp(t, end.LowerLeft);
            tweened.ViewportSize = start.ViewportSize.Lerp(t, end.ViewportSize);
            tweened.Orientation = start.Orientation.Slerp(t, end.Orientation);
        }
    }
    
    m_renderingEngine->Render(visuals);
}
void ApplicationEngine::UpdateAnimation(float dt)
{
    m_timestamp += dt;
    m_renderingEngine->UpdateAnimation(m_timestamp);
}
void ApplicationEngine::Render() const
{
    m_renderingEngine->Render();
}
void ApplicationEngine::Initialize(int width, int height)
{
    m_renderingEngine->Initialize();
}