/********************************************************************/
/* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
#ifndef _MGAttribedGel_HH_
#define _MGAttribedGel_HH_

#include "mg/MGCL.h"
#include "mg/Gel.h"
#include "mgGL/VBO.h"

//
//Define MGAttribedGel Class.

class MGAppearance;
class MGObject;
class MGGroup;
class MGGLAttrib;
class MGName;
class mgVBO;

class MGColor;

/** @addtogroup GelRelated
 *  @{
 */

///Is an abstract class which provides interfaces of MGGel that has MGAppearance.

///MGAppearance has MGAttrib's that decorate MGGel. MGAttribedGel is MGGel
///that has MGAppearance.
class MG_DLL_DECLR MGAttribedGel:public MGGel{
friend class MGGroup;
friend class MGObject;
friend class mgVBO;
friend class MGDNameControl;

public:

///void constructor.
MGAttribedGel():m_dlistName(nullptr){;};

///copy constructor.
MGAttribedGel(const MGAttribedGel& gel2);

///Assignment.
///When the leaf objects of this and gel2 are not equal, this assignment
///does nothing.
virtual MGAttribedGel& operator=(const MGAttribedGel& gel2);

virtual ~MGAttribedGel();

///Get the MGAppearance pointer in this group. If not defined, null will be
///returned.
virtual MGAppearance* appearance()=0;
virtual const MGAppearance* appearance()const=0;

//copy the appearance of gel2 to this.
void copy_appearance(const MGAttribedGel& gel2);

///Obtain display list name.
///MGAttribedGel's deleteDlistName only deletes Dname to pointer map list.
mgVBO* dlist_name()const;

///Judge if the display list for vmode is made or not.
virtual bool displayList_is_made(MGCL::VIEWMODE vmode)const;

///Delete display list name from MGDNameControl.
///MGAttribedGel's deleteDlistName deletes mgVBO of this.
void deleteDlistName()const;

///Process of draw or render attributes.
virtual void drawAttrib(
	mgVBO& vbo,///<The target graphic object.
	bool no_color=false	///if true, color attribute will be neglected.
)const;
virtual void render_attribute()const;

///Make sure that this MGAttribedGel has appearance,
/// and get the MGAppearance pointer.
virtual MGAppearance* ensure_appearance()=0;

///Obtain attribute mask for glPushAttrib().
virtual int get_draw_attrib_mask()const;
virtual int get_render_attrib_mask()const;

///Get the number of elements of m_dlistName.
int getVBOElementsNumber()const;

///Get the number of shading elements of m_dlistName.
int getVBOShaderElementsNumber()const;

///Test if this group is attributed  as no display.
///true if attributed as no display.
virtual bool no_display()const;

///Remove the MGAppearance of this MGAttribedGel.
virtual void remove_appearance()=0;

///Removed the attribute of specified type.
void remove_GLattrib(long tid);

///Set the attribute in this list. attr must be a newed object, and the
///ownership will be transfered to this MGAppearance.
virtual void set_GLattrib(MGGLAttrib* attr);

///Set this group as display or no display group.
virtual void set_display();
virtual void set_no_display();
bool visible()const{return !no_display();};

//set the copy of appr2 to this MGAttribedgel.
virtual void set_appearance(const MGAppearance& appr2)=0;

///Set name to this MGAttribedGel.
///If this had a name already, the old name is replace with newName;
void set_name(const MGName& newName);

///Get the name of this MGAttribedGel.
///If this had no name, null will be returned.
///If this did have a name, the pointer is returned.
const MGName* get_name()const;

///Set color to this MGAttribedGel.
///If this had a color already, the old color is replace with newColor;
void set_color(const MGColor& newColor);

///Get the color of this MGAttribedGel.
///If this had no color, null will be returned.
///If this did have a color, the pointer is returned.
const MGColor* get_color()const;

///Set DlistName.
///vbo must be newed one, and the ownership is transfered to this MGAttribedGel.
void setDlistName(mgVBO* vbo=0)const;

///Set dirty flag(s) of this VBO(m_dlistName).
void setDirty(
	bool is_dirty	///<  =true if dirty and need to remake.
)const;

protected:
	mutable std::unique_ptr<mgVBO> m_dlistName;///<display name if m_dlistName!=0;


};

/** @} */ // end of GelRelated group
#endif
