#include "stdafx.h"

#include "mdc_canvas_view_opengl.h"
/**
 * @file  mdc_canvas_view_opengl.cpp
 * @brief 
 */

using namespace mdc;


OpenGLCanvasView::OpenGLCanvasView(int width, int height)
  : CanvasView(width, height)
{
}


OpenGLCanvasView::~OpenGLCanvasView()
{
}


void OpenGLCanvasView::check_error()
{
  GLenum err= glGetError();
  if (err != GL_NO_ERROR)
  {
    const char *msg= "unknown error";
    switch (err)
    {
    case GL_NO_ERROR: msg= "no error"; break;
    case GL_INVALID_ENUM: msg= "invalid enum"; break;
    case GL_INVALID_VALUE: msg= "invalid value"; break;
    case GL_INVALID_OPERATION: msg= "invalid operation"; break;
    case GL_STACK_OVERFLOW: msg= "stack overflow"; break;
    case GL_STACK_UNDERFLOW: msg= "stack underflow"; break;
    case GL_OUT_OF_MEMORY: msg= "out of memory"; break;
#ifdef GL_TABLE_TOO_LARGE
    case GL_TABLE_TOO_LARGE: msg= "table too large"; break;
#endif
    }
    throw std::runtime_error("OpenGL error: "+std::string(msg));
  }
}


bool OpenGLCanvasView::initialize()
{
  if (!CanvasView::initialize())
    return false;
  
  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

  glFrontFace(GL_CW);
  glDisable(GL_CULL_FACE);
  glDisable(GL_DITHER);
  glDisable(GL_DEPTH_TEST);

  glEnable(GL_LINE_SMOOTH);
  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  glDisable(GL_POLYGON_SMOOTH);
  glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  glEnable(GL_AUTO_NORMAL);
  glEnable(GL_NORMALIZE);

  glDisable(GL_FOG);
  glDisable(GL_LOGIC_OP);
  glDisable(GL_STENCIL_TEST);
  glDisable(GL_TEXTURE_1D);
  glEnable(GL_TEXTURE_2D);
  glDisable(GL_LIGHTING);

  check_error();

  return true;
}


void OpenGLCanvasView::begin_repaint(int, int, int, int)
{
  make_current();

  // Start clean.
  glClear(GL_COLOR_BUFFER_BIT);
}


void OpenGLCanvasView::end_repaint()
{
  swap_buffers();
  check_error();
  remove_current();
}

