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

#ifndef tools_sg_viewer
#define tools_sg_viewer

#include "group"
#include "cursor_shape"

namespace tools {
namespace sg {

class viewer {
public:
  TOOLS_SCLASS(tools::sg::viewer)
  virtual void* cast(const std::string& a_class) const {
    if(void* p = cmp_cast<viewer>(this,a_class)) {return p;}
    else return 0;
  }
public:
  virtual void set_size(unsigned int a_w,unsigned int a_h) {
    size_event e(m_ww,m_wh,a_w,a_h);
    m_ww = a_w;
    m_wh = a_h;
    event_action action(m_out,m_ww,m_wh,e);
    action.set_do_switch_children(true); //Android : rot device : GUI & scene.
    m_sg.event(action); //used by m_plots in plots_viewer.
  }

  virtual bool set_cursor_shape(cursor_shape) {return false;}

public:
  viewer(std::ostream& a_out,unsigned int a_width,unsigned int a_height)
  :m_out(a_out)
  ,m_clear_color(1,1,1)
  ,m_ww(a_width)
  ,m_wh(a_height)
  ,m_use_gsto(false)
  ,m_produce_out_jpeg(false)
  ,m_produce_out_png(false)
  ,m_produce_out_file()
  ,m_produce_out_bpp(4)
  {
  }
  virtual ~viewer(){
    m_sg.clear(); //we must delete node before m_zb_mgr (and any render_manager).
  }
public:
  viewer(const viewer& a_from)
  :m_out(a_from.m_out)
  ,m_clear_color(a_from.m_clear_color)
  ,m_ww(a_from.m_ww)
  ,m_wh(a_from.m_wh)
  ,m_sg(a_from.m_sg)
  ,m_use_gsto(a_from.m_use_gsto)
  ,m_produce_out_jpeg(a_from.m_produce_out_jpeg)
  ,m_produce_out_png(a_from.m_produce_out_png)
  ,m_produce_out_file(a_from.m_produce_out_file)
  ,m_produce_out_bpp(a_from.m_produce_out_bpp)
  {
  }
  viewer& operator=(const viewer& a_from){
    m_clear_color = a_from.m_clear_color;
    m_ww = a_from.m_ww;
    m_wh = a_from.m_wh;
    m_sg = a_from.m_sg;
    m_use_gsto = a_from.m_use_gsto;
    m_produce_out_jpeg = a_from.m_produce_out_jpeg;
    m_produce_out_png = a_from.m_produce_out_png;
    m_produce_out_file = a_from.m_produce_out_file;
    m_produce_out_bpp = a_from.m_produce_out_bpp;
    return *this;
  }
public:
  bool set_default_cursor_shape() {return set_cursor_shape(cursor_default);}

  group& sg() {return m_sg;}
  const group& sg() const {return m_sg;}

  unsigned int width() const {return m_ww;}
  unsigned int height() const {return m_wh;}

  bool screen2aspect(int a_x,int a_y,float& a_wx,float& a_wy) const {
    // convert screen point in [aspect,1] coordinates.
    float aspect = float(m_ww)/float(m_wh);
    float wch = 1;
    float wcw = wch*aspect;
    a_wx = float(a_x) * wcw/float(m_ww);
    a_wy = float(a_y) * wch/float(m_wh);
    return true;
  }

  void set_clear_color(float a_r,float a_g,float a_b,float a_a = 1) {
    m_clear_color = colorf(a_r,a_g,a_b,a_a);
  }
  void set_clear_color(const colorf& a_color) {
    m_clear_color = a_color;
  }
  void get_clear_color(float& a_r,float& a_g,float& a_b,float& a_a) {
    a_r = m_clear_color.r();
    a_g = m_clear_color.g();
    a_b = m_clear_color.b();
    a_a = m_clear_color.a();
  }

  const colorf& background() const {return m_clear_color;}

  std::ostream& out() const {return m_out;}

  const std::string& out_dir() const {return m_out_dir;}


  void set_produce_out_jpeg(bool a_value) {m_produce_out_jpeg = a_value;}
  bool produce_out_jpeg() const {return m_produce_out_jpeg;}

  void set_produce_out_png(bool a_value) {m_produce_out_png = a_value;}
  bool produce_out_png() const {return m_produce_out_png;}

  void set_produce_out_file(const std::string& a_file) {m_produce_out_file = a_file;}
  const std::string& produce_out_file() const {return m_produce_out_file;}

  void set_produce_out_bpp(unsigned int a_bpp) {m_produce_out_bpp = a_bpp;}
  unsigned int produce_out_bpp() const {return m_produce_out_bpp;}

protected:
  std::ostream& m_out;
  colorf m_clear_color;
  unsigned int m_ww;
  unsigned int m_wh;
  group m_sg;
  std::string m_out_dir;
  bool m_use_gsto;
  bool m_produce_out_jpeg;
  bool m_produce_out_png;
  std::string m_produce_out_file;
  unsigned int m_produce_out_bpp;
};

}}

#endif

