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

#pragma once

#include "VWFC/PluginSupport/VWPluginToolApp.h"

namespace VWFC
{
	namespace PluginSupport
	{

		// ------------------------------------------------------------------------------------------------------------------
		class CDrawProvider : public VWFC::PluginSupport::IToolDrawProvider
		{
		public:
								CDrawProvider();

		public:
			// default drawing
			virtual void		DrawDefaultRect() const;
			virtual void		DrawDefault2D() const;
			virtual void		DrawDefault3D() const;

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

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

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

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

		protected:
			struct SPolyVertex {
				int				fType;
				int				fTypeOriginal;
				VWPoint2D		fPt;
				VWPoint2D		fControlPt;
				double			fdRadius;
			};

			typedef std::vector<SPolyVertex>		TPointsArray;

		protected:
			void				RenderPolyline(TPointsArray& arrVertices);
			void				DisplaySplineSubSection(const VWPoint2D &v1, const VWPoint2D &v2, const VWPoint2D &v3, short level );
			void				CalculatePolyline(TPointsArray& arrVertices);
			void				SwapControlPts(TPointsArray& arrVertices);
			void				DrawPolyVert(const SPolyVertex& lastVert, const SPolyVertex& thisVert, const SPolyVertex& nextVert );
			void				DisplayArc(const VWPoint2D& lastPt, const VWPoint2D& thisPt, const VWPoint2D& nextPt);
			bool				CalcChamfer(const VWPoint2D& pt1, const VWPoint2D& int0Value, const VWPoint2D& pt4, VWPoint2D& lastCam, VWPoint2D& thisCam, VWPoint2D& center, double& radius, double &lastAngle, double &thisAngle);
			void				InterLoc(const VWPoint2D& a1, const VWPoint2D& a2, const VWPoint2D& b1, const VWPoint2D& b2, bool& intersect, bool& parallel, VWPoint2D& int0);
			void				DisplayArc(const VWPoint2D &lastPt, const VWPoint2D &/*thisPt*/, const VWPoint2D &nextPt, double radius, VWPoint2D& lastCam, VWPoint2D& thisCam, VWPoint2D& center, double myStart, double myArc);
			void				SegmentArc(double inMyStart, double inMyArc, const VWPoint2D& cen, double radius );
			void				RenderArc(double arcStart, double arcEnd, short currentLevel, const VWPoint2D& cen, double radius);
			VWPoint2D			NextLoc(double a, const VWPoint2D& cen, double radius);

			void				PolyRenderDrawLine(const VWLine2D& line) const;

		protected:
			TPointsArray		farrPoints;

			// current point while rendering polyline
			VWPoint2D			fCurrPolyPt;

			bool				fbPoly3DRender;
			VWTransformMatrix	fPoly3DMatrix;
		};

		// ------------------------------------------------------------------------------------------------------------------
		class CStatusProvider : public VWFC::PluginSupport::IToolStatusProvider
		{
		public:
			virtual	VWFC::PluginSupport::TToolStatus		GetOnePointToolStatus() const;
			virtual VWFC::PluginSupport::TToolStatus		GetTwoPointToolStatus() const;
			virtual VWFC::PluginSupport::TToolStatus		GetThreePointToolStatus() const;
			virtual VWFC::PluginSupport::TToolStatus		GetPolyToolStatus() const;
			virtual VWFC::PluginSupport::TToolStatus		GetClickDragToolStatus() const;
		};

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

		// ------------------------------------------------------------------------------------------------------------------
		class CModeBarInitProvider : public  VWFC::PluginSupport::IToolModeBarInitProvider
		{
		public:
			virtual void		AddButtonModeGroup(short ICNRes) const;
			virtual void		AddCheckModeGroup(short ICNRes, bool initState) const;
			virtual void		AddPullDownMenuModeGroup(const TXString& label) const;
			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;
			virtual void		AddTextButtonModeGroup(const TXString& text) const;

			virtual void		EnableModeGroup(size_t modeGroupID, bool bEnable) const;
			virtual void		SetHelpString(const TXString& helpMessage) const;
			virtual SInt32		GetModeGroupValue(size_t modeGroupID) const;
			virtual void		SetModeGroupValue(size_t modeGroupID, SInt32 value) const;
			virtual void		InsertPullDownMenuItem(size_t modeGroupID, const TXString& text) const;
			virtual void		SetPullDownMenuSelection(size_t modeGroupID, size_t selection) const;
		};


		// ------------------------------------------------------------------------------------------------------------------
		class CToolPropertiesProvider : public VWFC::PluginSupport::IToolPropertiesProvider
		{
		public:
								CToolPropertiesProvider(long codeRefID);
			virtual bool		SetProperty(long propID, bool bValue);
			virtual bool		SetPropertyChar(long propID, char value);
		private:
			long fCodeRefID;
		};

	}
}