//-----------------------------------------------------------------------------
// VST Plug-Ins SDK
// VSTGUI: Graphical User Interface Framework for VST plugins : 
//
// Version 3.0       $Date: 2005/11/15 14:56:42 $
//
//-----------------------------------------------------------------------------
// VSTGUI LICENSE
// © 2004, Steinberg Media Technologies, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// 
//   * Redistributions of source code must retain the above copyright notice, 
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation 
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this 
//     software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  PARTICULAR PURPOSE ARE DISCLAIMED. 
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#ifndef __vstgui__
#define __vstgui__

// define global defines
#if WIN32
	#define WINDOWS 1
#elif SGI | SUN
	#define MOTIF 1
#elif __MWERKS__ || __APPLE_CC__
	#define MAC 1
	#if __MACH__
	#define MACX 1
	#define QUARTZ 1
	#ifndef TARGET_API_MAC_CARBON
	#define TARGET_API_MAC_CARBON 1
	#endif
	#ifndef __CF_USE_FRAMEWORK_INCLUDES__
	#define __CF_USE_FRAMEWORK_INCLUDES__ 1
	#endif
	#endif
#elif __BEOS__
	#define BEOS 1
#endif

#if WINDOWS
 #define USE_NAMESPACE 1
#endif

#if USE_NAMESPACE
 #define BEGIN_NAMESPACE_VSTGUI  namespace VSTGUI {
 #define END_NAMESPACE_VSTGUI    }
 #define USING_NAMESPACE_VSTGUI using namespace VSTGUI;
#else
 #define BEGIN_NAMESPACE_VSTGUI
 #define END_NAMESPACE_VSTGUI
 #define USING_NAMESPACE_VSTGUI
#endif

// VSTGUI Version
#define VSTGUI_VERSION_MAJOR  3
#define VSTGUI_VERSION_MINOR  0

//----------------------------------------------------
//----------------------------------------------------
BEGIN_NAMESPACE_VSTGUI

class CFrame;
class CDrawContext;
class COffscreenContext;
class CControl;
class CBitmap;

END_NAMESPACE_VSTGUI

#if PLUGGUI
	#ifndef __plugguieditor__
	#include "plugguieditor.h"
	#endif
#else
	#ifndef __aeffguieditor__
	#include "aeffguieditor.h"
	#endif
#endif

//----------------------------------------------------
#if WINDOWS
	#include <windows.h>

//----------------------------------------------------
#elif MOTIF
	#include <X11/Xlib.h>
	#include <X11/Intrinsic.h>
	#ifdef NOBOOL
		#ifndef bool
			typedef short bool;
		#endif
		#ifndef false
			static const bool false = 0; 
		#endif
		#ifndef true
			static const bool true = 1;
		#endif
	#endif

	// definition of struct for XPixmap resources
	struct CResTableEntry {
		int id;
  		char **xpm;
	};

	typedef CResTableEntry CResTable[];
	extern CResTable xpmResources;

//----------------------------------------------------
#elif MAC
	#if MACX
	#include <Carbon/Carbon.h>
	//macho VST's set gBundleRef which is a CFBundleRef
	BEGIN_NAMESPACE_VSTGUI
	extern void* gBundleRef;
	END_NAMESPACE_VSTGUI
	#else
	#include <Quickdraw.h>
	#include <Menus.h>
	#include <Windows.h>
	#include <TextUtils.h>
	#include <TextEdit.h>
	#include <ToolUtils.h>
	#include <Resources.h>
	#include <Dialogs.h>
	#endif
//----------------------------------------------------
#elif BEOS
	#include <Font.h>
	class BView;
	class PlugView;
	class BBitmap;
	class BResources;
#endif

struct VstKeyCode;

BEGIN_NAMESPACE_VSTGUI

struct CPoint;

