/* PhBMonitorCalibration.C: PhBMonitorCalibration nodes (public source) */

#include "PhBMonitorCalibration.H"
#include "cie.H"
#include "renderer.H"

namespace xrml {

static bool get_chromaticities(const Spectrum& spec, float *x, float *y)
{
  float s = spec.s[0] + spec.s[1] + spec.s[2];
  if (s<EPSILON)
    return false;
  *x = spec.s[0] / s;
  *y = spec.s[1] / s;
  return true;
}

void PhBMonitorCalibration::render(void)
{
  float
    xr = 0.640, yr = 0.330,		// nominal CRT primaries
    xg = 0.290, yg = 0.600,
    xb = 0.150, yb = 0.060,
    xw = 0.33333333, yw = 0.333333333;

  if (red) {
    red->render();
    if (!get_chromaticities(red->value, &xr, &yr))
      Warning(NULL, "%s.red is invalid", name());
  }
  if (green) {
    green->render();
    if (!get_chromaticities(green->value, &xg, &yg))
      Warning(NULL, "%s.green is invalid", name());
  }
  if (blue) {
    blue->render();
    if (!get_chromaticities(blue->value, &xb, &yb))
      Warning(NULL, "%s.blue is invalid", name());
  }
  if (white) {
    white->render();
    if (!get_chromaticities(white->value, &xw, &yw))
      Warning(NULL, "%s.white is invalid", name());
  }

  ComputeColorConversionTransforms(xr, yr, xg, yg, xb, yb, xw, yw,
				   xyz2rgb, rgb2xyz);

  world->renderer->phbMonitorCalibration(this);
}

Spectrum PhBMonitorCalibration::RGBToSpectrum(const SFColor& rgb)
{
  Vec3 rgbv(rgb.r, rgb.g, rgb.b);
  Vec3 xyzv = rgb2xyz * rgbv;
  return Spectrum(xyzv.x, xyzv.y, xyzv.z);
}

void PhBMonitorCalibration::set_bind(const SFBool& set)
{
  Bindable::set_bind(set);
}

}  // namespace xrml
