// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2004.  All Rights Reserved
//
// The Wild Magic Library (WM3) source code is supplied under the terms of
// the license agreement http://www.wild-magic.com/License/WildMagic3.pdf and
// may not be copied or disclosed except in accordance with the terms of that
// agreement.

#include "Section3p4p3a.h"

WM3_WINDOW_APPLICATION(Section3p4p3a);

//----------------------------------------------------------------------------
Section3p4p3a::Section3p4p3a ()
    :
    WindowApplication3("Section3p4p3a",0,0,640,480,ColorRGB::WHITE)
{
}
//----------------------------------------------------------------------------
bool Section3p4p3a::OnInitialize ()
{
    if ( !WindowApplication3::OnInitialize() )
        return false;

    // camera and view frustum
    m_spkCamera->SetFrustum(-0.055f,0.055f,-0.04125f,0.04125f,0.1f,1000.0f);
    Vector3f kCLoc(0.0f,0.0f,0.67f);
    Vector3f kCDir(0.0f,0.0f,-1.0f);
    Vector3f kCUp(0.0f,1.0f,0.0f);
    Vector3f kCRight = kCDir.Cross(kCUp);
    m_spkCamera->SetFrame(kCLoc,kCDir,kCUp,kCRight);

    m_spkScene = new Node(1);

    // single quadrilateral
    float fXMin = -1.0f;
    float fXMax = 1.0f;
    float fYMin = -1.0f;
    float fYMax = 1.0f;
    Vector3f* akVertex = new Vector3f[4];
    akVertex[0] = Vector3f(fXMin,fYMin,0.0f);
    akVertex[1] = Vector3f(fXMax,fYMin,0.0f);
    akVertex[2] = Vector3f(fXMax,fYMax,0.0f);
    akVertex[3] = Vector3f(fXMin,fYMax,0.0f);
    Vector3fArray* pkVertices = new Vector3fArray(5,akVertex);

    Vector2f* akUV = new Vector2f[4];
    akUV[0] = Vector2f(0.0f,0.0f);
    akUV[1] = Vector2f(8.0f,0.0f);
    akUV[2] = Vector2f(8.0f,8.0f);
    akUV[3] = Vector2f(0.0f,8.0f);
    Vector2fArray* pkUVs = new Vector2fArray(4,akUV);

    int* aiIndex = new int[6];
    aiIndex[0] = 0;  aiIndex[1] = 1;  aiIndex[2] = 2;
    aiIndex[3] = 0;  aiIndex[4] = 2;  aiIndex[5] = 3;
    IntArray* pkIndices = new IntArray(6,aiIndex);

    m_spkMesh = new TriMesh(pkVertices,pkIndices,false);
    m_spkMesh->Local.SetRotate(Matrix3f().FromAxisAngle(
        Vector3f::UNIT_X,-0.5f*Mathf::HALF_PI));
    m_spkScene->AttachChild(m_spkMesh);

    m_spkTexture = new Texture(Image::Load("Checkerboard.wmif"));
    m_spkEffect = new TextureEffect(m_spkTexture,pkUVs);
    m_spkMesh->SetEffect(m_spkEffect);

    // nearest neighbor
    m_spkTexture->Filter = Texture::FM_NEAREST;
    m_spkTexture->Mipmap = Texture::MM_NEAREST;
    m_spkTexture->CoordU = Texture::WM_REPEAT;
    m_spkTexture->CoordV = Texture::WM_REPEAT;

    m_spkScene->UpdateGS();
    m_spkScene->UpdateRS();

    InitializeCameraMotion(0.001f,0.001f);
    InitializeObjectMotion(m_spkScene);
    return true;
}
//----------------------------------------------------------------------------
void Section3p4p3a::OnTerminate ()
{
    m_spkScene = 0;
    m_spkMesh = 0;
    m_spkEffect = 0;
    m_spkTexture = 0;
    WindowApplication3::OnTerminate();
}
//----------------------------------------------------------------------------
void Section3p4p3a::OnIdle ()
{
    MoveCamera();
    if ( MoveObject() )
        m_spkScene->UpdateGS();

    m_pkRenderer->ClearBuffers();
    if ( m_pkRenderer->BeginScene() )
    {
        m_pkRenderer->DrawScene(m_spkScene);
        m_pkRenderer->EndScene();
    }
    m_pkRenderer->DisplayBackBuffer();
}
//----------------------------------------------------------------------------
bool Section3p4p3a::OnKeyDown (unsigned char ucKey, int iX, int iY)
{
    if ( WindowApplication3::OnKeyDown(ucKey,iX,iY) )
        return true;

    switch ( ucKey )
    {
    case 'n':  // filter nearest
        m_pkRenderer->ReleaseTexture(m_spkTexture);
        m_spkTexture->Filter = Texture::FM_NEAREST;
        m_spkTexture->Mipmap = Texture::MM_NEAREST;
        return true;
    case 'b':  // filter linear
        m_pkRenderer->ReleaseTexture(m_spkTexture);
        m_spkTexture->Filter = Texture::FM_LINEAR;
        m_spkTexture->Mipmap = Texture::MM_NEAREST;
        return true;
    case 'm': // filter linear, mipmap linear
        m_pkRenderer->ReleaseTexture(m_spkTexture);
        m_spkTexture->Filter = Texture::FM_LINEAR;
        m_spkTexture->Mipmap = Texture::MM_LINEAR;
        return true;
    case 't': // filter linear, mipmap trilinear
        m_pkRenderer->ReleaseTexture(m_spkTexture);
        m_spkTexture->Filter = Texture::FM_LINEAR;
        m_spkTexture->Mipmap = Texture::MM_LINEAR_LINEAR;
        return true;
    }

    return false;
}
//----------------------------------------------------------------------------
