//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 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.   
//
//////////////////////////////////////////////////////////////////////////////

#ifndef ACMTITLE_H
#define ACMTITLE_H

#include "rxsrvice.h"
#include "gepnt3d.h"
#include "dbid.h"
#include "dbidar.h"

class AcMgTitleBorder;
class AcMgTitleSetting;
class AcMgTitleSpaceIterator;
class AcMgTitleBorderMgr;
class AcMgTitleOpSettings;
class AcMgTitleDatum;
class AcMgTitleEventReactor;

class AcDbBlockTableRecord;
class AcDbExtents;

#ifdef AMGTITLEBUILD
#define AMGTITLE_DLLSHARE __declspec(dllexport)
#else
#define AMGTITLE_DLLSHARE __declspec(dllimport)
#endif

#ifdef AMGTITLE_CRX_BUILD
#define AMGTITLE_CRX_DLLSHARE __declspec(dllexport)
#else
#define AMGTITLE_CRX_DLLSHARE __declspec(dllimport)
#endif

///<summary><para>This abstract class provides the following general functions: </para>
///<para>1. Create, delete and get title border object </para>
///<para>2. Instantiate the below abstract classes </para>
///<para>3. Add and remove event reactor</para></summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleBorderMgr : public AcRxService
{
public:
  ///<summary>There is no implementation for the destructor.</summary>
  virtual ~AcMgTitleBorderMgr(){}
  ///<summary>Deletes the title border object given by object id from the drawing.</summary>
  virtual bool DeleteTitleBorder(AcDbObjectId) = 0;
  ///<summary>Allocates an AcMgTitleBorder object from "unresolved" object id.</summary>
  virtual AcMgTitleBorder* GetTitleBorderFromRef(AcDbObjectId&) = 0;
  ///<summary>Allocates an AcMgTitleBorder object from a title border object in the drawing given by objid.</summary>
  virtual AcMgTitleBorder* GetTitleBorderFromObj(const AcDbObjectId) = 0;
  ///<summary>Function creates new Title-Border-Object in current space and returns the object id for the Genius object constituting the title-border-object.</summary>
  virtual AcDbObjectId CreateTitleBorder(AcMgTitleBorder *pTB = NULL,
  AcMgTitleOpSettings *pSet = NULL,AcDbDatabase *pDb = NULL) = 0;
  ///<summary>Allocates an instance of AcMgTitleBorder and fills it with default settings of the specified drawing.</summary>
  virtual AcMgTitleBorder *NewDescriptor(AcDbDatabase *pDb = NULL) = 0;
  ///<summary>Allocates a new instance of AcMgTitleOpSettings and fills it with the default settings of this drawing.</summary>
  virtual AcMgTitleOpSettings *NewContext(bool bNewTB = true,AcDbDatabase *pDb = NULL) = 0;
  ///<summary>The iterator iterates a given space for AmgTitleBorder objects.</summary>
  virtual AcMgTitleSpaceIterator *newAmgTitleSpaceIterator() = 0;
  ///<summary>Allocates a new instance of AcMgTitleDatum of string type.</summary>
  ///<param name="key">The used key of the data element</param>
  ///<param name="cval">The string value </param>
  virtual AcMgTitleDatum *NewDatum(const TCHAR *key, const TCHAR *cval)= 0;
  ///<summary>Allocates a new instance of AcMgTitleSetting.</summary>
  virtual AcMgTitleSetting *NewSetting() = 0;
  ///<summary>Adds an event reactor to handle all title/border events</summary>
  virtual void addEventReactor( AcMgTitleEventReactor* pReac ) = 0;
  ///<summary>removes the event reactor</summary>
  virtual void removeEventReactor() = 0;
};

