//
//	Copyright © 2006 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#ifndef VECTORWORKS_PLUGIN_TOOL_APPLICATION__H
#define VECTORWORKS_PLUGIN_TOOL_APPLICATION__H

#pragma once

#include "VWFC/PluginSupport/VWPluginToolCustomBar.h"

namespace VWFC
{
	namespace PluginSupport
	{
		// ---------------------------------------------------------------------------
		enum EStandardCursor {
			kStandardCursor_Arrow			= 147,
			kStandardCursor_ArrowShort		= 140,
			kStandardCursor_ArrowDiagonal	= 107,
			kStandardCursor_FourArrows		= 93,
			kStandardCursor_HandFinger		= 304,
			kStandardCursor_HandLeft		= 104,
			kStandardCursor_Hand			= 145,
			kStandardCursor_CrossSmall		= 103,
			kStandardCursor_CrossBig		= 105,
			kStandardCursor_CrossBigDashed	= 106,
			kStandardCursor_CrossBezier		= 330,
			kStandardCursor_CrossCubic		= 331,
			kStandardCursor_CrossArc		= 332,
			kStandardCursor_Target			= 154,
			kStandardCursor_Bucket			= 126,
			kStandardCursor_Pipette			= 442
		};

		// ---------------------------------------------------------------------------
		typedef		long			TToolStatus;
		class IToolStatusProvider
		{
		public:
			virtual					~IToolStatusProvider() {}
			virtual	TToolStatus		GetOnePointToolStatus() const = 0;
			virtual TToolStatus		GetTwoPointToolStatus() const = 0;
			virtual TToolStatus		GetThreePointToolStatus() const = 0;
			virtual TToolStatus		GetPolyToolStatus() const = 0;
			virtual TToolStatus		GetClickDragToolStatus() const = 0;
		};

		// ---------------------------------------------------------------------------
		class IToolModeBarProvider
		{
		public:
			virtual				~IToolModeBarProvider() {}
			virtual void		EnableModeGroup(size_t modeGroupID, bool bEnable) const = 0;
			virtual void		SetHelpString(const TXString& helpMessage) const = 0;
			virtual SInt32		GetModeGroupValue(size_t modeGroupID) const = 0;
			virtual void		SetModeGroupValue(size_t modeGroupID, SInt32 value) const = 0;
			virtual void		InsertPullDownMenuItem(size_t modeGroupID, const TXString& text) const = 0;
			virtual void		SetPullDownMenuSelection(size_t modeGroupID, size_t selection) const = 0;
		};

		// ---------------------------------------------------------------------------
		class IToolModeBarInitProvider : public IToolModeBarProvider
		{
		public:
			virtual				~IToolModeBarInitProvider() {}
			virtual void		AddButtonModeGroup(short ICNRes) const = 0;
			virtual void		AddCheckModeGroup(short ICNRes, bool initState) const = 0;
			virtual void		AddPullDownMenuModeGroup(const TXString& label) const = 0;
			virtual void		AddRadioModeGroup(size_t initState, size_t btnCnt, short id1, short id2, short id3=0, short id4=0, short id5=0, short id6=0 ) const = 0;
			virtual void		AddTextButtonModeGroup(const TXString& text) const = 0;
		};

		// ---------------------------------------------------------------------------
		class IToolDrawProvider
		{
		public:
			virtual				~IToolDrawProvider() {}

			// default drawing
			virtual void		DrawDefaultRect() const = 0;
			virtual void		DrawDefault2D() const = 0;
			virtual void		DrawDefault3D() const = 0;

			// simple drawing
			virtual void		DrawLine2D(const VWLine2D& line) const = 0;
			virtual void		DrawLine3D(const VWLine3D& line) const = 0;
			virtual void		DrawRect(const VWRectangle2D& rect) const = 0;
			virtual void		DrawArc(const VWArc2D& arc) const = 0;
			virtual void		DrawEllipse(const VWRectangle2D& rect) const = 0;

			// poly drawing
			virtual void		DrawPolyBegin() = 0;
			virtual void		DrawPoly_AddCornerVertex(const VWPoint2D& pt) = 0;
			virtual void		DrawPoly_AddBezierVertex(const VWPoint2D& pt) = 0;
			virtual void		DrawPoly_AddCubicVertex(const VWPoint2D& pt) = 0;
			virtual void		DrawPoly_AddArcVertex(const VWPoint2D& pt, double dRadius) = 0;
			virtual void		DrawPolyEnd() = 0;
			virtual void		DrawPolyEnd(const VWTransformMatrix& matrix) = 0;

			// object drawing
			virtual void		DrawObject(MCObjectHandle hObj, bool bDoSelect) const = 0;
			virtual void		DrawNurbsObject(MCObjectHandle hNurbsObj) const = 0;
			virtual void		DrawDataDisplayBar(bool bDrawFramesFirst = false) const = 0;

