//
// map.cc for graviball in
//
// Made by razik yousfi
// Login   <yousfi_r@epita.fr>
//
// Started on  Sun Nov 19 14:27:05 2006 razik yousfi
// Last update Tue Nov 21 01:30:21 2006 
//

#include <iostream>
#include "map.hh"

Map::Map ()
{
  surface_init (&surface_);
}

Map::~Map ()
{
  surface_stop (&surface_);
}

void
Map::init ()
{
  GLuint texture;

  for (std::vector<struct s_face>::iterator i = map_.faces.begin ();
       i != map_.faces.end (); ++i)
    for (std::vector<std::string>::iterator j = (*i).textures.begin ();
         j != (*i).textures.end (); ++j)
    {
      if (surface_load (&surface_, (*j).c_str (), &texture))
      {
      	std::cerr << "Could not load " << (*j).c_str () << "." << std::endl;
      	continue;
      }
      (*i).texturesid.push_back (texture);
    }
}

void
Map::render ()
{
  GLuint        textureId;

  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable (GL_BLEND);
  glEnable (GL_TEXTURE_2D);
  glPushMatrix ();
  for (int i = 0; i < map_.world.numFaces; ++i)
  {
    struct s_face&  face = map_.faces[map_.world.faces[i]];

    for (std::vector<struct s_shader>::iterator j = face.shaders.begin ();
	 j != face.shaders.end (); ++j)
      (*j).shader (face, (*j));

    glBindTexture (GL_TEXTURE_2D, face.texturesid[0]);
    glBegin (GL_POLYGON);
    glColor4f (face.color[0], face.color[1], face.color[2], face.color[3]);
    for (int j = 0; j < (int)face.vertices.size (); ++j)
    {
      glTexCoord2f (face.curTexcoords[j].u, face.curTexcoords[j].v);
      glVertex3f (face.curVertices[j].x, face.curVertices[j].y,
		  face.curVertices[j].z);
    }
    glEnd ();
  }

  for (std::vector<struct s_block_group>::iterator i =
         map_.blockGroups.begin (); i != map_.blockGroups.end (); ++i)
  {
    struct s_block_group&	group = (*i);

    for (std::vector<struct s_block>::iterator j = group.blocks.begin ();
         j != group.blocks.end (); ++j)
    {
      struct s_block&   block = (*j);

      if (!block.alive)
        continue;

      for (std::vector<struct s_move>::iterator m = group.moves.begin ();
           m != group.moves.end (); ++m)
        (*m).move (block, (*m));

      for (int f = 0; f < group.numFaces; ++f)
      {
        struct s_face&	face = map_.faces[group.faces[f]];

        for (std::vector<struct s_shader>::iterator s = face.shaders.begin ();
             s != face.shaders.end (); ++s)
          (*s).shader (face, (*s));

        textureId = group.lives > 0 ? block.hits : 0;
        glBindTexture (GL_TEXTURE_2D, face.texturesid[textureId]);
        glBegin (GL_POLYGON);
        glColor4f (face.color[0], face.color[1], face.color[2], face.color[3]);
        for (int j = 0; j < (int)face.vertices.size (); ++j)
        {
          glTexCoord2f (face.curTexcoords[j].u, face.curTexcoords[j].v);
          glVertex3f (face.curVertices[j].x + block.curOrigin.x,
                      face.curVertices[j].y + block.curOrigin.y,
                      face.curVertices[j].z + block.curOrigin.z);
        }
        glEnd ();
      }
    }
  }

  glPopMatrix ();
  glDisable (GL_TEXTURE_2D);
}

struct s_map&
Map::getMap ()
{
  return map_;
}