#define CLASS_METHODS(name, parent)             \
	virtual bool isTypeOf (const char* s) const \
		{ return (!strcmp (s, (#name))) ? true : parent::isTypeOf (s); }\

#ifdef VSTGUI_FLOAT_COORDINATES
typedef float CCoord;
#else
typedef long CCoord;
#endif

//-----------------------------------------------------------------------------
// Structure CRect
//-----------------------------------------------------------------------------
struct CRect
{
	CRect (CCoord left = 0, CCoord top = 0, CCoord right = 0, CCoord bottom = 0)
	:	left (left), top (top), right (right), bottom (bottom) {}
	CRect (const CRect& r)
	:	left (r.left), top (r.top), right (r.right), bottom (r.bottom) {}
	CRect& operator () (CCoord left, CCoord top, CCoord right, CCoord bottom)
	{
		if (left < right)
			this->left = left, this->right = right;
		else
			this->left = right, this->right = left;
		if (top < bottom)
			this->top = top, this->bottom = bottom;
		else
			this->top = bottom, this->bottom = top;
		return *this;
	}

	bool operator != (const CRect& other) const
	{ return (left != other.left || right != other.right ||
				top != other.top || bottom != other.bottom); }

	bool operator == (const CRect& other) const
	{ return (left == other.left && right == other.right &&
				top == other.top && bottom == other.bottom); }
	
	inline CCoord width () const  { return right - left; }
	inline CCoord height () const { return bottom - top; }

	inline CCoord getWidth () const  { return right - left; }
	inline CCoord getHeight () const { return bottom - top; }

	inline void setWidth (CCoord width) { right = left + width; }
	inline void setHeight (CCoord height) { bottom = top + height; }

	CRect &offset (CCoord x, CCoord y)
	{ left += x; right += x; top += y; bottom += y; return *this; }

	CRect &inset (CCoord deltaX, CCoord deltaY)
	{ left += deltaX; right -= deltaX; top += deltaY; bottom -= deltaY;
    return *this; }

	CRect &moveTo (CCoord x, CCoord y)
	{ CCoord vDiff = y - top; CCoord hDiff = x - left; 
	top += vDiff; bottom += vDiff; left += hDiff; right += hDiff;
	return *this; }

	bool pointInside (const CPoint& where) const;	// Checks if point is inside this rect
	bool isEmpty () const;

	bool rectOverlap (const CRect& rect) const
	{
		if (right < rect.left) return false;
		if (left > rect.right) return false;
		if (bottom < rect.top) return false;
		if (top > rect.bottom) return false;
		return true;
	}

	void bound (const CRect& rect);

	union
	{ CCoord left; CCoord x;};

	union
	{ CCoord top; CCoord y;};

	union
	{ CCoord right; CCoord x2;};

	union
	{ CCoord bottom; CCoord y2;};
};

//-----------------------------------------------------------------------------
// Structure CPoint
//-----------------------------------------------------------------------------
struct CPoint
{
	CPoint (CCoord h = 0, CCoord v = 0) : h (h), v (v) {}
	CPoint& operator () (CCoord h, CCoord v)
	{ this->h = h; this->v = v; return *this; }

	bool isInside (CRect& r) const
	{ return h >= r.left && h <= r.right && v >= r.top && v <= r.bottom; } 

	bool operator != (const CPoint &other) const
	{ return (h != other.h || v != other.v); }

	bool operator == (const CPoint &other) const
	{ return (h == other.h && v == other.v); }

	CPoint &offset (CCoord h, CCoord v)
	{ this->h += h; this->v += v; return *this; }

	union
	{ CCoord h; CCoord x;};

	union
	{ CCoord v; CCoord y;};
};

//-----------------------------------------------------------------------------
// Structure CColor
//-----------------------------------------------------------------------------
struct CColor
{
	CColor& operator () (unsigned char red,
						unsigned char green,
						unsigned char blue,
						unsigned char alpha)
	{
		this->red   = red;
		this->green = green;
		this->blue  = blue;
		this->alpha = alpha;
		return *this; 
	}

	CColor& operator = (const CColor& newColor)
	{
		red   = newColor.red;
		green = newColor.green;
		blue  = newColor.blue;
		alpha = newColor.alpha;
		return *this; 
	}
	
	CColor operator ~ ()
	{
		CColor c;
		c.red   = ~red;
		c.green = ~green;
		c.blue  = ~blue;
		c.alpha = ~alpha;
		return c;
	}

	bool operator != (const CColor &other) const 
	{ return (red != other.red || green != other.green || blue  != other.blue || alpha != other.alpha); }

	bool operator == (const CColor &other) const
	{ return (red == other.red && green == other.green && blue  == other.blue && alpha == other.alpha); }
	
	unsigned char red;
	unsigned char green;
	unsigned char blue;
	unsigned char alpha;
};

// define some basic colors
extern CColor kTransparentCColor;
extern CColor kBlackCColor;
extern CColor kWhiteCColor;
extern CColor kGreyCColor;
extern CColor kRedCColor;
extern CColor kGreenCColor;
extern CColor kBlueCColor;
extern CColor kYellowCColor;
extern CColor kCyanCColor;
extern CColor kMagentaCColor;


//-----------------------------------------------------------------------------
// Definitions of special characters in a platform independent way

#if WINDOWS || MOTIF
#define kDegreeSymbol      "\xB0"
#define kInfiniteSymbol    "oo"
#define kCopyrightSymbol   "\xA9"
#define kTrademarkSymbol   "\x99"
#define kRegisteredSymbol  "\xAE"
#define kMicroSymbol       "\x85"
#define kPerthousandSymbol "\x89"

#elif BEOS
#define kDegreeSymbol      "\xC2\xB0"
#define kInfiniteSymbol    "\xE2\x88\x9E"
#define kCopyrightSymbol   "\xC2\xA9"
#define kTrademarkSymbol   "\xE2\x84\xA2"
#define kRegisteredSymbol	"\xC2\xAE"
#define kMicroSymbol       "\xC2\xB5"
#define kPerthousandSymbol "\xE2\x80\xB0"

#elif MAC
#define kDegreeSymbol      "\xA1"
#define kInfiniteSymbol    "oo"
#define kCopyrightSymbol   "\xA9"
#define kTrademarkSymbol   "\xAA"
#define kRegisteredSymbol  "\xA8"
#define kMicroSymbol       "\xB5"
#define kPerthousandSymbol "\xE4"
#endif

class CDragContainer;
class CCView;
class CAttributeListEntry;

//-----------------------------------------------------------------------------
typedef unsigned long CViewAttributeID;
//-----------------------------------------------------------------------------
// Attributes
//		all attributes where the first letter is lowercase are reserved for the vstgui lib

extern const CViewAttributeID kCViewAttributeReferencePointer;	// 'cvrp'

//-----------------------------------------------------------------------------
//-----------
// Font Type
//-----------
enum CFont
{
	kSystemFont = 0,
	kNormalFontVeryBig,
	kNormalFontBig,
	kNormalFont,
	kNormalFontSmall,
	kNormalFontSmaller,
	kNormalFontVerySmall,
	kSymbolFont,

	kNumStandardFonts
};

//-----------
// Text Face
//-----------
enum CTxtFace
{
	kNormalFace    = 0,
	kBoldFace      = 1,
	kItalicFace    = 2,
	kUnderlineFace = 4
};

//-----------
// Line Style
//-----------
enum CLineStyle
{
	kLineSolid = 0,
	kLineOnOffDash
};

//-----------
// Draw Mode
//-----------
enum CDrawMode
{
	kCopyMode = 0,
	kOrMode,
	kXorMode,
	kAntialias
};

//----------------------------
// Text Alignment (Horizontal)
//----------------------------
enum CHoriTxtAlign
{
	kLeftText = 0,
	kCenterText,
	kRightText
};

//----------------------------
// Buttons Type (+modifiers)
//----------------------------
enum CButton
{
	kLButton =  1,
	kMButton =  2,
	kRButton =  4,
	kShift   =  8,
	kControl = 16,
	kAlt     = 32,
	kApple   = 64
};

//----------------------------
// Cursor Type
//----------------------------
enum CCursorType
{
	kCursorDefault = 0,
	kCursorWait,
	kCursorHSize,
	kCursorVSize,
	kCursorSizeAll,
	kCursorNESWSize,
	kCursorNWSESize,
	kCursorCopy,
	kCursorNotAllowed,
	kCursorHand
};

//----------------------------
// Knob Mode
//----------------------------
enum CKnobMode
{
	kCircularMode = 0,
	kRelativCircularMode,
	kLinearMode
};

//----------------------------
// Draw Style
//----------------------------
enum CDrawStyle
{
	kDrawStroked = 0,
	kDrawFilled,
	kDrawFilledAndStroked
};

enum CMouseWheelAxis
{
	kMouseWheelAxisX = 0,
	kMouseWheelAxisY
};

//-----------------------------------------------------------------------------
// CReferenceCounter Declaration (Reference Counting)
//-----------------------------------------------------------------------------
class CReferenceCounter
{
public:
	CReferenceCounter () : nbReference (1) {}
	virtual ~CReferenceCounter () {}
	
	virtual void forget () { nbReference--; if (nbReference == 0) delete this; }
	virtual void remember () { nbReference++; }
	long getNbReference () const { return nbReference; }

private:
	long nbReference;
};

//-----------------------------------------------------------------------------
// CDrawContext Declaration
//! A drawing context encapsulates the drawing context of the underlying OS. It implements the drawing functions.
//-----------------------------------------------------------------------------
class CDrawContext : public CReferenceCounter
{
public:
	CDrawContext (CFrame *pFrame, void *pSystemContext, void *pWindow = 0);
	virtual ~CDrawContext ();	

	void moveTo (const CPoint &point);	///< move line position to point
	void lineTo (const CPoint &point);	///< draw a line from current position to point
	void drawLines (const CPoint* points, const long& numberOfLines);	///< draw multiple lines at once

	void drawPolygon (const CPoint *pPoints, long numberOfPoints, const CDrawStyle drawStyle = kDrawStroked); ///< draw a polygon
	void polyLine (const CPoint *pPoint, long numberOfPoints);	///< draw a stroked polygon
	void fillPolygon (const CPoint *pPoint, long numberOfPoints);	///< draw a filled polygon

	void drawRect (const CRect &rect, const CDrawStyle drawStyle = kDrawStroked);	///< draw a stroked rect
	void fillRect (const CRect &rect);	///< draw a filled rect

	void drawArc (const CRect &rect, const float startAngle1, const float endAngle2, const CDrawStyle drawStyle = kDrawStroked);	///< draw a stroked arc, where the angles are in degree
	void drawArc (const CRect &rect, const CPoint &point1, const CPoint &point2);		///< draw a stroked arc between point1 and point2
	void fillArc (const CRect &rect, const CPoint &point1, const CPoint &point2);		///< draw a filled arc between point1 and point2

	void drawEllipse (const CRect &rect, const CDrawStyle drawStyle = kDrawStroked);	///< draw an ellipse
	void fillEllipse (const CRect &rect);	///< draw a filled ellipse
	
	void drawPoint (const CPoint &point, CColor color);	///< draw a point
	CColor getPoint (const CPoint& point); ///< \deprecated

	void floodFill (const CPoint& start); ///< \deprecated
	
	void       setLineStyle (CLineStyle style);				///< set the current line style
	CLineStyle getLineStyle () const { return lineStyle; }	///< get the current line style

	void   setLineWidth (CCoord width);						///< set the current line width
	CCoord getLineWidth () const { return frameWidth; }		///< get the current line width

	void      setDrawMode (CDrawMode mode);					///< set the current draw mode, see CDrawMode
	CDrawMode getDrawMode () const { return drawMode; }		///< get the current draw mode, see CDrawMode

	void   setClipRect (const CRect &clip);					///< set the current clip
	CRect &getClipRect (CRect &clip) const { clip = clipRect; clip.offset (-offset.h, -offset.v); return clip; }	///< get the current clip
	void   resetClipRect ();	///< reset the clip to the default state

	void   setFillColor  (const CColor color);			///< set current fill color
	CColor getFillColor () const { return fillColor; }	///< get current fill color

	void   setFrameColor (const CColor color);				///< set current stroke color
	CColor getFrameColor () const { return frameColor; }	///< get current stroke color

	void   setFontColor (const CColor color);			///< set current font color
	CColor getFontColor () const { return fontColor; }	///< get current font color
	void   setFont (CFont fontID, const long size = 0, long style = 0);	///< set current font
	CFont  getFont () const { return fontId; }							///< get current font
	long   getFontSize () const { return fontSize; }	///< get current font size

	CCoord getStringWidth (const char* pStr);	///< get the width of a string

	void drawString (const char *pString, const CRect &rect, const short opaque = false,
					 const CHoriTxtAlign hAlign = kCenterText);	///< draw a string

	long getMouseButtons ();	///< get current mouse buttons
	void getMouseLocation (CPoint &point);	///< get current mouse location. should not be used, see CView::getMouseLocation
	bool waitDoubleClick ();	///< check if another mouse click occurs in the near future
	bool waitDrag ();			///< check if the mouse will be dragged

#if MOTIF
	long getIndexColor (CColor color);
	Colormap getColormap ();
	Visual   *getVisual ();
	unsigned int getDepth ();

	static long nbNewColor;
#endif

	void *getWindow () { return pWindow; }
	void setWindow (void *ptr)  { pWindow = ptr; }
	void getLoc (CPoint &where) const { where = penLoc; }
	CFrame* getFrame () const { return pFrame; }

	CPoint offsetScreen;
	CPoint offset;

	void   *getSystemContext () const { return pSystemContext; }

	virtual void forget ();

	//-------------------------------------------
protected:

	friend class CBitmap;
	friend class COffscreenContext;

	void   *pSystemContext;
	void   *pWindow;
	CFrame *pFrame;

	long   fontSize;
	long   fontStyle;
	CFont  fontId;
	CColor fontColor;
	CPoint penLoc;

	CCoord   frameWidth;
	CColor frameColor;
	CColor fillColor;
	CLineStyle lineStyle;
	CDrawMode  drawMode;
	CRect  clipRect;

#if WINDOWS
	void *pBrush;
	void *pPen;
	void *pFont;
	void *pOldBrush;
	void *pOldPen;
	void *pOldFont;
	long iPenStyle;
	HDC  pHDC;

#elif MAC
	#if QUARTZ
	CGContextRef gCGContext;
	bool needToSynchronizeCGContext;
	public:
	CGContextRef getCGContext () const { return gCGContext; }
	CGContextRef beginCGContext (bool swapYAxis = false);
	void releaseCGContext (CGContextRef context);
	void synchronizeCGContext ();
	
	virtual CGImageRef getCGImage () const;
	protected:
	#else

	FontInfo fontInfoStruct;
	Pattern fillPattern;
	bool bInitialized;
	#endif
	virtual BitMapPtr getBitmap ();
	virtual void releaseBitmap ();
	virtual CGrafPtr getPort ();
	
#elif MOTIF
	Display *pDisplay;

	XFontStruct *pFontInfoStruct;

#elif BEOS
	BView*	pView;
	BFont	font;
	void lineFromTo (CPoint& cstart, CPoint& cend);

#endif
};


//-----------------------------------------------------------------------------
// COffscreenContext Declaration
//! A drawing device which uses a pixmap as its drawing surface.
//-----------------------------------------------------------------------------
class COffscreenContext : public CDrawContext
{
public:
	COffscreenContext (CDrawContext *pContext, CBitmap *pBitmap, bool drawInBitmap = false);
	COffscreenContext (CFrame *pFrame, long width, long height, const CColor backgroundColor = kBlackCColor);

	virtual ~COffscreenContext ();
	
	void copyFrom (CDrawContext *pContext, CRect destRect, CPoint srcOffset = CPoint (0, 0));	///< copy from offscreen to pContext
	void copyTo (CDrawContext* pContext, CRect& srcRect, CPoint destOffset = CPoint (0, 0));	///< copy to offscreen from pContext

	inline CCoord getWidth () const { return width; }
	inline CCoord getHeight () const { return height; }

	//-------------------------------------------
protected:
	CBitmap *pBitmap;
	CBitmap *pBitmapBg;
	CCoord    height;
	CCoord    width;
	bool    bDestroyPixmap;

	CColor  backgroundColor;

#if WINDOWS
	void* oldBitmap;

#elif MOTIF
	Display *pXdisplay;

#elif BEOS
	BBitmap *offscreenBitmap;

#elif MAC
	#if QUARTZ
	void* offscreenBitmap;
	virtual CGImageRef getCGImage () const;
	#else
	CGrafPtr getPort ();
	#endif
	BitMapPtr getBitmap ();
	void releaseBitmap ();
#endif
};


//-----------------------------------------------------------------------------
// CBitmap Declaration
//! Encapsulates various platform depended kinds of bitmaps.
//-----------------------------------------------------------------------------
class CBitmap : public CReferenceCounter
{
public:
	CBitmap (long resourceID);	///< Create a pixmap from a resource identifier
	CBitmap (CFrame &frame, CCoord width, CCoord height);	///< Create a pixmap with a given size.
	virtual ~CBitmap ();

	virtual void draw (CDrawContext *pContext, CRect &rect, const CPoint &offset = CPoint (0, 0));	///< Draw the pixmap using a given rect as output position and a given offset of its source pixmap.
	virtual void drawTransparent (CDrawContext *pContext, CRect &rect, const CPoint &offset = CPoint (0, 0));
	virtual void drawAlphaBlend  (CDrawContext *pContext, CRect &rect, const CPoint &offset = CPoint (0, 0), unsigned char alpha = 128);	///< Same as CBitmap::draw except that it uses the alpha value to draw the bitmap alpha blended.

	inline CCoord getWidth () const { return width; }
	inline CCoord getHeight () const { return height; }

	bool isLoaded () const;
	void *getHandle () const;
	
	void setTransparentColor (const CColor color);
	CColor getTransparentColor () const { return transparentCColor; }
	void setTransparencyMask (CDrawContext* pContext, const CPoint& offset = CPoint (0, 0));

	void setNoAlpha (bool state) { noAlpha = state; }
	bool getNoAlpha () const { return noAlpha; }

#if BEOS
	static void closeResource ();
#endif
#if MACX
	#if QUARTZ
	virtual CGImageRef createCGImage (bool transparent = false);
	#endif
#endif

	//-------------------------------------------
protected:
	CBitmap ();

	virtual void dispose ();
	virtual bool loadFromResource (long resourceID);
	virtual bool loadFromPath (const void* platformPath);	// load from a platform path. On Windows it's a C string and on Mac OS X its a CFURLRef.

	long resourceID;
	CCoord width;
	CCoord height;

	CColor transparentCColor;
	bool noAlpha;

#if WINDOWS
	void *pHandle;
	void *pMask;

#elif MOTIF
	void *createPixmapFromXpm (CDrawContext *pContext);

	char    **ppDataXpm;
	Display *pXdisplay;
	void *pHandle;
	void *pMask;

#elif MAC
	void* pHandle;
	void* pMask;
	#if QUARTZ
	void* cgImage;
	#endif
#elif BEOS
	static BResources *resourceFile;
	BBitmap    *bbitmap;
	bool		transparencySet;
#endif
};

enum {
	kMessageUnknown = 0,
	kMessageNotified = 1
};

//-----------------------------------------------------------------------------
// CView Declaration
//-----------------------------------------------------------------------------
class CView : public CReferenceCounter
{
public:
	CView (const CRect &size);
	virtual ~CView ();

	virtual void draw (CDrawContext *pContext);	///< called if the view should draw itself
	virtual void drawRect (CDrawContext *pContext, const CRect& updateRect) { draw (pContext); }	///< called if the view should draw itself
	virtual bool checkUpdate (CRect& updateRect) const { return updateRect.rectOverlap (size); }
	virtual void mouse (CDrawContext *pContext, CPoint &where, long buttons = -1);	///< called if a mouse click event occurs
	
	virtual void setBackground (CBitmap *background);				///< set the background image of this view
	virtual CBitmap *getBackground () const { return pBackground; }	///< get the background image of this view

	virtual long onKeyDown (VstKeyCode& keyCode);	///< called if a key down event occurs and this view has focus
	virtual long onKeyUp (VstKeyCode& keyCode);		///< called if a key up event occurs and this view has focus

	virtual bool onWheel (CDrawContext *pContext, const CPoint &where, float distance);	///< called if a mouse wheel event is happening over this view
	virtual bool onWheel (CDrawContext *pContext, const CPoint &where, const CMouseWheelAxis axis, float distance);	///< called if a mouse wheel event is happening over this view

	virtual bool onDrop (CDrawContext* context, CDragContainer* drag, const CPoint& where) { return false; }	///< called if a drag is dropped onto this view
	virtual void onDragEnter (CDrawContext* context, CDragContainer* drag, const CPoint& where) {}				///< called if a drag is entering this view
	virtual void onDragLeave (CDrawContext* context, CDragContainer* drag, const CPoint& where) {}				///< called if a drag is leaving this view
	virtual void onDragMove (CDrawContext* context, CDragContainer* drag, const CPoint& where) {}				///< called if a drag is current moved over this view

	virtual void looseFocus (CDrawContext *pContext = 0);										///< called if view should loose focus
	virtual void takeFocus (CDrawContext *pContext = 0);										///< called if view should take focus

	virtual bool isDirty () const { return bDirty; }											///< check if view is dirty
	virtual void setDirty (const bool val = true) { bDirty = val; }								///< set the view to dirty so that it is redrawn in the next idle. Thread Safe !
	
	virtual void setMouseEnabled (const bool bEnable = true) { bMouseEnabled = bEnable; }		///< turn on/off mouse usage for this view
	virtual bool getMouseEnabled () const { return bMouseEnabled; }								///< get the state of wheather this view uses the mouse or not

	virtual void setMouseableArea (const CRect &rect)  { mouseableArea = rect; }				///< set the area in which the view reacts to the mouse
	virtual CRect &getMouseableArea (CRect &rect) const { rect = mouseableArea; return rect;}	///< get the area in which the view reacts to the mouse

	virtual bool hitTest (const CPoint& where, const long buttons = -1) { return where.isInside (mouseableArea); }	///< check if where hits this view

	virtual void setTransparency (bool val) { bTransparencyEnabled = val; }			///< set views transparent state
	virtual bool getTransparency () const { return bTransparencyEnabled; }			///< is view transparent ?

	CCoord getHeight () const { return size.height (); }								///< get the height of the view
	CCoord getWidth ()  const { return size.width (); }								///< get the width of the view

	virtual void setViewSize (CRect &rect);											///< set views size
	virtual CRect &getViewSize (CRect &rect) const { rect = size; return rect; }	///< returns the current view size

	virtual bool removed (CView* parent) { return true; }   ///< view is removed from parent view
	virtual bool attached (CView* view) { return true; }    ///< view is attached to a parent view

	virtual void getMouseLocation (CDrawContext* context, CPoint &point);	///< get current mouse location in local view coordinates

	virtual CPoint& frameToLocal (CPoint& point) const;		///< conversion from frame coordinates to local view coordinates
	virtual CPoint& localToFrame (CPoint& point) const;		///< conversion from local view coordinates to frame coordinates

	bool getAttributeSize (const CViewAttributeID id, long& outSize) const;									///< get the size of an attribute
	bool getAttribute (const CViewAttributeID id, const long inSize, void* outData, long& outSize) const;	///< get an attribute
	bool setAttribute (const CViewAttributeID id, const long inSize, void* inData);							///< set an attribute

	CView  *getParentView () const { return pParentView; }
	CFrame *getFrame () const { return pParentFrame; }
	virtual void *getEditor () const;

	virtual long notify (CView* sender, const char* message);
	void redraw ();
	virtual void redrawRect (CDrawContext* context, const CRect& rect);

	virtual bool wantsFocus () const { return bWantsFocus; }			///< check if view supports focus
	virtual void setWantsFocus (bool state) { bWantsFocus = state; }	///< set focus support on/off

	#if DEBUG
	virtual void dumpInfo ();
	#endif

	virtual bool isTypeOf (const char* s) const
		{ return (!strcmp (s, "CView")); }

#if ENABLE_DEPRECATED_METHODS
	// deprecated methods will be placed here, so that people who really need them can turn the macro on

	virtual void setParentView (CView *pParentView) { this->pParentView = pParentView; }  ///< \deprecated
	virtual void setFrame (CFrame *pParent) { this->pParentFrame = pParent; }  ///< \deprecated
	virtual void getFrameTopLeftPos (CPoint& topLeft) const; ///< \deprecated
#endif
	//-------------------------------------------
protected:
	friend class CControl;
	friend class CFrame;
	friend class CViewContainer;

	CRect  size;
	CRect  mouseableArea;

	CFrame *pParentFrame;
	CView  *pParentView;

	bool  bDirty;
	bool  bMouseEnabled;
	bool  bTransparencyEnabled;
	bool  bWantsFocus;
	
	CBitmap* pBackground;
	CAttributeListEntry* pAttributeList;

	virtual void update (CDrawContext *pContext); // don't call this !!!
};

// Message to check if View is a CViewContainer
extern char* kMsgCheckIfViewContainer;

//-----------------------------------------------------------------------------
// CViewContainer Declaration
//! Container Class of CView objects.
//-----------------------------------------------------------------------------
class CViewContainer : public CView
{
public:
	CViewContainer (const CRect &size, CFrame *pParent, CBitmap *pBackground = 0);
	virtual ~CViewContainer ();

	virtual void addView (CView *pView);	///< add a child view
	virtual void addView (CView *pView, CRect &mouseableArea, bool mouseEnabled = true);	///< add a child view
	virtual void removeView (CView *pView, const bool &withForget = true);	///< remove a child view
	virtual void removeAll (const bool &withForget = true);	///< remove all child views
	virtual bool isChild (CView *pView) const;	///< check if pView is a child view of this container
	virtual long getNbViews () const;			///< get the number of child views
	virtual CView *getView (long index) const;	///< get the child view at index

	virtual void setBackgroundColor (const CColor color);	///< set the background color (will only be drawn if this container is not set to transparent and does not have a background bitmap)
	virtual CColor getBackgroundColor () const { return backgroundColor; }	///< get the background color
	virtual void setBackgroundOffset (const CPoint &p) { backgroundOffset = p; }	///< set the offset of the background bitmap
	virtual const CPoint& getBackgroundOffset () const { return backgroundOffset; }	///< get the offset of the background bitmap

	virtual void drawBackgroundRect (CDrawContext *pContext, CRect& _updateRect);	///< draw the background

	enum {
		kNormalUpdate = 0,		///< this mode redraws the whole container if something is dirty
		kOnlyDirtyUpdate		///< this mode only redraws the views which are dirty
	};

	virtual void setMode (long val) { mode = val; }	///< set the update mode
	virtual long getMode () const { return mode; }	///< get the update mode

	virtual void useOffscreen (bool b);	///< turn on/off using an offscreen

	virtual CView *getCurrentView () const;	///< get the current view under the mouse
	virtual CView *getViewAt (const CPoint& where, bool deep = false) const;	///< get the view at point where

	void modifyDrawContext (CCoord save[4], CDrawContext* pContext);
	void restoreDrawContext (CDrawContext* pContext, CCoord save[4]);

	// CView
	virtual void draw (CDrawContext *pContext);
	virtual void drawRect (CDrawContext *pContext, const CRect& updateRect);
	virtual void mouse (CDrawContext *pContext, CPoint &where, long buttons = -1);
	virtual bool onWheel (CDrawContext *pContext, const CPoint &where, float distance);
	virtual bool onWheel (CDrawContext *pContext, const CPoint &where, const CMouseWheelAxis axis, float distance);
	virtual void update (CDrawContext *pContext);
	virtual bool hitTest (const CPoint& where, const long buttons = -1);
	virtual long onKeyDown (VstKeyCode& keyCode);
	virtual long onKeyUp (VstKeyCode& keyCode);
	virtual long notify (CView* sender, const char* message);

	virtual bool onDrop (CDrawContext* context, CDragContainer* drag, const CPoint& where);
	virtual void onDragEnter (CDrawContext* context, CDragContainer* drag, const CPoint& where);
	virtual void onDragLeave (CDrawContext* context, CDragContainer* drag, const CPoint& where);
	virtual void onDragMove (CDrawContext* context, CDragContainer* drag, const CPoint& where);

	virtual void looseFocus (CDrawContext *pContext = 0);
	virtual void takeFocus (CDrawContext *pContext = 0);
	virtual bool advanceNextFocusView (CView* oldFocus, bool reverse = false);

	virtual bool isDirty () const;

	virtual void setViewSize (CRect &rect);

	virtual bool removed (CView* parent);
	virtual bool attached (CView* view);
		
	virtual CPoint& frameToLocal (CPoint& point) const;
	virtual CPoint& localToFrame (CPoint& point) const;

	virtual void redrawRect (CDrawContext* context, const CRect& rect);

	CLASS_METHODS(CViewContainer, CView)

	#if DEBUG
	virtual void dumpInfo ();
	virtual void dumpHierarchy ();
	#endif

	//-------------------------------------------
protected:
	bool hitTestSubViews (const CPoint& where, const long buttons = -1);

	CCView  *pFirstView;
	CCView  *pLastView;
	long mode;
	COffscreenContext *pOffscreenContext;
	CColor backgroundColor;
	CPoint backgroundOffset;
	bool bDrawInOffscreen;

	CView* currentDragView;
};

//-----------------------------------------------------------------------------
// CFrame Declaration
//! The CFrame is the parent container of all views.
//-----------------------------------------------------------------------------
class CFrame : public CViewContainer
{
public:
	CFrame (const CRect &size, void *pSystemWindow, void *pEditor);
	CFrame (const CRect &size, const char *pTitle, void *pEditor, const long style = 0);
	
	virtual ~CFrame ();

	virtual bool open (CPoint *pPoint = 0);
	virtual bool close ();
	virtual bool isOpen () const { return bOpenFlag; }

	virtual void idle ();
	virtual void doIdleStuff ();

	virtual unsigned long getTicks () const;	///< get the current time (in ms)
	virtual long getKnobMode () const;			///< get hosts knob mode

	virtual bool setPosition (CCoord x, CCoord y);
	virtual bool getPosition (CCoord &x, CCoord &y) const;

	virtual bool setSize (CCoord width, CCoord height);
	virtual bool getSize (CRect *pSize) const;
	virtual bool getSize (CRect &pSize) const;

	virtual long   setModalView (CView *pView);
	virtual CView *getModalView () const { return pModalView; }

	virtual void  beginEdit (long index);
	virtual void  endEdit (long index);

	virtual bool  getCurrentLocation (CPoint &where);
	virtual void  setCursor (CCursorType type);

	virtual void   setFocusView (CView *pView);
	virtual CView *getFocusView () const { return pFocusView; }
	virtual bool advanceNextFocusView (CView* oldFocus, bool reverse = false);

	virtual bool setDropActive (bool val);
	virtual bool isDropActive () const { return bDropActive; };

	CDrawContext* createDrawContext ();

	virtual void setOpenFlag (bool val) { bOpenFlag = val;};
	virtual bool getOpenFlag () const { return bOpenFlag; };

	virtual void invalidate (const CRect &rect);

	virtual bool updatesDisabled () const { return bUpdatesDisabled; }
	virtual bool updatesDisabled (bool state) { bool before = bUpdatesDisabled; bUpdatesDisabled = state; return before; }

	#if WINDOWS
	HWND getOuterWindow () const;
	void *getSystemWindow () const { return pHwnd; }
	COffscreenContext* getBackBuffer ();
	#elif BEOS
	void *getSystemWindow () const { return pPlugView; }
	#else
	void *getSystemWindow () const { return pSystemWindow; }
	#endif
	void *getParentSystemWindow () const { return pSystemWindow; }
	void setParentSystemWindow (void *val) { pSystemWindow = val; }

	// CView
	virtual void draw (CDrawContext *pContext);
	virtual void drawRect (CDrawContext *pContext, const CRect& updateRect);
	virtual void draw (CView *pView = 0);
	virtual void mouse (CDrawContext *pContext, CPoint &where, long buttons = -1);
	virtual bool onWheel (CDrawContext *pContext, const CPoint &where, float distance);
	virtual bool onWheel (CDrawContext *pContext, const CPoint &where, const CMouseWheelAxis axis, float distance);
	virtual long onKeyDown (VstKeyCode& keyCode);
	virtual long onKeyUp (VstKeyCode& keyCode);
	virtual void update (CDrawContext *pContext);
	virtual void setViewSize (CRect& inRect);
	virtual CView *getCurrentView () const;

	virtual void *getEditor () const { return pEditor; }

#if MOTIF
	Colormap getColormap ()   const { return colormap; }
	Visual  *getVisual ()     const { return pVisual; }
	unsigned int getDepth ()  const { return depth; }
	Display *getDisplay ()    const { return pDisplay; }
	Window   getWindow ()     const { return window; }
	void     freeGc ();

	Region   region;

	GC       gc;
	GC       getGC ()         const { return gc; }
#endif

	#if DEBUG
	virtual void dumpHierarchy ();
	#endif

	CLASS_METHODS(CFrame, CViewContainer)

	//-------------------------------------------
protected:
	bool   initFrame (void *pSystemWin);

	void   *pEditor;
	
	void    *pSystemWindow;
	CView   *pModalView;
	CView   *pFocusView;

	bool    bFirstDraw;
	bool    bOpenFlag;
	bool    bDropActive;
	bool	bUpdatesDisabled;

#if WINDOWS
	void      *pHwnd;
	HINSTANCE hInstMsimg32dll;
	void*     dropTarget;
	COffscreenContext* backBuffer;

#elif MOTIF
	Colormap  colormap;
	Display  *pDisplay;
	Visual   *pVisual;
	Window    window;
	unsigned int depth;

	friend void _destroyCallback (Widget, XtPointer, XtPointer);

#elif BEOS
	PlugView *pPlugView;
#endif
#if QUARTZ
	void setDrawContext (CDrawContext* context) { pFrameContext = context; }
	friend class CDrawContext;

	static pascal OSStatus carbonEventHandler (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
	bool registerWithToolbox ();
	
	ControlDefSpec controlSpec;
	ControlRef controlRef;
	bool hasFocus;
	EventHandlerRef dragEventHandler;
	public:
	void* getPlatformControl () const { return controlRef; }
	CPoint hiScrollOffset;
	protected:
#endif
	//-------------------------------------------
private:
	CDrawContext *pFrameContext;
	bool     bAddedWindow;
	void     *pVstWindow;
	void     *defaultCursor;
};

//-----------------------------------------------------------------------------
// CDragContainer Declaration
//-----------------------------------------------------------------------------
class CDragContainer : public CReferenceCounter
{
public:
	CDragContainer (void* platformDrag);
	~CDragContainer ();

	void* first (long& size, long& type);		///< returns pointer on a char array if type is known
	void* next (long& size, long& type);		///< returns pointer on a char array if type is known
	
	long getType (long idx) const;
	long getCount () const { return nbItems; }

	enum {
		kFile = 0,
		kText,

		kUnknown = -1
	};

protected:
	void* platformDrag;
	long nbItems;
	
	long iterator;
	void* lastItem;
};

//-----------------------------------------------------------------------------
// CCView Declaration
//-----------------------------------------------------------------------------
class CCView
{
public:
	CCView (CView *pView);
	~CCView ();

	CView    *pView;
	CCView   *pNext;
	CCView   *pPrevious;
};

END_NAMESPACE_VSTGUI

// include the control objects
#ifndef __vstcontrols__
#include "vstcontrols.h"
#endif

USING_NAMESPACE_VSTGUI

//-End VSTGUI.H--------------------------------------
#endif	// __vstgui__
