#ifndef _XPRIMITIVES_INCLUDED
#define _XPRIMITIVES_INCLUDED

///////////////////////////////////////////////
//											 //
// All files in X-framework are Copyright    //
// of Aleksandras Gluchovas 				 //
// 											 //
// e-mail: alex@soften.ktu.lt                //
//											 //
///////////////////////////////////////////////

#include "XObject.h"

#include "wx/string.h"

class XPrimitive : public XObject
{
public:
	int      mPrecision;
	wxString mName;

public:

	XPrimitive();

	virtual const char* GetTypeName() { return "XPrimitive"; }

	virtual void DrawName( wxDC& canvas );

	// overridables

	virtual void OnPropertiesChanged() {}

	// accessors

	inline wxString GetName() { return mName; }
	inline void SetName( const wxString& name ) { mName = name; }
};

class XLabelObj : public XPrimitive
{
public:
	XLabelObj();
	XLabelObj( const wxString& text );

	virtual void Draw( wxDC& canvas );

	virtual XRect GetBounds();
	virtual void SetBounds( const XRect& bounds );
	virtual void SetShape( XPoly& shape );
	virtual void GetShape( XPoly& shape );

	void SetColour( const wxColour& col );

	virtual XObject* CloneCopy( bool identical = FALSE );

protected:
	XRect  mBounds;
	wxColour mCol;
};

class XRectObj : public XPrimitive
{
protected:
	XRect  mRect;
	wxPen   mPen;
	wxBrush mBrush;

	bool   mMoveStarted;
public:

	XRectObj( const XRect& rect, 
			  const wxColour& bgColor = wxColour(0,0,255 ), 
			  const wxColour& outlineColor = wxColour(0,0,0) );

	virtual void Draw( wxDC& canvas );

	virtual XRect GetBounds();

	virtual void SetShape( XPoly& shape );
	virtual void GetShape( XPoly& shape );

	virtual XObject* CloneCopy( bool identical = FALSE );
};

// object covers infinitely large area, thus can
// be used as a background object. It should be placed
// in the back of all z-ordered objects and marked
// by calling "MarkBackgroundObj()" for XCollection object. 
// The drawing is optimized to repaint only the area which 
// is marked as dirty in the given canvas 

class XBackgroundObj : public XObject
{
protected:
	wxBrush mBrush; 
public:

	XBackgroundObj( const wxColour& bkColor = wxColour(255,255,255) );

	virtual void Draw( wxDC& canvas );

	virtual XRect GetBounds();
};

class XEdgedCircle : public XPrimitive
{
protected:
	XRect   mBounds;
	XPoly   mShape;
	wxBrush mBrush;

	void RegenerateShape();
public:
	XEdgedCircle( const XPoint& pos, 
		          int nEdges, 
				  int radius, const wxColour& color );

	virtual void Draw( wxDC& canvas );

	virtual XRect GetBounds();

	virtual void SetShape( XPoly& shape );
	virtual void GetShape( XPoly& shape );

	virtual void OnPropertiesChanged() { RegenerateShape(); }

	virtual XObject* CloneCopy( bool identical = FALSE );
};

class XArrow : public XPrimitive
{
protected:
	XPoint mFirst;
	XPoint mSecond;
	wxPen  mPen;

	int    mShaftLen;

public:
	XArrow( const XPoint& first, const XPoint& second, 
		    const wxColour& color = wxColour(0,0,0), int shaftLen = 40 );

	virtual void Draw( wxDC& canvas );

	virtual XRect GetBounds();

	virtual void SetShape( XPoly& shape );
	virtual void GetShape( XPoly& shape );

	virtual XObject* CloneCopy( bool identical = FALSE );
};

class XLineEditor : public XEditor
{
protected:
	XPoint mFirst;
	XPoint mSecond;

	XPoint mFirstOriginal;
	XPoint mSecondOriginal;

	XPoint mDragOrigin;

	bool   mFirstDragged;
	bool   mDragStarted;
	int    mHandleWidth;

	wxPen   mPen;
	wxBrush mBrush;

	bool IsInHandle( int isFirst, const XPoint& pos );
public:

	XLineEditor( int handleWidth );

	virtual bool OnMouseDown ( const XPoint& pos );
	virtual bool OnMouseUp   ( const XPoint& pos );
	virtual bool OnMouseMove ( const XPoint& pos );

	virtual void Draw( wxDC& canvas );

	virtual void SetShape( XPoly& shape );
	virtual void GetShape( XPoly& shape );

	virtual XRect GetBounds();
};

#endif