			// attributes
			virtual void		SetPenSize(short penSize = 0) const = 0;
			virtual void		SetPenPattern(short penPatIndex = 2) const = 0;
		};

		// ---------------------------------------------------------------------------
		class IToolPropertiesProvider
		{
		public:
			virtual				~IToolPropertiesProvider() {}
			virtual bool		SetProperty(long propID, bool bValue) = 0;
			virtual bool		SetPropertyChar(long propID, char value) = 0;
		};

		// ---------------------------------------------------------------------------
		class VWPluginToolApp
		{
		public:
									VWPluginToolApp();
			virtual					~VWPluginToolApp();

			void					SetToolModeBarProvider(IToolModeBarProvider* pModeBarProvider);

			long					GetResult() const;
			void					SetResult(long result);

		public:
			virtual bool			InitializeApp();
			virtual void			DeinitializeApp();

			virtual long			GetUserData() const;
			virtual void			SetUserData(long userData);

			virtual TXString		GetContextualHelpID() const;
			virtual	void			OnInitXProperties(const IToolPropertiesProvider* pPropsProvider);

			virtual void			OnSelectionChange();
			virtual void			OnCustomBar_Setup();
			virtual void			OnCustomBar_Setdown();
			virtual void			OnCustomBar_UpdateValues();
			virtual void			OnCustomBar_LockValue(size_t fieldIndex, const TXString& userString);
			virtual void			OnCustomBar_UnlockValue(size_t fieldIndex);

			// When tool is selected or resumed
			virtual bool			DoSetUp(bool bRestore, const IToolModeBarInitProvider* pModeBarInitProvider);
			// When tool is deselected	or paused
			virtual void			DoSetDown(bool bRestore, const IToolModeBarInitProvider* pModeBarInitProvider);
			virtual void			DoDrawScrMod();
			virtual void			DoUndrawScrMod();

			// init the tool data for creation of the specified object
			virtual void			OnToolInitByObject(MCObjectHandle hObject, const IToolModeBarProvider* pModeBarInitProvider);

			// When tool selected and curs in doc
			virtual long			GetCursor();
			// When app needs tool's status
			virtual TToolStatus		GetStatus(const IToolStatusProvider* pStatusProvider);

			// When mouse is clicked in drawing
			virtual void			PointAdded();
			// When app removes a point
			virtual void			PointRemoved(bool bClearAllPts);
			// Whenever tool needs to draw
			virtual void			Draw(IToolDrawProvider* pDrawProvider)		= 0;
			// When mouse moves in drawing
			virtual void			MouseMove();
			// When tool is done getting points
			virtual void			HandleComplete() = 0;

			// When mouse is clicked in mode bar
			virtual void			DoModeEvent(size_t modeGroupID, size_t newButtonID, size_t oldButtonID);
			// When tool is double-clicked
			virtual void			DoDoubleClick();
			// When double-click in drawing
			virtual bool			DrawingDoubleClick();
			// After every key event.
			virtual void			GenericStateChange();

			// The default event notificaiotn
			// if no virutal is present for an event, this function is called to allow the user to catch everything
			virtual long			OnDefaultEvent(long action, long message1, long message2);

		// tool points
		public:
			size_t					GetToolPointsCount() const;
			void					ClearAllToolPoints();
			VWPoint2D				GetToolPt2D(size_t ptIndex) const;
			VWPoint3D				GetToolPt3D(size_t ptIndex) const;
			bool					GetToolPtCurren2D(VWPoint2D& outPt) const;
			bool					GetToolPtCurren3D(VWPoint3D& outPt) const;
			bool					PopLastToolPt();

		// hot spot points
		public:
			long					HotSpotAdd(HotSpotType type, const VWPoint3D& pt, long cursorID);
			long					HotSpotAdd(HotSpotType type, const VWPoint3D& pt, long cursorID, const TXString& strTip);
			long					HotSpotTrack(bool& bOutIs3D, VWPoint3D& outLocation);
			void					HotSpotRemove(long hotSpotID);

		// snap geometry
		public:
			long					SnapGeometryAdd(MCObjectHandle hSnapGeometry);
			void					SnapGeometryRemove(long snapGeometryID);

		protected:
			IToolModeBarProvider*	fpModeBarProvider;
			long					fResult;
		};
	}
}

// ------------------------------------------------------------------------------
#define	INSTANTIATE_TOOL_APP(T)	VWFC::PluginSupport::VWPluginToolApp* CreateToolInstance()  { void* pRawMem = malloc( sizeof(T) ); return (T*) new (pRawMem) T(); }

#endif // VECTORWORKS_PLUGIN_TOOL_APPLICATION__H