#include "SM_CommonFXPCH.h"
#include "SM_Engine3DPCH.h"
#include "SM_Spline.h"


/*
    RenderContext RC;   

    RC.GetViewport()->Set(
    Vector3D(0.0f, 0.0f, 0.0f),
    Quaternion(1.0f, 0.0f, 0.0f, 0.0f),
    0, 0, 640, 480,
    90,
    0.75f,
    1.0f,
    200.0f);
  
    RC.SyncRasterizer();
    RC.UpdateFrustum();

    D3DVIEWPORT8 Viewport;
    Viewport.X      =0;
    Viewport.Y      =0;
    Viewport.Width  =640;
    Viewport.Height =480;
    Viewport.MinZ   =0.0f;
    Viewport.MaxZ   =1.0f;

    SM_D3d::Device()->SetViewport(&Viewport);  

    MeshElement me;

    FVF_PosNormalDiffuseTex1 pVertices[3];
    unsigned short pusIndices[3]={0,2,1};

    pVertices[0].x=0.0f; pVertices[0].y=0.0f; pVertices[0].z=10.0f; 
    pVertices[0].nx=0.0f; pVertices[0].ny=0.0f; pVertices[0].nz=1.0f;
    pVertices[0].u=0.0f; pVertices[0].v=0.0f; pVertices[0].diffuse=0xFFFFFFFF;

    pVertices[1].x=0.0f; pVertices[1].y=10.0f; pVertices[1].z=10.0f; 
    pVertices[1].nx=0.0f; pVertices[1].ny=0.0f; pVertices[1].nz=1.0f;
    pVertices[1].u=0.0f; pVertices[1].v=0.0f; pVertices[1].diffuse=0xFFFFFFFF;

    pVertices[2].x=10.0f; pVertices[2].y=10.0f; pVertices[2].z=10.0f; 
    pVertices[2].nx=1.0f; pVertices[2].ny=0.0f; pVertices[2].nz=0.0f;
    pVertices[2].u=0.0f; pVertices[2].v=0.0f; pVertices[2].diffuse=0xFFFFFFFF;
    
    me.m_iShader            =m_iShader;
    me.m_iVB                =-1;
    me.m_iIB                =-1;
    me.m_pVertices          =pVertices; 
    me.m_pIndices           =pusIndices;
    me.m_uStartVertex       =0;
    me.m_uVertices          =3;
    me.m_uStartIndex        =0;
    me.m_uPrimitives        =1;
    me.m_WorldTransform     =Matrix4X4::Identity;
    me.m_uActiveLightMask   =-1;  
    me.m_fDepth             =0.0f;

    RenderPipeline::Render(&me);
    RenderPipeline::Flush();
    */



class TunelFX : public SM_DemoEffect
{
public:              
  TunelFX(char const* pcName) : SM_DemoEffect(pcName)
  {
  }

  virtual          ~TunelFX()
  {
  }

  int      Init(const char* pcCommand)
  {
    Vector3D v3d[]=
    {
      Vector3D(0.05f, 0.0f, 0.0f),      
      Vector3D(0.10f, 0.0f, 20.0f),
      Vector3D(0.0f, 0.00f, 30.0f),

      Vector3D(2.15f, 8.0f, 40.01f),      
      Vector3D(0.20f, 1.00f, 50.0f),
      Vector3D(-3.30f, 2.00f, 60.0f),

      Vector3D(5.40f, 4.00f, 70.0f),      
      Vector3D(0.50f, 3.00f, 80.0f),
      Vector3D(3.6f, -5.00f, 90.0f),
      
      Vector3D(-6.7f, 5.00f, 100.0f),      
      Vector3D(0.8f, 2.00f, 110.0f),
      Vector3D(0.9f, 3.00f, 120.0f),

      Vector3D(3.0f, -6.00f, 170.0f),
    };

    float          fTimes[]=
    {
      0.0f, 
      1.0f,
      2.0f,
      3.0f,
      4.0f,
      5.0f,
      6.0f,
      7.0f,
      8.0f,
      9.0f,
      10.0f,
      11.0f,
    };

    m_Trajectory.Init(12, v3d, fTimes);

    return (0);
  }

  int      Shutdown()
  {
    return (0);
  }

  int      Reset()
  {
    return (0);
  }

  int      Start(float fTime)
  {
    m_iShader=ShaderManager::LoadShader("DEFORMA");
    return (0);
  }

  int      Stop()
  {
    return (0);
  }