///<summary>This is the interface class for handling all the settings for the title/border.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleOpSettings
{
public:      
  ///<summary>returns the scale setting as a reference to a AcMgTitleSetting object.</summary>
  virtual const AcMgTitleSetting&   Scale()      const = 0;
  ///<summary>returns the Border setting.</summary>
  virtual const AcMgTitleSetting&   Border()     const = 0;
  ///<summary>Returns the TitleBlock setting.</summary>
  virtual const AcMgTitleSetting&   TitleBlock() const = 0;
  ///<summary>returns the setting, if selecttion set should be moved after insertion of the title/border</summary>
  virtual const AcMgTitleSetting&   Move()       const = 0;
  ///<summary>returns the setting, if all layers should be thaw before select sset for move/rescale</summary>
  virtual const AcMgTitleSetting&   Thaw()       const = 0;
  ///<summary>returns the setting, if the base scale for the drawing should be set according the scale of title/border object</summary>
  virtual const AcMgTitleSetting&   baseScale()  const = 0;
  ///<summary>returns the setting, if default settings of the drawing should be set</summary>
  virtual const AcMgTitleSetting&   dwgDefaultSet()      const = 0;
  ///<summary>returns the setting, if the selected sset should automatic be placed after insertin of title/border</summary>
  virtual const AcMgTitleSetting&   automaticPlacement() const = 0;
  ///<summary>return the setting, if rescale should be performed after insertion of title/border</summary>
  virtual const AcMgTitleSetting&   Rescale()  const = 0;
  ///<summary>returns the setting, if some special title block attributes should be filled from a part reference</summary>
  virtual const AcMgTitleSetting&   Retrieve() const = 0;
  ///<summary>returns the setting, if some special title block attributes should be filled from assembly properties.</summary>
  virtual const AcMgTitleSetting&   RetrieveA() const = 0;
  virtual const AcMgTitleSetting&   Additional(int iIndex) const = 0;
  virtual bool setAdditional(const AcMgTitleSetting&,bool check = true,int iIndex = 0) = 0;
  ///<summary>sets the scale setting via an AcMgTitleSetting parameter.</summary>
  virtual bool setScale(const AcMgTitleSetting& set,bool check = true) = 0;
  ///<summary>sets the scale setting via an AcMgTitleSetting parameter.</summary>
  virtual bool setScale(const TCHAR *pscale, bool check = true) = 0;
  ///<summary>sets the border setting via an AcMgTitleSetting parameter</summary>
  virtual bool setBorder(const AcMgTitleSetting&,bool check = true) = 0;
  ///<summary>sets the title setting via an AcMgTitleSetting parameter</summary>
  virtual bool setTitleBlock(const AcMgTitleSetting&,bool check = true) = 0;
  ///<summary>Sets the setting for move objects</summary>
  virtual bool setMove(const AcMgTitleSetting&) = 0;
  virtual bool setMoveObjects(const AcDbObjectIdArray&, const AcGePoint3d&) = 0;
  ///<summary>sets the setting for thaw all layers</summary>
  virtual bool setThaw(const AcMgTitleSetting&) = 0;
  ///<summary>sets the setting for set base scale</summary>
  virtual bool setBaseScale(const AcMgTitleSetting&) = 0;
  ///<summary>sets the setting for drawing defaults</summary>
  virtual bool setDwgDefaultSet(const AcMgTitleSetting&) = 0;
  ///<summary>sets the setting for automatc placement.</summary>
  virtual bool setAutomaticPlacement(const AcMgTitleSetting&) = 0;
  ///<summary>set the setting for rescale</summary>
  virtual bool setRescale(const AcMgTitleSetting&) = 0;
  ///<summary>Set the setting for retrieving attributes from part reference</summary>
  virtual bool setRetrieve(const AcMgTitleSetting&) = 0;
  virtual bool setRetrievePartRef(const AcDbObjectId&) = 0;
  ///<summary>set the setting for retrieving attributes from assembly properties of the main BOM.</summary>
  virtual bool setRetrieveA(const AcMgTitleSetting&) = 0;
  ///<summary>This function determines if the move option is active in a subsequent dialogue or disabled</summary>
  virtual bool enableMove(bool bMovEn = true) = 0;
  ///<summary>Determines if insertion point may be specified by the user manually.</summary>
  virtual bool enablePosInput(bool bPosEn = true) = 0;
  ///<summary>Determines if title block name or alias may be entered by user</summary>
  virtual bool enableTitleInput(bool bTitleEn = true) = 0;
  ///<summary>Determines whether border block name or alias may be entered by user</summary>
  virtual bool enableBorderInput(bool bBorderEn = true) = 0;
  ///<summary>Determines if attribute input is allowed after insertion of title/border</summary>
  virtual bool enableAttrInput(bool bAttEn = true) = 0;
  ///<summary>Determines if scale may be entered by user.</summary>
  virtual bool enableScaleInput(bool bScaleEn = true) = 0;
  ///<summary>Determines if user entry is allowed for insertion point, title block and border name, attribute input and scale input.</summary>
  virtual bool enableUserInput(bool bUserEn = true) = 0;
  ///<summary>returns if insertion point may be specified by the user manually.</summary>
  virtual bool PosInput() = 0;
  ///<summary>returns if attribute input is allowed after insertion of title/border</summary>
  virtual bool AttrInput() = 0;
  ///<summary>Returns if user entry is allowed.</summary>
  virtual bool userInput() const = 0;
  ///<summary>Returns the list of objects selected to be moved and destination point.</summary>
  virtual bool movedObjects(AcDbObjectIdArray& objIds, AcGePoint3d& toPts) const = 0;
  ///<summary>Returns the object id of the selected part reference to retrieve attribute from.</summary>
  virtual const AcDbObjectId retrievedPartRef() const = 0;
  virtual void addRef() = 0;
  virtual void release() = 0;
protected:
  virtual ~AcMgTitleOpSettings(){}
};

