
//**************************************************************************/
// Copyright (c) 2008 Autodesk, Inc.
// All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
//**************************************************************************/
// DESCRIPTION:
// CREATED: October 2008
//**************************************************************************/

namespace mudbox {

// Remove Linux's system header clashing defines.
#if defined(Bool)
#undef Bool
#endif

enum LinearUnits
{
	eMillimeter,
	eCentimeter,
	eMeter,
	eInch
};

enum SelectionMode
{
	ePaint = 0,
	eRectangle,
	eLasso
};

enum InactiveLevelDisplay
{
	eNone,
	eHide,
	eShade
};

/// \brief Holds Mudbox application preferences. 
/// Most of the data members will be removed from the SDK in future
/// releases. For more information about adding an item to preferences see Preferences::Integer.
class MBDLL_DECL Preferences : public Node
{
	DECLARE_CLASS;
public:
	Preferences( void );
	~Preferences( void );
	void Serialize( Stream & );
	void ProcessLine( QString &sSrc, QString &sName, QString &sValue );
	void SavePaths( void );
	bool LoadPaths( void );
	QString FindSettings( QString &sDir );

	Attribute *RegisterVariable( const QString &sName, const QString &sCategory, Attribute::AttributeType eType, const QString &sDefaultValue );
	inline afloatr *RegisterFloatVariable( const QString &sName, const QString &sCategory, float fDefaultValue ) { return (afloatr *)RegisterVariable( sName, sCategory, Attribute::typeFloat, QString("%1").arg(fDefaultValue) ); };
	inline abool *RegisterBoolVariable( const QString &sName, const QString &sCategory, bool bDefaultValue ) { return (abool *)RegisterVariable( sName, sCategory, Attribute::typeBool, bDefaultValue ? "true" : "false" ); };
	inline astring *RegisterStringVariable( const QString &sName, const QString &sCategory, const QString &sDefaultValue ) { return (astring *)RegisterVariable( sName, sCategory, Attribute::typeString, sDefaultValue ); };
	inline acolor *RegisterColorVariable( const QString &sName, const QString &sCategory, const mudbox::Color &cDefaultValue ) { return (acolor *)RegisterVariable( sName, sCategory, Attribute::typeColor, QString("%1 %2 %3 %4").arg(cDefaultValue.r).arg(cDefaultValue.g).arg(cDefaultValue.b).arg(cDefaultValue.a) ); };
	inline aint *RegisterIntegerVariable( const QString &sName, const QString &sCategory, int iDefaultValue ) { return (aint *)RegisterVariable( sName, sCategory, Attribute::typeInt, QString("%1").arg(iDefaultValue) ); };
	inline avector *RegisterVectorVariable( const QString &sName, const QString &sCategory, const mudbox::Vector &vDefaultValue ) { return (avector *)RegisterVariable( sName, sCategory, Attribute::typeVector, QString("%f %f %f").arg(vDefaultValue.x).arg(vDefaultValue.y).arg(vDefaultValue.z ) ); };
	inline aenum *RegisterEnumVariable( const QString &sName, const QString &sCategory, int iDefaultValue ) { return (aenum *)RegisterVariable( sName, sCategory, Attribute::typeEnum, QString("%1").arg(iDefaultValue) ); };

	void OnNodeEvent( const Attribute &, NodeEventType );

	abool m_bCheckFrustum, m_bMultiThreadRender, m_bHighlightBrushArea;
	aint m_iFastBrushLevel;
	abool m_bFocusWhenEmpty, m_bFocusWhenNotEmpty, m_bZoomWhileFocus;
	abool m_bPickBothSide;
	abool m_bUseVideoMemory, m_bRemoveLevels, m_bRemoveOctree, m_bCreateUVs, m_bSmoothUV, m_bSmoothPos;
	aenum m_eDefaultMaterial;
	abool m_bDisableLODChange;
	abool m_bNoPaintUndo;

	aint m_fMinPenPressure, m_fMaxPenPressure;
	aint m_iGridSize, m_iGridSteps;
	aint m_iDoubleClickTime;
	abool m_bWireOnShaded;
	abool m_bShowPickedFace;
	aint m_iWireLevel;
	aenum m_eImportAutofocus;
	bool m_bFlatLighting;
	bool m_bFacetedShading;
    bool m_bLighting;

