
// quality_menu.cpp - make GLUT menu of framebuffer quality settings

#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>  // for std::sort
#include <GL/glew.h>
#include <GL/glut.h>
#include "gl_framebuffer.hpp"
#include "quality_menu.hpp"

extern GLFramebuffer *fb;

class GLQualitySetting {
private:
  int coverage_samples;
  int color_samples;
  bool supersampled;

  int menu_value;
  std::string name;
  int effective_coverage_samples;
  int effective_color_samples;

public:
  GLQualitySetting(int cov_samples, int col_samples, bool ss) 
    : coverage_samples(cov_samples)
    , color_samples(col_samples)
    , supersampled(ss)
    , effective_coverage_samples(ss ? 4*coverage_samples : coverage_samples)
    , effective_color_samples(ss ? 4*color_samples : color_samples)
  {
    char buffer[100];
    sprintf(buffer, "%s%d:%d (samples=%d)", supersampled ? "4x" : "",
      coverage_samples, color_samples, effective_coverage_samples);
    name = std::string(buffer);
  }

  inline const char* getName() const {
    return name.c_str();
  }
  inline int getColorSamples() const {
    return color_samples;
  }
  inline int getCoverageSamples() const {
    return coverage_samples;
  }
  inline bool getSupersampled() const {
    return supersampled;
  }

  bool operator<( const GLQualitySetting& other) const { 
    if (effective_coverage_samples != other.effective_coverage_samples) {
      return effective_coverage_samples < other.effective_coverage_samples;
    }
    if (effective_color_samples != other.effective_color_samples) {
      return effective_color_samples < other.effective_color_samples;
    }
    if (coverage_samples != other.coverage_samples) {
      return coverage_samples < other.coverage_samples;
    }
    if (color_samples != other.color_samples) {
      return color_samples < other.color_samples;
    }
    return true;
  }
};

typedef std::vector<GLQualitySetting> GLQualitySettingArray;
GLQualitySettingArray quality_settings;

static void selectQuality(int ndx)
{
  const GLQualitySetting &setting = quality_settings[ndx];
  fb->setQuality(setting.getCoverageSamples(),
    setting.getColorSamples(),
    setting.getSupersampled() ? GLFramebuffer::Supersample : GLFramebuffer::Normal);
  glutPostRedisplay();
}

int createQualitySettingMenu(bool hasFramebufferMixedSamples)
{
  int quality_menu = glutCreateMenu(selectQuality);
  for (int s=0; s<2; s++) {
    for (int i=1; i<=8; i *= 2) {
      for (int j=i; j<=16; j *= 2) {
        if (!hasFramebufferMixedSamples) {
          if (i != j) {
            break;  // Skip
          }
        }
        quality_settings.push_back(GLQualitySetting(j, i, !!s));
      }
    }
  }
  std::sort(quality_settings.begin(), quality_settings.end());

  for (size_t i=0; i<quality_settings.size(); i++) {
    const GLQualitySetting &setting = quality_settings[i];
    glutAddMenuEntry(setting.getName(), int(i)); 
  }
  return quality_menu;
}