///<summary>This is the interface class for handling one of the settings for the title/border.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleSetting
{
public:
  virtual ~AcMgTitleSetting(){}
  virtual bool isVisible() const = 0;
  ///<summary>returns true, if the option is enabled for dialog box input</summary>
  virtual bool hasWriteAccess() const = 0;
  ///<summary>returns the value as a VARIANT</summary>
  virtual VARIANT& value() const = 0;
  virtual void setVisible(bool) = 0;
  ///<summary>Determines if the option should be enabled or disabled for dialog box input</summary>
  virtual bool setWriteAccess(bool) = 0;
  ///<summary>set value of the setting from a double parameter</summary>
  virtual bool setValue(VARIANT&) = 0;
  ///<summary>set value of the setting from a double parameter</summary>
  virtual bool setValue(const TCHAR *) = 0;
  ///<summary>set value of the setting from a double parameter</summary>
  virtual bool setValue(bool) = 0;
  ///<summary>set value of the setting from a double parameter</summary>
  virtual bool setValue(double) = 0;
};

///<summary>This is the interface class for handling data stored in the title block or drawing border.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleDatum
{
public:
  virtual ~AcMgTitleDatum(){}
  ///<summary>returns the string representing the key of the data element</summary>
  virtual CString key() const = 0;
  ///<summary>set the key of the data element</summary>
  virtual void setKey(const TCHAR *) = 0;
  ///<summary>return whether the data element is write protected</summary>
  virtual bool IsProtected() = 0;
  ///<summary>determines whether the data element is protected</summary>
  virtual void Protect(bool) = 0;
  ///<summary>returns a bool if the datum was changed</summary>
  virtual bool isChanged() = 0;
};

///<summary>This is the interface class for handling strings stored in the title block or drawing border.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleString : public AcMgTitleDatum
{
public:
  ///<summary>returns the string representing the key of the data element</summary>
  virtual CString key() const = 0;
  ///<summary>set the key of the data element</summary>
  virtual void setKey(const TCHAR *) = 0;
  ///<summary>return whether the data element is write protected</summary>
  virtual bool IsProtected() = 0;
  ///<summary>determines if the data element is protected</summary>
  virtual void Protect(bool) = 0;
  ///<summary>returns a pointer to a copy of the string value</summary>
  virtual TCHAR *value() = 0;
  ///<summary>set the string value of the string datum</summary>
  virtual void setValue(const TCHAR *pVal) = 0;
  ///<summary>returns a bool if the datum was changed</summary>
  virtual bool isChanged() = 0;
};

///<summary>This is the interface class for handling doubles stored in the title block or drawing border.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleReal : public AcMgTitleDatum
{
public:
  ///<summary>returns the string representing the key of the data element</summary>
  virtual CString key() const = 0;
  ///<summary>set the key of the data element</summary>
  virtual void setKey(const TCHAR *) = 0;
  ///<summary>return whether the data element is write protected</summary>
  virtual bool IsProtected() = 0;
  ///<summary>determines whether the data element is protected</summary>
  virtual void Protect(bool) = 0;
  ///<summary>returns a value (double)</summary>
  virtual double value() const = 0;
  ///<summary>set the double value of the real datum</summary>
  virtual void setValue(double) = 0;
  ///<summary>a bool if the datum was changed</summary>
  virtual bool isChanged() = 0;
};

