//	Vamos Automotive Simulator
//  Copyright (C) 2001--2002 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/Material.h>
#include <vamos/geometry/Conversions.h>
#include <vamos/geometry/Constants.h>

#include <cassert>

Vamos_Geometry::Material::
Material (Material_Type type, double friction, double restitution,
		  double rolling, double drag, 
		  double bump_amplitude, double bump_wavelength, 
		  Gl_Texture_Image* image)
  : m_type (type),
	m_friction_factor (friction),
	m_restitution_factor (restitution),
	m_rolling_resistance_factor (rolling),
	m_drag_factor (drag),
	m_bump_amplitude (bump_amplitude),
	m_bump_wavelength (bump_wavelength),
	mp_texture_image (image)
{
}

Vamos_Geometry::Material::
Material () :
  m_type (UNKNOWN),
  m_friction_factor (1.0),
  m_restitution_factor (1.0),
  m_rolling_resistance_factor (1.0),
  m_drag_factor (0.0),
  m_bump_amplitude (0.0),
  m_bump_wavelength (0.0),
  mp_texture_image (0)
{
}

Vamos_Geometry::Material::
Material (const Material& material)
{
  m_type = material.m_type;
  m_friction_factor = material.m_friction_factor;
  m_restitution_factor = material.m_restitution_factor;
  m_rolling_resistance_factor = material.m_rolling_resistance_factor;
  m_drag_factor = material.m_drag_factor;
  m_bump_amplitude = material.m_bump_amplitude;
  m_bump_wavelength = material.m_bump_wavelength;

  if (material.mp_texture_image != 0)
	{
	  mp_texture_image = new Gl_Texture_Image (*(material.mp_texture_image));
	}
  else
	{
	  mp_texture_image = 0;
	}
}

Vamos_Geometry::Material::
~Material ()
{
  delete mp_texture_image;
}

const Vamos_Geometry::Material& Vamos_Geometry::Material::
operator = (const Material& material)
{
  if (&material != this)
	{
	  m_type = material.m_type;
	  m_friction_factor = material.m_friction_factor;
	  m_restitution_factor = material.m_restitution_factor;
	  m_rolling_resistance_factor = material.m_rolling_resistance_factor;
	  m_drag_factor = material.m_drag_factor;
	  m_bump_amplitude = material.m_bump_amplitude;
	  m_bump_wavelength = material.m_bump_wavelength;
	  
	  if (material.mp_texture_image != 0)
		{
		  delete mp_texture_image;
		  mp_texture_image 
			= new Gl_Texture_Image (*(material.mp_texture_image));
		}
	  else
		{
		  mp_texture_image = 0; 
		}
	}

  return *this;
}

double Vamos_Geometry::Material::
bump (double distance) const
{
  if ((m_bump_amplitude == 0.0) || (m_bump_wavelength == 0.0)) return 0.0;

  // To avoid interfering with the initial placement of the car, don't
  // return a positive number.
  const double phase = two_pi * distance / m_bump_wavelength; 
  const double shift = 2.0 * sin (phase * root_2);
  const double amplitude = 0.25 * m_bump_amplitude;
  return amplitude * (sin (phase + shift) + sin (root_2 * phase) - 2.0);
}