	afloatr m_fCameraDollySensitivity;
	afloatr m_fCameraTrackSensitivity;
	afloatr m_fCameraRotateSensitivity;
	
	abool m_bOptimizeMeshes;
	abool m_bShowLayerMask;
	abool m_bUseDraftRender, m_bShowFrozenVertices;
	aint m_iPointRenderRarity;
	aint m_iDraftRenderMinFaceCount;
	abool m_bHUDProjectedSubdiv, m_bHUDSelected, m_bHUDVisible, m_bHUDFPS, m_bHUDRendered;
	aint m_iHUDProjectedXSubdivisionLevel;
	aint m_iMinutesToAlarm, m_iBuildUpRate;
	afloatr m_fPressureTreshold;
	afloatr m_fStencilRotateSensitivity;
	abool m_bForceVidmemRender;
	abool m_bUseLocalYForCameraRotation;
	aenum m_iCameraControlMode;
	afloatr m_fRollArea;
	aint m_iMaximumTextureSize;

	abool m_bSaveIndicator, m_bSelectPicked, m_bLocalFocus;

	aint m_iMirrorPlanes;
	Store<mudbox::Vector> m_aMirrorPlaneNormals;
	Store<mudbox::Vector> m_aMirrorPlanePositions;
	abool m_bMirrorLocal;

	afloatr m_fSmartFocus;
	acolor m_cViewportCenter, m_cViewportTop, m_cViewportBottom, m_cViewportFlat, m_cGrid, m_cGridAxis, m_cLocked;
	acolor m_cSelection, m_cMask, m_cActiveLayer, m_cInactiveLayer, m_cLayerMask;
	acolor m_cSceneInfoBg, m_cFalloffCurve, m_cFalloffHull, m_cFalloffFill;
	aenum m_eUnitLinear;
	aenum m_eFaceSelectionMode, m_eObjectSelectionMode;
	float m_aLinearUnitRates[4];
	astring m_sDefaultObjDir, m_sDefaultMudDir, m_sDefaultStampDir, m_sDefaultStencilDir, m_sDefaultIconDir,
			m_sDefaultImagePlaneDir, m_sDefaultTextureLayerDir, m_sDefaultPSDDir, m_sDefaultSaveScreenDir;
	astring m_sUserName;
	astring m_sLogPath, m_sTempPath, m_sSettingsPath, m_sDataPath;
	astring m_sTexturePath; 
	astring m_sMayaInstallPath; 
#ifdef WantSendToMax
#ifdef WIN32
	astring m_sMaxInstallPath;
#endif
#endif
	abool m_bPathsChanged;
	abool m_bExpertHidesSouth, m_bExpertHidesEast, m_bExpertHidesMenu, m_bExpertHidesStatus;
	aint m_iDragBoxSize;
	abool m_bShowLearningMovies;
	abool m_bShowWelcomeDialog;
	abool m_bHUDInfoMessage;
	abool m_bHUDHelpMessage;
	aenum m_iHelpType;
	astring m_sHelpLocation;
	abool m_bCompressFiles;
	abool m_bOBJThumbnail;
	abool m_bMUDContainsView, m_bMUDContainsBrush;
	abool m_bCull, m_bCreateBackup;
	abool m_bShowTileInfo;
	// map extraction
	//struct MapExtraction
	//{
		aint m_iMapWidth;
		aint m_iMapHeight;
		astring m_sOutputDir;
		abool m_bExtractNormal;
		abool m_bExtractDisplacement;
		abool m_bSmoothNormals;
		aint m_iSmoothLevel;
		aint m_iNormalSpace;
		afloat m_fRayTravel;
		aint m_eRayCenter;
		abool m_bPickBothSides;
		aint m_iEdgeBleed;
		aint m_iNormalFormat;
		aint m_iDisplacementFormat;
		aint m_iSubdivLow;
		astring m_sNormalFileName;
		astring m_sDisplacementFileName;
		abool m_bSkipEmptyMaps;
		aint m_iExtUDim;
		aint m_iUStart;
		abool m_bSelectedFacesOnly;
		astring m_sLowObjectName;
		astring m_sHighObjectName;
		abool m_bInvertTangent;
		abool m_bInvertBinormal;
		afloat m_fAreaTreshold;
	//} m_cMapExtraction;

