/* -*- c++ -*-
 *
 * Copyrig>ht (C) 2004-2006 Mekensleep
 *
 *	Mekensleep
 *	24 rue vieille du temple
 *	75004 Paris
 *       licensing@mekensleep.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Authors:
 *  Johan Euphrosine <johan@mekensleep.com>
 *
 */

#ifndef OSGBUBBLE
#define OSGBUBBLE

#ifndef UGAME_USE_VS_PCH

#include <osg/Geometry>
#include <osg/Group>
#include <osg/Texture2D>

#endif

#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
	#  ifdef BUBBLE_LIBRARY
	#    define BUBBLE_EXPORT   __declspec(dllexport)
	#  else
	#    define BUBBLE_EXPORT   __declspec(dllimport)
	#  endif /* BUBBLE_LIBRARY*/
#else
	#  define BUBBLE_EXPORT
#endif

#ifdef UNITTEST
#undef BUBBLE_EXPORT
#define BUBBLE_EXPORT
#endif

namespace osgText
{
  class Text;
}
extern "C" {
  struct _xmlDoc;
}

struct PokerEditor;
BUBBLE_EXPORT void setPokerEditor(PokerEditor* editor);

namespace osgbubble
{
  struct PatchBase : osg::Geometry
  {
    PatchBase();
    void	init(const std::string& xml);
    void	initStateSet();
    void	setVertices(const osg::Vec3* vertices, unsigned int size);
    template<int N>
    void	setVertices(const osg::Vec3 (&vertices)[N])
    {
      setVertices(&vertices[0], N);
    }
    void	setTexCoords(const osg::Vec2* tex_coord, unsigned int size);
    template<int N>
    void	setTexCoords(const osg::Vec2 (&tex_coord)[N])
    {
      setTexCoords(&tex_coord[0], N);
    }
    void	addTriStrip(const unsigned short* tri_strip, unsigned int size);
    template<int N>
    void	addTriStrip(const unsigned short (&trip_strip)[N])
    {
      addTriStrip(&trip_strip[0], N);
    }
    osg::Texture2D*	setTexture(const std::string& filename);
    osg::ref_ptr<osg::Vec3Array> mVertices;
    osg::ref_ptr<osg::Vec2Array> mTexCoords;
  };

  struct Body : PatchBase
  {
    Body();
    void init();
    void computeXYLen(float xLen, float yLen);
    std::string mBodyCenterTextureFileName;
		std::string mBodyLeftTextureFileName;
		std::string mBodyRightTextureFileName;
		osg::ref_ptr<osg::Texture2D> mTextureCenter;
		osg::ref_ptr<osg::Texture2D> mTextureLeft;
		osg::ref_ptr<osg::Texture2D> mTextureRight;
  };

  struct Tail : PatchBase
  {
    Tail();
    void init();
    void snap(const osg::Vec3& pos);
		std::string mTailTextureFileName;
  };

  struct Bubble : osg::Group
  {
    BUBBLE_EXPORT Bubble();
    BUBBLE_EXPORT Bubble(osg::Node *node);
    BUBBLE_EXPORT ~Bubble();
    BUBBLE_EXPORT void init();
    BUBBLE_EXPORT void clean();
    BUBBLE_EXPORT bool unserialize(_xmlDoc* doc);
    void attachToNode(osg::Node* node);
    void attachTailToBody();
    BUBBLE_EXPORT void setText(const std::string &text);
		
    osg::ref_ptr<osgText::Text> mText;
    osg::ref_ptr<osg::Geode> mTextGeode;
    osg::ref_ptr<osg::PositionAttitudeTransform> mTextPAT;

    osg::ref_ptr<Tail> mTailCenter;
    osg::ref_ptr<osg::Geode> mTailCenterGeode;
    osg::ref_ptr<Tail> mTailLeft;
    osg::ref_ptr<osg::Geode> mTailLeftGeode;
    osg::ref_ptr<Tail> mTailRight;
    osg::ref_ptr<osg::Geode> mTailRightGeode;
    osg::ref_ptr<osg::PositionAttitudeTransform> mTailPAT;

    osg::ref_ptr<Body> mBody;
    osg::ref_ptr<osg::Geode> mBodyGeode;
    osg::ref_ptr<osg::PositionAttitudeTransform> mBodyPAT;

    BUBBLE_EXPORT void SetTailPosition(const osg::Vec3& tailPosition)
    {
      mTailPosition = tailPosition;
    }
    BUBBLE_EXPORT const osg::Vec3& GetTailPosition() const
    {
      return mTailPosition;
    }
    osg::Vec3 mTailPosition;
    
    BUBBLE_EXPORT void SetBubblePosition(const osg::Vec3& bubblePosition)
    {
      mBubblePosition = bubblePosition;
    }
    BUBBLE_EXPORT const osg::Vec3& GetBubblePosition() const
    {
      return mBubblePosition;
    }
    osg::Vec3 mBubblePosition;
    
    BUBBLE_EXPORT const osg::Vec2& GetSize()
    {
      return mSize;
    }
    osg::Vec2 mSize;
    BUBBLE_EXPORT void UpdateBubblePosition();
    BUBBLE_EXPORT void UpdateTailPosition();
    BUBBLE_EXPORT void UpdateTailPosition2();
    BUBBLE_EXPORT void SetFontSize(float size);
    BUBBLE_EXPORT void SetRenderBinOffset(int offset);
    BUBBLE_EXPORT void SetColor(const osg::Vec4& color);
    bool IntersectBodyTail(float& t, int a, int b);
    std::string mTextFontFileName;
    float mTextFontCharacterSize;
    osg::Vec4 mTextColor;
    osg::ref_ptr<osg::Vec3Array> mDebugVertices;
    osg::ref_ptr<osg::Geometry> mDebugGeom;
    osg::ref_ptr<osg::Geode> mDebugGeode;
    float mAngle;
    bool mFlag;
    osg::Vec4 mColor;
  };  
}

#endif //OSGBUBBLE
