//  Gl_Texture_Image.h - an interface to OpenGL texture objects.
//
//	Vamos Automotive Simulator
//  Copyright (C) 2003 Sam Varner
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include <vamos/geometry/Gl_Texture_Image.h>

#include <iostream>
#include <cassert>

// Windows puts OpenGL 1.2 and 1.3 stuff in glext.h.
#if HAVE_GL_GLEXT_H
# include <GL/glext.h>
#endif

Vamos_Geometry::
Gl_Texture_Image::Gl_Texture_Image (std::string file_name,
									bool smooth, bool mip_map,
									double width, double height) :
  Texture_Image (file_name, width, height),
  m_texture_name ()
{
/*glGenTextures (1, &m_texture_name);
  glBindTexture (GL_TEXTURE_2D, m_texture_name);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  GLint format = 0;
  switch (channels ())
	{
	case 1:
	  format = GL_LUMINANCE;
	  break;
	case 3:
	  format = GL_RGB;
	  break;
	case 4:
	  format = GL_RGBA;
	  break;
	default:
	  assert (false);
	}

  if (mip_map)
	{
	  if (smooth)
		{
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
						   GL_LINEAR_MIPMAP_LINEAR);
		}
	  else
		{
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
						   GL_NEAREST_MIPMAP_NEAREST);
		}
	  gluBuild2DMipmaps (GL_TEXTURE_2D, format, 
						 width_pixels (), height_pixels (),
						 format, GL_UNSIGNED_BYTE, 
						 data ());
	}
  else
	{
	  if (smooth)
		{
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		}
	  else
		{
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		}

	  glTexImage2D (GL_TEXTURE_2D, 0, format, 
					width_pixels (), height_pixels (),
					0, format, GL_UNSIGNED_BYTE, 
					data ());
	}*/
	m_texture_name.Load((string)file_name, true, m_width_pixels, m_height_pixels );
//    cout << m_width_pixels << endl;
}

Vamos_Geometry::
Gl_Texture_Image::Gl_Texture_Image (const Gl_Texture_Image& image) :
  Texture_Image (image),
  m_texture_name (image.m_texture_name)
{
}

const Vamos_Geometry::Gl_Texture_Image& Vamos_Geometry::
Gl_Texture_Image::operator = (const Gl_Texture_Image& image)
{
  if (&image != this)
	{
	  Texture_Image::operator = (image);
	  m_texture_name = image.m_texture_name;
	}
  return *this;
}

void Vamos_Geometry::
Gl_Texture_Image::activate ()
{
  //assert (glIsTexture (m_texture_name) == GL_TRUE);
  //glBindTexture (GL_TEXTURE_2D, m_texture_name);
	m_texture_name.Activate();
}

// Set texture the texture wrap parameter to GL_CLAMP_TO_EDGE.
// GL_REPEAT is the default.
void Vamos_Geometry::
Gl_Texture_Image::clamp_to_edge ()
{
  activate ();
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

// Draw the image to the stencil buffer.
void Vamos_Geometry::
Gl_Texture_Image::draw_stencil ()
{
//  glDrawPixels (width_pixels (), height_pixels (), GL_STENCIL_INDEX,
//				GL_UNSIGNED_BYTE, data ());
}

using namespace Vamos_Geometry;

//* Class Facade
Facade::Facade (std::string image_name, bool draw_back) 
  : Gl_Texture_Image (image_name, true, true, 1.0, 1.0),
    m_draw_back (draw_back),
    m_x_offset (0.0),
    m_y_offset (0.0),
    m_z_offset (0.0)
{
}

void
Facade::set_radius (double radius)
{
  set_width (2.0 * radius * aspect_ratio ());
	//set_width (2.0 * radius * aspect_ratio());
  set_height (2.0 * radius);
  m_x_offset = -width () / 2.0;
  m_y_offset = -height () / 2.0;
}

void
Facade::draw ()
{
  activate ();
  glColor3d (1.0, 1.0, 1.0);
  glEnable (GL_CULL_FACE);
  glBegin (GL_QUADS);
  glNormal3f (0.0, 0.0, 1.0);
  glTexCoord2d (0.0, 1.0);
  glVertex3d (m_x_offset, m_y_offset, m_z_offset);
  glTexCoord2d (1.0, 1.0);
  glVertex3d (m_x_offset + width (), m_y_offset, m_z_offset);
  glTexCoord2d (1.0, 0.0);
  glVertex3d (m_x_offset + width (), m_y_offset + height (), m_z_offset);
  glTexCoord2d (0.0, 0.0);
  glVertex3d (m_x_offset, m_y_offset + height (), m_z_offset);

  if (m_draw_back)
    {
      glNormal3f (0.0, 0.0, -1.0);
      glVertex3d (m_x_offset, m_y_offset, m_z_offset);
      glVertex3d (m_x_offset, m_y_offset + height (), m_z_offset);
      glVertex3d (m_x_offset + width (), m_y_offset + height (), m_z_offset);
      glVertex3d (m_x_offset + width (), m_y_offset, m_z_offset);
    }
  glEnd ();
  glDisable (GL_CULL_FACE);
}