	//// displacement
	//struct DisplacementPreferences
	//{
		astring m_sTileRange;
		afloat m_fMiddleValue;
		aint m_iFirstTileIndex, m_iDispUDim;
		aint m_iMaskChannel, m_iNegativeDisplacementChannel, m_iPositiveDisplacementChannel;
		aint m_iXSubdivisionLevel;
		astring m_sObjectName;
		astring m_sDisplacementFileMask;
		astring m_sMaskFileMask;
//	} m_cDisplacement;

	aenum m_eTextureRatio;
	afloat m_fTextureRatio;

	avoid m_lExpertModeLabel;
	abool m_bMultisampling;
	astring m_sNextCommand;

	Store<Attribute *> m_aPluginAttributes;

	/// Specifies a distance how far the edge bleeding should go over UV edges during painting.
	afloatr m_fPaintBleedDistance;
	afloatr m_fPaintBrushOffset;
	abool m_bFastDryBrush;
	astring m_sExportFilter;

	abool m_bHideEULANag;

	/// movie-recording preferences
	aint m_movieWidth;
	aint m_movieHeight;
	aint m_movieRecordFps;
	aint m_moviePlaybackFps;
	abool m_moviePauseWhenIdle;
	abool m_movieUses3dView;

	/// \brief This class holds a simple integer preference.
	///
	/// This class can be used by a plugin to declare a single integer preference. The object should be 
	/// declared as a global variable or as a static member variable. If a valid name is given to the object
	/// it will autoatically appear in the preferences dialog, and its value will be automatically saved and
	/// restored when mudbox quits/restarts. Example:
	/// \code
	/// Preferences::Integer g_iMaxlevel( "Maximum level", "Render", 4 );
	/// \endcode
	class MBDLL_DECL Integer
	{
	public:
		Integer( 
			const QString &sName, ///< Name of the item, which will appear in the preferences dialog.
			const QString &sCategory, ///< Category of the item, which it belongs to in the preferences dialog. This can be an empty string.
			unsigned int iDefaultValue ///< Default value of the item. This is only used the first time when the preference is used, in other cases the value of the preferences will be restored from the general mudbox preference file.
			);
		operator unsigned int( void ) const;
		aint *m_pAttribute;
	};
	/// This class is a simple boolean preference, appears as a checkbox. See Preferences::Integer for details.
	class MBDLL_DECL Bool
	{
	public:
		Bool( const QString &sName, const QString &sCategory, bool bDefaultValue );
		operator bool( void ) const;
		abool *m_pAttribute;
	};
	/// This class represents a float value, appears as an editbox and a slider. See Preferences::Integer for mode details.
	class MBDLL_DECL Float
	{
	public:
		Float( const QString &sName, const QString &sCategory, float fDefaultValue, float fMinimum, float fMaximum );
		operator float( void ) const;
		afloatr *m_pAttribute;
	};
	/// This class represents a string preference value. See Preferences::Integer for mode details.
	class MBDLL_DECL String
	{
	public:
		String( const QString &sName, const QString &sCategory, const QString &sDefaultValue );
		operator QString( void ) const;
		astring *m_pAttribute;
	};
	/// This class represents a color item in the preferences. See Preferences::Integer for mode details.
	class MBDLL_DECL Color
	{
	public:
		Color( const QString &sName, const QString &sCategory, const mudbox::Color &cDefaultValue );
		operator mudbox::Color( void ) const;
		acolor *m_pAttribute;
	};
	/// This class represents a 3d vector item. See Preferences::Integer for mode details.
	class MBDLL_DECL Vector
	{
	public:
		Vector( const QString &sName, const QString &sCategory, const mudbox::Vector &vDefaultValue );
		operator mudbox::Vector( void ) const;
		avector *m_pAttribute;
	};
	/// This class represents a enum item, appears as a combo box. See Preferences::Enum for mode details.
	class MBDLL_DECL Enum
	{
	public:
		Enum( const QString &sName, const QString &sCategory, int iDefaultValue );
		operator int( void ) const;
		aenum *m_pAttribute;
	};

	private:
		QString m_sUserPath;
};

}; // end of namespace mudbox
