// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.

#ifndef toolx_sg_GL_viewer
#define toolx_sg_GL_viewer

#include <tools/sg/viewer>

namespace tools{namespace sg{class render_manager;}}

namespace toolx {
namespace sg {

template <class GL_MANAGER,class GL_ACTION>
class GL_viewer_T : public tools::sg::viewer {
  TOOLS_T2_HEADER(GL_MANAGER,GL_ACTION,GL_viewer_T,toolx::sg::GL_viewer_T,tools::sg::viewer)
public:
  void render() {
    if(!m_ww) return;
    if(!m_wh) return;

    if(!m_gl_mgr.begin_render(0,0,m_ww,m_wh,
                              m_clear_color.r(),
                              m_clear_color.g(),
                              m_clear_color.b(),
                              m_clear_color.a())) return;

    GL_ACTION action(m_gl_mgr,m_out,m_ww,m_wh);
    action.state().m_use_gsto = m_use_gsto;

    action.set_do_transparency(false);
    action.set_have_to_do_transparency(false);
    
    m_sg.render(action);
    if(!action.end()) { //check that matrices stack are ok.
      m_out << "toolx::sg::GL_viewer_T : bad gl_action end." << std::endl;
    } else {
      if(action.have_to_do_transparency()) {
        action.set_do_transparency(true);
        m_sg.render(action);
        if(!action.end()) { //check that matrices stack are ok.
          m_out << "toolx::sg::GL_viewer_T : bad gl_action end." << std::endl;
        }
      }
    }

    m_gl_mgr.end_render();
  }

public:
  GL_viewer_T(std::ostream& a_out,unsigned int a_width,unsigned int a_height)
  :parent(a_out,a_width,a_height)
  ,m_gl_mgr(a_out)
  {}
  virtual ~GL_viewer_T(){
    //WARNING : nodes may refer m_gl_mgr (to handle gstos/texs), then
    //          we have to delete them first.
    m_sg.clear();
  }
public:
  GL_viewer_T(const GL_viewer_T& a_from)
  :parent(a_from)
  ,m_gl_mgr(a_from.m_gl_mgr)
  {}
  GL_viewer_T& operator=(const GL_viewer_T& a_from){
    parent::operator=(a_from);
    m_gl_mgr = a_from.m_gl_mgr;
    return *this;
  }
public:
  const tools::sg::render_manager& render_manager() const {return m_gl_mgr;}
  tools::sg::render_manager& render_manager() {return m_gl_mgr;}
protected:
  GL_MANAGER m_gl_mgr;
};

}}

#endif
