#ifndef _vlacik2c_H
#define _vlacik2c_H


struct ElementA {
  GLenum type;
  int n;
  GLuint* ind;

  ElementA () {}

  ElementA (GLenum t, int nn, GLuint* indices) :
    type(t), n(nn), ind(indices) {}

  void Render () {
    glDrawElements(type, n, GL_UNSIGNED_INT, (void*)ind);
  }
};

class RenderableEntityA : public RenderableEntity {
  Vertex3DS* v;
  int numvertices;
  List<ElementA> elements;

  Material3DS* material;
  BoundingBox B;
public:
  RenderableEntityA () : v(0), numvertices(0), material(0) {}

  ~RenderableEntityA () {
    delete[] v;
    elements.rewind();
    for(int i=elements.size(); i; i--) {
      delete[] (*elements).ind;
      ++elements;
    }
  }

  void SetMaterial (Material3DS* m) {
    material = m;
  }
  void AddElement (GLenum type, int num, GLuint* indices) {
    elements.push_back(ElementA(type, num, indices));
  }
  void Vertices (int n, Vertex3DS* p) {
    numvertices = n;
    v = p;

    GLfloat mx, my, mz, Mx, My, Mz, a1, a2;
    mx = Mx = p->x;
    my = My = p->y;
    mz = Mz = p->z;
    Vertex3DS* p1 = p+1;

    for(int i=n-1; i; i--, p++, p1++)
    {
      a1 = p->x;
      a2 = p1->x;
      if(a1<=a2) {
        if(a1<mx) mx=a1;
        if(a2>Mx) Mx=a2;
      }
      else {
        if(a2<mx) mx=a2;
        if(a1>Mx) Mx=a1;
      }

      a1 = p->y;
      a2 = p1->y;
      if(a1<=a2) {
        if(a1<my) my=a1;
        if(a2>My) My=a2;
      }
      else {
        if(a2<my) my=a2;
        if(a1>My) My=a1;
      }

      a1 = p->z;
      a2 = p1->z;
      if(a1<=a2) {
        if(a1<mz) mz=a1;
        if(a2>Mz) Mz=a2;
      }
      else {
        if(a2<mz) mz=a2;
        if(a1>Mz) Mz=a1;
      }
    }
    B.Corner1(mx, my, mz);
    B.Corner2(Mx, My, Mz);
  }
  virtual void Render (double time=0.0)
  {
    if(!(B.IsVisible())) 
      return;
//    B.Render();

    glInterleavedArrays(GL_T4F_C4F_N3F_V4F, 0, (void*)v);

    glLockArraysEXT(0, numvertices);

    if(material) {
      material->GL();
      if(material->Transparency()==50) {
        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
        glDepthMask(GL_ZERO);
        glDisable(GL_CULL_FACE);
        glEnable(GL_BLEND);
      }
      else {
        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
        glDepthMask(GL_ONE);
        glEnable(GL_CULL_FACE);
        glDisable(GL_BLEND);
      }
      if(material->Texture1())
        glEnable(GL_TEXTURE_2D);
      else
        glDisable(GL_TEXTURE_2D);
    }

    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);

    elements.rewind();
    for(int i=elements.size(); i; i--) {
      (*elements).Render();
      ++elements;
    }

    glUnlockArraysEXT();
  
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
    glDisable(GL_CULL_FACE);
    glDisable(GL_BLEND);
    glDepthMask(GL_ONE);
  }


};

#endif