///<summary>This is the interface class for iterator of AcMgTitleDatum object.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleDataIterator
{
public:
  virtual ~AcMgTitleDataIterator(){}
  ///<summary>looks if iteration must be continued</summary>
  virtual bool next() = 0;
  ///<summary>sets the pointer to the first AcMgTitleDatum</summary>
  virtual bool toFirst() = 0;
  ///<summary>returns pointer to current AcMgTitleDatum</summary>
  virtual AcMgTitleDatum* const & current() const = 0;
  ///<summary>returns the key of the current datum</summary>
  virtual CString key() = 0;
};

///<summary>This is the interface class for a title/border component object.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleComp
{
public:
  virtual    ~AcMgTitleComp(){}
  ///<summary>returns the block name of a title or border block (possible with full path but without extension DWG)</summary>
  virtual    const CString& Name() const = 0;
  ///<summary>set the block name of a title or border block</summary>
  virtual    void setName(const CString& szName, bool check = true) = 0;
  ///<summary>returns a data element of the component via input the key</summary>
  virtual    AcMgTitleDatum* datumAt(const TCHAR *key) = 0;
  ///<summary>removes one data element by given key from the data list of the component</summary>
  virtual    Acad::ErrorStatus removeDatum(const TCHAR *key) = 0;
  ///<summary>add a data element to the data list of the component</summary>
  virtual    Acad::ErrorStatus insertDatum(AcMgTitleDatum* datum) = 0;
  ///<summary>returns a pointer to a iterator, which gives the possibility to iterate through the all data elements of the component</summary>
  virtual    AcMgTitleDataIterator *newIterator() = 0;
  ///<summary>checks if the data list of the component is empty (returns true in this case)</summary>
  virtual    bool isDataEmpty() = 0;
  ///<summary>function initializes data list of the component from definitions of the components components block</summary>
  virtual    int InitDatafromCompDef() = 0;
  ///<summary>returns the Object Id of the entity representing the component</summary>
  virtual    AcDbObjectId ObjectId() = 0;
  ///<summary>Function deactivates a component</summary>
  virtual    Acad::ErrorStatus deactivate(AcDbObjectId ObjId = AcDbObjectId::kNull) = 0;
  ///<summary>returns the position of component in WCS</summary>
  virtual    Acad::ErrorStatus getPosition(AcGePoint3d&) = 0;
  ///<summary>returns the count data items of the component</summary>
  virtual    int DataCount() = 0;
  ///<summary>remove all data items of the component</summary>
  virtual    void removeAllData() = 0;
};

///<summary>This is the interface class for a border component object.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgBorder :  public AcMgTitleComp                       
{
  virtual ~AcMgBorder(){}
};

///<summary>This is the interface class for a title component object.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitle : public AcMgTitleComp
{
  virtual ~AcMgTitle(){}
};

