using System;

using System.Drawing;

using System.Collections;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using D3D = Microsoft.DirectX.Direct3D;


namespace MhsApplication
{
	////-----------------------------------------------------------------------------
	////           Name: shadow_volume.h
	////         Author: Mostly from a DX9 SDK sample
	////  Last Modified: 02/01/05
	////    Description: Simple class for grouping together as that's needed to 
	////                 create and use a shadow volume.
	////
	//// Note: The buildShadowVolume() method contains a data type called MeshVertex,
	////       which is basically hard-coded to work with my sample's teapot mesh.
	////       If you want to use another mesh instead of the teapot, you'll need to
	////       find out what the FVF layout is for its vertex type and substitute it
	////       there for MeshVertex.
	////-----------------------------------------------------------------------------

	/// <summary>
	/// Summary description for ShadowVolume.
	/// </summary>
	public class ShadowVolume
	{
		public ShadowVolume()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		public void reset() { vertices.Clear(); }

		public void MeshToShadow( Mesh mesh, Vector3 lightPosition )
		{

			//    MeshVertex *pVertices;
			//    WORD       *pIndices;

			CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[]) mesh.LockVertexBuffer(typeof(CustomVertex.PositionColored), LockFlags.None,1);
			GraphicsStream indices =  mesh.LockIndexBuffer(LockFlags.None);

			// Allocate a temporary edge list
			CustomVertex.PositionColored[] tmpEdges = new CustomVertex.PositionColored[mesh.NumberFaces*6];

			for( int i=0; i < mesh.NumberFaces; i++)
			{

				int faceVert0 = indices.ReadByte();
				int faceVert1 = indices.ReadByte();
				int faceVert2 = indices.ReadByte();


				Vector3 v0 = new Vector3( verts[faceVert0].X,verts[faceVert0].Y,verts[faceVert0].Z);
				Vector3 v1 = new Vector3( verts[faceVert1].X,verts[faceVert1].Y,verts[faceVert1].Z);
				Vector3 v2 = new Vector3( verts[faceVert2].X,verts[faceVert2].Y,verts[faceVert2].Z);

				Vector3 vCross1 = new Vector3(v2-v1);
				Vector3 vCross2 = new Vector3(v1-v0);
				Vector3 vNormal = Vector3.Cross(vCross1,vCross2);

				if( Vector3.Dot(vNormal, lightPosition) >= 0.0f )
				{
					AddEdge( pEdges, dwNumEdges, wFace0, wFace1 );
					AddEdge( pEdges, dwNumEdges, wFace1, wFace2 );
					AddEdge( pEdges, dwNumEdges, wFace2, wFace0 );
				}

			}

			//    for( i = 0; i < dwNumEdges; ++i )
			//    {
			//        D3DXVECTOR3 v1 = pVertices[pEdges[2*i+0]].p;
			//        D3DXVECTOR3 v2 = pVertices[pEdges[2*i+1]].p;
			//        D3DXVECTOR3 v3 = v1 - vLight*10;
			//        D3DXVECTOR3 v4 = v2 - vLight*10;
			//
			//        // Add a quad (two triangles) to the vertex list
			//        m_pVertices[m_dwNumVertices++] = v1;
			//        m_pVertices[m_dwNumVertices++] = v2;
			//        m_pVertices[m_dwNumVertices++] = v3;
			//
			//        m_pVertices[m_dwNumVertices++] = v2;
			//        m_pVertices[m_dwNumVertices++] = v4;
			//        m_pVertices[m_dwNumVertices++] = v3;
			//    }
			//
			//    // Delete the temporary edge list
			//    delete[] pEdges;
			//
			//    // Unlock the geometry buffers

			mesh.UnlockVertexBuffer();
			mesh.UnlockIndexBuffer();

		}

		public void Render( Device d3dDevice )
		{
			d3dDevice.VertexFormat = CustomVertex.PositionColored.Format;
			d3dDevice.SetStreamSource(0,BUFFER,0);
			d3dDevice.DrawPrimitives(PrimitiveType.TriangleList,0,vertices.Count/3);
		}

		////-----------------------------------------------------------------------------
		//// Name: addEdge()
		//// Desc: Adds an edge to a list of silohuette edges of a shadow volume.
		////-----------------------------------------------------------------------------
		//void ShadowVolume::addEdge( WORD* pEdges, DWORD& dwNumEdges, WORD v0, WORD v1 )
		//{
		//    // Remove interior edges (which appear in the list twice)
		//    for( DWORD i = 0; i < dwNumEdges; ++i )
		//    {
		//        if( ( pEdges[2*i+0] == v0 && pEdges[2*i+1] == v1 ) ||
		//            ( pEdges[2*i+0] == v1 && pEdges[2*i+1] == v0 ) )
		//        {
		//            if( dwNumEdges > 1 )
		//            {
		//                pEdges[2*i+0] = pEdges[2*(dwNumEdges-1)+0];
		//                pEdges[2*i+1] = pEdges[2*(dwNumEdges-1)+1];
		//            }
		//
		//            --dwNumEdges;
		//            return;
		//        }
		//    }
		//
		//    pEdges[2*dwNumEdges+0] = v0;
		//    pEdges[2*dwNumEdges+1] = v1;
		//    dwNumEdges++;
		//}		
		private  void AddEdge( ArrayList edges, int v0, int v1 )
		{
		}

		private ArrayList vertices = new ArrayList();

	}

}

