#ifndef __CPRIMIT_H__
#define __CPRIMIT_H__


#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

using namespace std;


class CPrimitives

{
   public:
     CPrimitives() {}
    ~CPrimitives() {}

    static IMesh* CreateCube()
      {
          SMesh* msh = new SMesh();
          SMeshBuffer* mb = new SMeshBuffer();
          msh->addMeshBuffer(mb);
          S3DVertex vtx[12];
          vtx[0]  = S3DVertex(-1,-1,-1, -1,-1,-1, SColor(255,255,255,255), 0, 1);
          vtx[1]  = S3DVertex( 1,-1,-1,  1,-1,-1, SColor(255,255,255,255), 1, 1);
          vtx[2]  = S3DVertex( 1, 1,-1,  1, 1,-1, SColor(255,255,255,255), 1, 0);
          vtx[3]  = S3DVertex(-1, 1,-1, -1, 1,-1, SColor(255,255,255,255), 0, 0);
          vtx[4]  = S3DVertex( 1,-1, 1,  1,-1, 1, SColor(255,255,255,255), 0, 1);
          vtx[5]  = S3DVertex( 1, 1, 1,  1, 1, 1, SColor(255,255,255,255), 0, 0);
          vtx[6]  = S3DVertex(-1, 1, 1, -1, 1, 1, SColor(255,255,255,255), 1, 0);
          vtx[7]  = S3DVertex(-1,-1, 1, -1,-1, 1, SColor(255,255,255,255), 1, 1);
          vtx[8]  = S3DVertex(-1, 1, 1, -1, 1, 1, SColor(255,255,255,255), 0, 1);
          vtx[9]  = S3DVertex(-1, 1,-1, -1, 1,-1, SColor(255,255,255,255), 1, 1);
          vtx[10] = S3DVertex( 1,-1, 1,  1,-1, 1, SColor(255,255,255,255), 1, 0);
          vtx[11] = S3DVertex( 1,-1,-1,  1,-1,-1, SColor(255,255,255,255), 0, 0);


          for(int i=0;i<12;i++)mb->Vertices.push_back(vtx[i]);
          u16 indices[36] = {   0,2,1,   0,3,2,   1,5,4,   1,2,5,
                                4,6,7,   4,5,6,   7,3,0,   7,6,3,
                                9,5,2,   9,8,5,   0,11,10, 0,10,7
                            };
          for(int i=0;i<36;i++)mb->Indices.push_back(indices[i]);
          return msh;
      }

   static IMesh* CreatePlane(int gridX=25, int gridY=25)
      {
          SMesh* msh = new SMesh();
          SMeshBuffer* mb = new SMeshBuffer();
          msh->addMeshBuffer(mb);
          int vertCnt = 0;
          for (int x = 0; x < gridX; x++)
              for (int y = 0; y < gridY; y++)
               {
                   f32 xx   = (0.5-(float)x/(gridX-1))*2;
                   f32 yy   = (0.5-(float)y/(gridY-1))*2;
                   f32 xcord = 1-(float)x/(gridX-1);
                   f32 ycord = (float)y/(gridY-1)-1;
                   mb->Vertices.push_back(S3DVertex(xx,yy,0, 0,0,0,SColor(255,255,255,255)

,xcord,ycord));

                   if (x < gridX - 1 && y < gridY - 1)
                    {
                       mb->Indices.push_back(vertCnt + 0);
                       mb->Indices.push_back(vertCnt + 1);
                       mb->Indices.push_back(vertCnt + 1 + gridY);
                       mb->Indices.push_back(vertCnt + 1 + gridY);
                       mb->Indices.push_back(vertCnt + gridY);
                       mb->Indices.push_back(vertCnt + 0);
                    }
                  vertCnt++;
               }
          return msh;
      }

    static IMesh* CreateCylinder(int gridX=25, int gridY=25,f32 ridus=1)
      {
          SMesh* msh = new SMesh();
          SMeshBuffer* mb = new SMeshBuffer();
          msh->addMeshBuffer(mb);
          f32 Tstp = 2*3.14/(float)(gridX-1);
          int vertCnt = 0;
          for (int x = 0; x < gridX; x++)
              for (int y = 0; y < gridY; y++)
               {
                   f32 yy   = (0.5-(float)y/(gridY-1))*2;
                   f32 xx   = sin((f32)x*Tstp)*ridus;
                   f32 zz   = cos((f32)x*Tstp)*ridus;
                   f32 xcord = 1-(float)x/(gridX-1);
                   f32 ycord = (float)y/(gridY-1)-1;
                   if (x < gridX-1)
                    {
                       mb->Vertices.push_back(S3DVertex(xx,yy,zz, 0,0,0,SColor(255,255,255

,255),xcord,ycord));

                    }
                   else
                    {
                       f32 yy   = (0.5-(float)y/(gridY-1))*2;
                       f32 xx   = sin(0.0)*ridus;
                       f32 zz   = cos(0.0)*ridus;
                       mb->Vertices.push_back(S3DVertex(xx,yy,zz, 0,0,0,SColor(255,255,255

,255),xcord,ycord));

                    }
                   if (x < gridX - 1 && y < gridY - 1)
                    {
                       mb->Indices.push_back(vertCnt + 0);
                       mb->Indices.push_back(vertCnt + 1);
                       mb->Indices.push_back(vertCnt + 1 + gridY);
                       mb->Indices.push_back(vertCnt + 1 + gridY);
                       mb->Indices.push_back(vertCnt + gridY);
                       mb->Indices.push_back(vertCnt + 0);
                    }
                  vertCnt++;
               }
          return msh;
      }