///<summary>This is the interface class for a title/border object.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleBorder 
{
public:
  ///<summary>Inserts a title/border object into the current space.</summary>
  virtual Acad::ErrorStatus appendToSpace(AcDbBlockTableRecord* pBTR = NULL, 
    AcMgTitleOpSettings* pSettings = NULL,
    bool userAction = false,
    AcDbDatabase *pDb = NULL) = 0;
  ///<summary>Enables modification of an existing title/border object.</summary>
  virtual Acad::ErrorStatus modify(AcMgTitleOpSettings *pSet = NULL,
    bool  userAction = false) = 0;
  ///<summary>Deactivates the title object currently use for this title/border object, if the pTitle is NULL.</summary>
  virtual Acad::ErrorStatus deactivateTitle(AcMgTitle *pTitle = NULL) = 0;
  ///<summary>Activates the title component currently used in the title border object.</summary>
  virtual Acad::ErrorStatus activateTitle() = 0;
  ///<summary>returns if the title block is deactivated</summary>
  virtual bool IsTitleDeactivated() = 0;
  ///<summary>returns the title component object of the title/border object.</summary>
  virtual AcMgTitle& title() = 0;
  virtual AcMgTitle& additional(int iIndex) = 0;
  ///<summary>returns the Border component object of the title/border object.</summary>
  virtual AcMgBorder& border() = 0;
  ///<summary>returns the Border component object of the title/border object.</summary>
  virtual double scale() = 0;
  ///<summary>set the scale value for title/border object</summary>
  virtual void setScaleVal(double) = 0;
  ///<summary>returns the object Id of title/border object (refers to the objecter object)</summary>
  virtual AcDbObjectId GetObjectId() = 0;
  ///<summary>Give the possibility to define a position for title/border.</summary>
  virtual void setPosition(AcGePoint3d) = 0;
  ///<summary>returns the position of border in WCS</summary>
  virtual Acad::ErrorStatus getPosition(AcGePoint3d&) = 0;
  ///<summary>edit the data of title/ border object</summary>
  virtual Acad::ErrorStatus editAttr() = 0;
  ///<summary>Increase the reference member, which shows how often clients hold references to this object.</summary>
  virtual void addRef() = 0;
  ///<summary>Decrease the the reference member.</summary>
  virtual void release() = 0;
  ///<summary>returns the extents of border</summary>
  virtual void GetExtents(AcDbExtents&) = 0;
  ///<summary>returns the object Id of layout where the title/border is inserted</summary>
  virtual AcDbObjectId GetLayoutId() const = 0;
protected:
  ///<summary>The destructor is declared as protected.</summary>
  virtual ~AcMgTitleBorder(){};
};

///<summary>This is the interface class for iterator of all title/border objects in current space.</summary>
class AMGTITLE_CRX_DLLSHARE AcMgTitleSpaceIterator
{
public:
  virtual ~AcMgTitleSpaceIterator(){}
  ///<summary>Sets the initialization suspend mode.</summary>
  virtual void setSuspend(bool) = 0;
  ///<summary>Advances the iterator by one item: Evtl.</summary>
  virtual Acad::ErrorStatus next() = 0;
  ///<summary>The function indicates whether the last operation tried to position the iterator beyond the ends of the list; 
  ///esp. if the list is empty done will always return true.</summary>
  virtual bool done() = 0;
  ///<summary>Evtl. Reinitalization, if not suspend mode.</summary>
  virtual Acad::ErrorStatus toFirst() = 0;
  ///<summary>If the list is empty, done() will return true and an error status is returned.</summary>
  virtual Acad::ErrorStatus current(AcDbObjectId&) = 0;
  ///<summary>Evtl. Reintialization, if not suspend mode.</summary>
  virtual int count() = 0;
  ///<summary>Evtl. reinitialization, if not suspend mode.</summary>
  virtual Acad::ErrorStatus item(int) = 0;
};

///<summary>This is class AcMgTitleEventReactor.</summary>
class AcMgTitleEventReactor
{
public:
  virtual ~AcMgTitleEventReactor() {}
  virtual void eventTitleBorderCreateBegin(AcMgTitleBorder*,
    AcMgTitleOpSettings*,
    bool *veto)
  {
  }
  virtual void eventTitleBorderCreateStarts(AcMgTitleBorder*,
    bool *veto)
  {
  }
  virtual void eventTitleBorderCreateComplete(AcDbObjectId&)
  {
  }
  virtual void eventTitleBorderModifyBegin(AcMgTitleBorder*,
    AcMgTitleOpSettings*,
    bool *veto)
  {
  }
  virtual void eventTitleBorderModifyStarts(AcMgTitleBorder*,
    AcMgTitleOpSettings*,
    bool *veto)
  {
  }
  virtual void eventTitleBorderModifyComplete(AcDbObjectId&)
  {
  }
  virtual void eventTitleBorderModifyCancelled(AcDbObjectId&)
  {
  }
  virtual void eventTitleBorderBeforeDataEdit(AcMgBorder *, AcMgTitle *)
  {
  }
};

#define ACMG_TITLE_SERVICE _T(/*MSG0*/"AcMgTitleService")
#define pAcMgTitleBorderMgr ((AcMgTitleBorderMgr*)AcRxService::cast(acrxServiceDictionary->at( ACMG_TITLE_SERVICE )))

#endif //ACMTITLE_H
