// spectrum.H: spectral data representation

#ifndef _XRML_SPECTRUM_H_
#define _XRML_SPECTRUM_H_

#include <stdio.h>
#include "memory.H"

namespace xrml {

class Spectrum /* : public PooledObj */ {
public:
  float s[3];		// CIE XYZ color space.

  inline Spectrum(const float luminance=0.)
    {
      s[0] = s[1] = s[2] = luminance;
    }

  inline Spectrum(const float s0, const float s1, const float s2)
    {
      s[0] = s0; s[1] = s1; s[2] = s2;
    }

  inline float luminance(void) const
    {
      return s[1]; 
    }

  inline const Spectrum operator*(const float& t) const
    {
      return Spectrum(s[0]*t, s[1]*t, s[2]*t);
    }

  inline const Spectrum& operator*=(const float& t)
    {
      s[0]*=t; s[1]*=t; s[2]*=t; return *this;
    }

  inline const Spectrum operator/(const float& t) const
    {
      return Spectrum(s[0]/t, s[1]/t, s[2]/t);
    }

  inline const Spectrum& operator/=(const float& t)
    {
      s[0]/=t; s[1]/=t; s[2]/=t; return *this;
    }

  inline const Spectrum operator+(const Spectrum& t) const
    {
      return Spectrum(s[0]+t.s[0], s[1]+t.s[1], s[2]+t.s[2]);
    }

  inline const Spectrum& operator+=(const Spectrum& t)
    {
      s[0] += t.s[0]; s[1] += t.s[1]; s[2] += t.s[2];
      return *this;
    }

  inline const Spectrum operator-(const Spectrum& t) const
    {
      return Spectrum(s[0]-t.s[0], s[1]-t.s[1], s[2]-t.s[2]);
    }

  inline const Spectrum& operator-=(const Spectrum& t)
    {
      s[0] -= t.s[0]; s[1] -= t.s[1]; s[2] -= t.s[2];
      return *this;
    }

  inline const Spectrum operator*(const Spectrum& t) const
    {
      return Spectrum(s[0]*t.s[0], s[1]*t.s[1], s[2]*t.s[2]);
    }

  inline const Spectrum& operator*=(const Spectrum& t)
    {
      s[0] *= t.s[0]; s[1] *= t.s[1]; s[2] *= t.s[2];
      return *this;
    }

  inline const Spectrum operator/(const Spectrum& t) const
    {
      return Spectrum(s[0]/t.s[0], s[1]/t.s[1], s[2]/t.s[2]);
    }

  inline const Spectrum& operator/=(const Spectrum& t)
    {
      s[0] /= t.s[0]; s[1] /= t.s[1]; s[2] /= t.s[2];
      return *this;
    }

  inline float operator&(const Spectrum& t) const
    {
      return s[0] * t.s[0] + s[1] * t.s[1] + s[2] * t.s[2];
    }

  void print(FILE *out) const
    {
      fprintf(out, "%g %g %g", s[0], s[1], s[2]);
    }

  friend ostream& operator<<(ostream& s, const Spectrum& t)
    {
      return s << t.s[0] << ' ' << t.s[1] << ' ' << t.s[2];
    }
};

}  // namespace xrml

#endif /*_XRML_SPECTRUM_H_*/