  int      Run(float fTime)
  {
    RenderContext RC;   


    
    
    MeshElement me;

    

    unsigned k;
    

    for (k=0 ; k<1 ; k++)
    {
      Vector3D Position;
      Vector3D Tangent;
      Vector3D Normal;
      Vector3D Binormal;

      m_Trajectory.GetFrame(fmodf(fTime,12.0f), &Position, &Tangent, &Normal, &Binormal);
      GetFrame(Tangent, Normal, Binormal);

      Quaternion q;
      q.FromFrame(Tangent, Normal, Binormal);

      RC.Set(
      Position,
      q,
      //Quaternion::IDENTITY,
      110,
      0.75f,
      0.01f,
      200.0f);

      RC.SetViewport(0, 0, 640, 480);
      RC.SyncRasterizer();
      RC.UpdateFrustum();

  
      const unsigned uSegments=140;
      const unsigned uRadiusSegments=40;
      unsigned i,j;

      FVF_PosNormalDiffuseTex1 pVertices [uSegments*uRadiusSegments];
      unsigned short           pusIndices[uSegments*uRadiusSegments*6]={0,2,1};

      int iVertex=0;      
      for (j=0 ; j<uSegments ; j++)
      {        
        m_Trajectory.GetFrame(1.00f+float(j)*12.0f/float(uSegments-1), &Position, &Tangent, &Normal, &Binormal);

        GetFrame(Tangent, Normal, Binormal);


        
        for (i=0 ; i<uRadiusSegments ; i++)
        {
          float fOffset=2.0f*3.1416f*float(i)/float(uRadiusSegments-1);

          Vector3D Vertex=Position+Normal*sinf(fOffset)*1.0f+Binormal*cosf(fOffset)*1.0f;
          //Vector3D Vertex=Position+Vector3D(1.0f, 0.0f, 0.0f)*sinf(fOffset)*2.0f+Vector3D(0.0f, 1.0f, 0.0f)*cosf(fOffset)*2.0f;
          pVertices[iVertex].x = Vertex.x; 
          pVertices[iVertex].y = Vertex.y; 
          pVertices[iVertex].z=  Vertex.z; 
          pVertices[iVertex].nx=0.0f ; pVertices[iVertex].ny=0.0f ; pVertices[iVertex].nz=1.0f;
          pVertices[iVertex].u =float(i)/float(uRadiusSegments) ; pVertices[iVertex].v =j/8.0f ; pVertices[iVertex].diffuse=0xFFFFFFFF;
        
          iVertex++;
        }
      }

      int iIndex=0;
      int iGap  =uRadiusSegments;
      for (j=0 ; j<uSegments-1 ; j++)
      {
        int iStart=j*uRadiusSegments;
        for (i=0 ; i<uRadiusSegments-1 ; i++)
        {
          pusIndices[iIndex  ] = iStart+i+1;
          pusIndices[iIndex+1] = iStart+i+0;
          pusIndices[iIndex+2] = iStart+i+iGap;
          pusIndices[iIndex+3] = iStart+i+1;
          pusIndices[iIndex+4] = iStart+i+iGap;
          pusIndices[iIndex+5] = iStart+i+iGap+1;
          iIndex+=6;
        }                      
      }
       
      me.m_iShader            =m_iShader;
      me.m_iVB                =-1;
      me.m_iIB                =-1;
      me.m_pVertices          =pVertices; 
      me.m_pIndices           =pusIndices;
      me.m_uStartVertex       =0;
      me.m_uVertices          =uSegments*uRadiusSegments;
      me.m_uStartIndex        =0;
      me.m_uPrimitives        =(uRadiusSegments)*2*uSegments;
      me.m_WorldTransform     =Matrix4X4::Identity;
      me.m_iActiveLightMask   =-1;  
      me.m_fDepth             =0.0f;

      SM_D3d::SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
      SM_D3d::SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
      SM_D3d::SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
      SM_D3d::SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);  
      SM_D3d::SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);

  
      RenderPipeline::Render(&me);
      RenderPipeline::Flush();

      fTime+=0.03f;
    }
    
    

    return (1);
  }

  int      Command           (float fTime, const char* pcCommand)
  {
    SM_DemoEffect::Command(fTime, pcCommand);
    return (0);
  }  

  int       m_iShader;
  Spline    m_Trajectory;

};

DEFINE_EFFECT(TunelFX)
TunelFX Tunel("TUNEL");