    static IMesh* CreateCone(int gridX=25, int gridY=25,f32 ridus=1)
      {
          SMesh* msh = new SMesh();
          SMeshBuffer* mb = new SMeshBuffer();
          msh->addMeshBuffer(mb);
          f32 vstp = ridus/(float)(gridY-1);
          f32 Tstp = 2*3.14/(float)(gridX-1);
          int vertCnt = 0;
          for (int x = 0; x < gridX; x++)
              for (int y = 0; y < gridY; y++)
               {
                   f32 yy   = (0.5-(float)y/(gridY-1))*2;
                   f32 xx   = sin((f32)x*Tstp)*((f32)y*vstp);
                   f32 zz   = cos((f32)x*Tstp)*((f32)y*vstp);
                   f32 xcord = 1-(float)x/(gridX-1);
                   f32 ycord = (float)y/(gridY-1)-1;
                   if (x < gridX-1)
                    {
                       mb->Vertices.push_back(S3DVertex(xx,yy,zz, 0,0,0,SColor(255,255,255,255),xcord,ycord));

                    }
                   else
                    {
                       f32 yy   = (0.5-(float)y/(gridY-1))*2;
                       f32 xx   = sin((f32)x*Tstp)*((f32)y*vstp);
                       f32 zz   = cos((f32)x*Tstp)*((f32)y*vstp);
                       mb->Vertices.push_back(S3DVertex(xx,yy,zz, 0,0,0,SColor(255,255,255,255),xcord,ycord));

                    }
                   if (x < gridX - 1 && y < gridY - 1)
                    {
                       mb->Indices.push_back(vertCnt + 0);
                       mb->Indices.push_back(vertCnt + 1);
                       mb->Indices.push_back(vertCnt + 1 + gridY);
                       mb->Indices.push_back(vertCnt + 1 + gridY);
                       mb->Indices.push_back(vertCnt + gridY);
                       mb->Indices.push_back(vertCnt + 0);
                    }
                  vertCnt++;
               }
          return msh;
      }

/* already in Irrlicht
   virtual IMesh* CreateSphere()
      {
          SMesh* msh = new SMesh();
          SMeshBuffer* mb = new SMeshBuffer();
          msh->addMeshBuffer(mb);

          // creating Sphere stuff here

          return msh;
      }
*/
    // From : Panther in Irrlicht-Forum.
    // Link : http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=15106&start=0&postdays=0&postorder=asc&highlight=
    static IMesh* CreateDiamond()
    {
        u16 indices[] =  //These are the faces of the diamond
        {   2,0,1,
             5,2,1,
             5,1,4,
             5,4,3,
             1,0,6,
             0,2,8,
             8,6,0,
             11,8,2,
             2,5,11,
             11,5,3,
             3,9,11,
             9,3,4,
             4,10,9,
             10,4,1,
             1,7,10,
             6,7,1,
             8,11,12,
             12,11,9,
             12,9,10,
             12,10,7,
             12,7,6,
             6,8,12
        };

        SMesh* msh = new SMesh();
        SMeshBuffer* mb = new SMeshBuffer();
        msh->addMeshBuffer(mb);

        mb->Vertices.push_back(S3DVertex(-8,3,0, 0,1,0, video::SColor(192,192,192,192), 0, 1));
        mb->Vertices.push_back(S3DVertex(-5,3,8, 0,1,0, video::SColor(192,192,192,192), 1, 0));
        mb->Vertices.push_back(S3DVertex(-5,3,-8, 0,1,0, video::SColor(192,192,192,192), 1, 1));
        mb->Vertices.push_back(S3DVertex(8,3,0, 0,1,0, video::SColor(192,192,192,192), 0, 0));
        mb->Vertices.push_back(S3DVertex(5,3,8, 0,1,0, video::SColor(192,192,192,192), 0, 1));
        mb->Vertices.push_back(S3DVertex(5,3,-8, 0,1,0, video::SColor(192,192,192,192), 1, 1));
        mb->Vertices.push_back(S3DVertex(-11,0,0, -1,1,0, video::SColor(192,192,192,192), 1, 0));
        mb->Vertices.push_back(S3DVertex(-8,0,11, -1,1,1, video::SColor(192,192,192,192), 0, 0));
        mb->Vertices.push_back(S3DVertex(-8,0,-11, -1,1,-1, video::SColor(192,192,192,192), 0, 1));
        mb->Vertices.push_back(S3DVertex(11,0,0, 1,1,0, video::SColor(192,192,192,192), 1, 0));
        mb->Vertices.push_back(S3DVertex(8,0,11, 1,1,1, video::SColor(192,192,192,192), 1, 1));
        mb->Vertices.push_back(S3DVertex(8,0,-11, 1,1,-1, video::SColor(192,192,192,192), 0, 0));
        mb->Vertices.push_back(S3DVertex(0,-15,0,0,-1,0, video::SColor(192,192,192,192), 0, 1));

        for(int ii=0; ii <66; ii++)
        {
        mb->Indices.push_back(indices[ii]);
        }
        return msh;
    };



};
#endif
