#include "SM_CommonFXPCH.h"
#include "SM_Engine3DPCH.h"
#include "MgcNaturalSpline3.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 EnredaderaFX : public SM_DemoEffect
{
public:              
  EnredaderaFX(char const* pcName) : SM_DemoEffect(pcName)
  {
  }

  virtual          ~EnredaderaFX()
  {
  }

  int      Init(const char* pcCommand)
  {
    return (0);
  }

  int      Shutdown()
  {
    return (0);
  }

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

  int      Stop()
  {
    return (0);
  }

  int      Reset()
  {
    return (0);
  }

  void RenderElement(Spline* pSpline, float fTime)
  {
    
    
    #define SEGMENTS 128
    FVF_PosNormalDiffuseTex1 pVertices[SEGMENTS*2];
    unsigned short pusIndices[(SEGMENTS-1)*6]={0,2,1};

    int i;

    #define DELTA 2.0f*3.1416f/float(120)


    
    Vector3D Position;
    Vector3D Tangent;
    Vector3D Normal;
    Vector3D Binormal;

    
    /*
    Position=Vector3D(0.0f, 0.0f, 2.0f);
    Tangent =Vector3D(0.0f, 0.0f, 1.0f);
    Normal  =Vector3D(1.0f, 0.0f, 0.0f);
    Binormal=Vector3D(0.0f, 1.0f, 0.0f);
    */


    float fOffset=0.0f;

    int j;
    #define TIRAS 32
    for (j=0 ; j<TIRAS ; j++)
    {
      Vector3D Vertex;
      for (i=0 ; i<SEGMENTS*2 ; i+=2)
      {         
        pSpline->GetFrame(fmodf(fTime*0.5f+0.01f*i,12.0f), &Position, &Tangent, &Normal, &Binormal);
        GetFrame(Tangent, Normal, Binormal);

          Vector3D v3dOffset=1.25f*(Normal*sinf(fOffset)+Binormal*cosf(fOffset));

          Vector3D v3dFinal, v3dNormal;
          v3dFinal          =Position+v3dOffset-Tangent*0.02f;
          v3dNormal         =(v3dFinal-Position).Normalize();
          pVertices[i].x = v3dFinal.x; 
          pVertices[i].y = v3dFinal.y; 
          pVertices[i].z=  v3dFinal.z; 
          pVertices[i].nx= v3dNormal.x; pVertices[i].ny=v3dNormal.y; pVertices[i].nz=v3dNormal.z;
          pVertices[i].u =0.0f ; pVertices[i].v =0.0f ; pVertices[i].diffuse=0xFFFFFFFF;                          

          v3dFinal          =Position+v3dOffset+Tangent*0.02f;
          v3dNormal         =(v3dFinal-Position).Normalize();

          pVertices[i+1].x = v3dFinal.x; 
          pVertices[i+1].y = v3dFinal.y; 
          pVertices[i+1].z=  v3dFinal.z; 
          pVertices[i+1].nx= v3dNormal.x; pVertices[i+1].ny=v3dNormal.y; pVertices[i+1].nz=v3dNormal.z;
          pVertices[i+1].u =0.0f ; pVertices[i+1].v =0.0f ; pVertices[i+1].diffuse=0xFFFFFFFF;                          

          fOffset+=DELTA;
      }    

      for (i=0 ; i<SEGMENTS-1 ; i++)
      {         
        pusIndices[i*6  ] = i*2;
        pusIndices[i*6+1] = i*2+1;
        pusIndices[i*6+2] = i*2+2;
        pusIndices[i*6+3] = i*2+2;
        pusIndices[i*6+4] = i*2+1;
        pusIndices[i*6+5] = i*2+3;          
      }

      MeshElement me;

      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          =SEGMENTS*2;
      me.m_uStartIndex        =0;
      me.m_uPrimitives        =(SEGMENTS-1)*2;
      me.m_WorldTransform     =Matrix4X4::Identity;
      me.m_iActiveLightMask   =-1;  
      me.m_fDepth             =0.0f;

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

      fOffset+=2.0f*3.1416f/TIRAS;
    }
  }

  int      Run(float fTime)
  {
    RenderContext RC;   

    RC.Set(
    Vector3D(0.0f, 0.0f, 0.0f),
    Quaternion(1.0f, 0.0f, 0.0f, 0.0f),
    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);  


    Vector3D v3d[]=
    {
      Vector3D(0.05f, 0.0f, 5.0f),      
      Vector3D(0.10f, 0.0f, 3.0f),
      Vector3D(0.0f, 0.040f, 5.0f),

      Vector3D(-2.15f, 1.0f, 5.01f),      
      Vector3D(0.20f, 1.040f, 2.0f),
      Vector3D(-0.30f, 4.00f, 1.0f),

      Vector3D(3.40f, 1.00f, 5.0f),      
      Vector3D(0.50f, 4.040f, 8.0f),
      Vector3D(1.6f, -1.00f, 3.0f),
      
      Vector3D(-1.7f, 1.00f, 5.0f),      
      Vector3D(0.8f, 3.00f, 5.0f),
      Vector3D(2.9f, 1.040f, 6.0f),

      Vector3D(1.0f, -1.00f, 7.0f),

      Vector3D(0.25f, 1.0f, 5.0f),      
      Vector3D(0.10f, 2.0f, 13.0f),
      Vector3D(0.0f, 0.040f, 5.0f),

      Vector3D(-2.15f, 1.0f, 15.01f),      
      Vector3D(0.20f, 4.040f, 2.0f),
      Vector3D(-0.30f, 4.00f, 1.0f),

      Vector3D(3.40f, 3.00f, 5.0f),      
      Vector3D(0.50f, 4.040f, 8.0f),
      Vector3D(1.6f, -1.00f, 3.0f),
      
      Vector3D(-1.7f, 1.00f, 5.0f),      
      Vector3D(0.8f, 2.00f, 5.0f),
      Vector3D(2.9f, 1.040f, 6.0f),

      Vector3D(1.0f, -1.30f, 7.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,
      12.0f, 
      13.0f,
      14.0f,
      15.0f,
      16.0f,
      17.0f,
      18.0f,
      19.0f,
      20.0f,
      21.0f,
      22.0f,
      23.0f,
      24.0f,
    };

    Spline m_Trajectory;
    m_Trajectory.Init(16
      , v3d, fTimes);

    D3DLIGHT8 Light;
    //Light
    
    Light.Type    =D3DLIGHT_POINT;
    Light.Diffuse.a =Light.Diffuse.r=Light.Diffuse.g=Light.Diffuse.b=0.5f;    
    Light.Specular.a =Light.Specular.r=Light.Specular.g=Light.Specular.b=1.0f;
    Light.Diffuse.a =Light.Ambient.r=Light.Ambient.g=Light.Ambient.b=1.0f;
    Light.Position.x=Light.Position.y=Light.Position.z=0.0f;
    Light.Direction;
    Light.Range   =100.0f;
    Light.Falloff =100.0;
    Light.Attenuation0=1.0f;
    Light.Attenuation1=0.0f;
    Light.Attenuation2=0.0f;
    Light.Theta=0.0f;
    Light.Phi=0.0f;

    
    SM_D3d::SetRenderState(D3DRS_LIGHTING, TRUE);
  
    SM_D3d::Device()->SetLight(0, &Light);
    SM_D3d::Device()->LightEnable(0, TRUE);    

    RenderElement(&m_Trajectory, fmodf(fTime,24));

    SM_D3d::SetRenderState(D3DRS_LIGHTING, FALSE);
       

    return (1);
  }

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

  int m_iShader;
};

DEFINE_EFFECT(EnredaderaFX)
EnredaderaFX Enredadera("ENREDADERA");

