//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 by Autodesk, Inc.  All rights reserved.
//
// This computer source code and related instructions and comments 
// are the unpublished confidential and proprietary information of 
// Autodesk, Inc. and are protected under applicable copyright and 
// trade secret law.  They may not be disclosed to, copied or used 
// by any third party without the prior written consent of Autodesk, Inc.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef __ACM_SYMBOL_LIBRARY_H
#define __ACM_SYMBOL_LIBRARY_H

class AcmSymbol;
class AcmCSubSymbol;
class AcmSymbolLibObjectImp;
class AcmCSubSymbolsList;
///<summary>This class is existing class derived from AcDbObject. It is the base class for AmdtSurfTextLibObject
///and AmdtWeldingLibObject. It is the wrapper for class class AcmSymbolLibObjectImp.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtSymbolLibObject : public AcDbObject
{
public:
  ACRX_DECLARE_MEMBERS(AmdtSymbolLibObject);
  ///<summary>The class constructor.</summary>
  AmdtSymbolLibObject();
  ///<summary>The class destructor. It frees the data member.</summary>
  ~AmdtSymbolLibObject();

  /// <summary>
  /// Method for set read/write mode from symbol library object.
  /// </summary>
  /// <param name="mode">enum type CSymLibBaseInfo::ReadWriteMode as intiger value</param>
  /// <param name="idx">index of the desired sub symbol when the mode is kOnlySubSymbol or kSymbolAndOneSubsymbol</param>
  virtual void setReadWriteMode(Adesk::UInt16 mode, Adesk::UInt16 idx = 0) const;
  virtual void resetReadWriteMode() const;

  virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler* pFiler);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
  ///<summary>Get the original standard name.</summary>
  const ACHAR * stdName() const;
  ///<summary>Get the library object name.</summary>
  const ACHAR * entryName() const;
  ///<summary>Get the symbol standard class name.</summary>
  const ACHAR* symStdClassName() const;
  ///<summary>Update the library object name.</summary>
  ///<param name="newName">Specifies the new name.</param>
  Acm::ErrorStatus setEntryName(const ACHAR *newName);
  ///<summary>Get the Default status.</summary>
  virtual bool isDefault() const;
  ///<summary>Update the isDefault status.</summary>
  ///<param name="className">Default is NULL. This is required for legacy library objects, eg welding symbol
  ///library object before edison. In legacy objects, symbol standard class name is not defined.</param>
  ///<param name="status">True or False</param>
  ///<returns>Return true, if there is no error.</returns>
  virtual bool setIsDefault(bool, const ACHAR* className = NULL);

  ///<summary>Get the specific value of the symbol library object.</summary>
  ///<param name="var">Refer to Acm::Variable for the specific symbol.</param>
  ///<param name="Value">Formatted result.</param>
  ///<returns>If returns Acad::eOK, the caller is responsible for deleting the string returned in value.</returns>
  virtual Acm::ErrorStatus getRequirementValue(Acm::Variable var, ACHAR *& retVal) const;

  ///<summary>Get the specific value of the symbol library object.</summary>
  ///<param name="idx">Refer to Adesk::UInt16 for the define idex of sub-symbol in the array of sub-symbol list.</param>
  ///<param name="var">Refer to Acm::Variable for the specific symbol.</param>
  ///<param name="Value">Formatted result.</param>
  ///<returns>If returns Acad::eOK, the caller is responsible for deleting the string returned in value.</returns>
  virtual Acm::ErrorStatus getRequirementValue(Adesk::UInt16 idx, Acm::Variable var, ACHAR*& retVal)const;

  ///<summary>Get the number of sub-symbols for given symbol in the library
  /// The function returns 1 if the symbol doesn't support the multi-sub-symbol system.
  ///  Otherwise, it is the size of the sub-symbols list  </summary>
  ///<returns>int value as number of sub-symbols</returns>
  virtual int getNumberOfSubSymbols() const;

  ///<summary>Get the update the data of SubSymbol.</summary>
  ///<param name="pCSubSym">Specifies the SubSymbol object.</param>
  virtual void getObject(AcmCSubSymbol *pCSubSym) const;
  ///<summary>Update the library object with the data in SubSymbol.</summary>
  ///<param name="pCSubSym">Specifies the SubSymbol object.</param>
  virtual void setObject(const AcmCSubSymbol *pCSubSym);

  ///<summary>Get the update the data of SubSymbols list.</summary>
  ///<param name="pCSubSym">Specifies the SubSymbol object.</param>
  virtual void getObjectList(AcmCSubSymbolsList* pCSubSymList) const;

  ///<summary>Update the library object with the data in SubSymbols list.</summary>
  ///<param name="pCSubSym">Specifies the SubSymbol object.</param>
  virtual void setObjectList(const AcmCSubSymbolsList* pCSubSymList);

  ///<summary>Update the symbol library object.</summary>
  ///<param name="pCSubSym">SubSymbol contains data used in updating current library object.</param>
  ///<param name="itemName">Name of the new library object.</param>
  ///<param name="stdName">Original standard name.</param>
  ///<param name="className">Symbol standard class name.</param>
  ///<returns>Return Acad::eOk, if successful.</returns>
  virtual Acm::ErrorStatus set(const AcmCSubSymbol * pCSubSym, const ACHAR *itemName, const ACHAR *stdName, const ACHAR* className);

  ///<summary>Update the symbol library object.</summary>
  ///<param name="pCSubSymList">AcmCSubSymbolsList contains data used in updating current library object.</param>
  ///<param name="itemName">Name of the new library object.</param>
  ///<param name="stdName">Original standard name.</param>
  ///<param name="className">Symbol standard class name.</param>
  ///<returns>Return Acad::eOk, if successful.</returns>
  virtual Acm::ErrorStatus set(const AcmCSubSymbolsList* pCSubSymList, const ACHAR* itemName, const ACHAR* stdName, const ACHAR* className);
  
  bool operator==(const AmdtSymbolLibObject& symLibObj)const;

  static Acm::ErrorStatus degradeSave(AmdtSymbolLibObject* symLibObj, LPCTSTR className);
protected:
  Adesk::UInt16 classVersion() const;
private:
  Adesk::UInt16     mVersion;
protected:
  AcmSymbolLibObjectImp *mpImp;
};

inline Adesk::UInt16 
AmdtSymbolLibObject::classVersion() const
{ return mVersion; }

////////////////////////////////////////////////////////////////

///<summary>This class is existing class derived from AcDbDictionary. It is the base class for AmdtSurfTextLibrary, 
///AmdtWeldingLibrary and AmdtJointLibrary.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtSymbolLibrary : public AcDbDictionary
{
public:
  ACRX_DECLARE_MEMBERS(AmdtSymbolLibrary);

  virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler* pFiler);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
  ///<summary>Get the name of the Symbol Library's Dictionary.</summary>
  virtual const ACHAR *name() const = 0;

  ///<summary>Load a symbol library object to the symbol, pSym.</summary>
  ///<param name="itemName">Name of library object.</param>
  ///<param name="pSym">Pointer to a Symbol with the return result.This symbol provides the information on standad
  ///and symbol standard.Standard refers to original standard.</param>
  ///<returns>If successful, returns Acad::eOK.</returns>
  virtual Acad::ErrorStatus loadItem(const ACHAR *itemName, AcmSymbol *pSym) = 0;

  ///<summary>Add a new symbol library object based on the symbol.</summary>
  ///<param name="itemName ">Name of the new library object.</param>
  ///<param name="pSym ">Pointer to a Symbol with the value added to the library.This symbol provides the 
  ///information on standad and symbol standard.Standard refers to original standard.</param>
  ///<param name="newId">Object ID of the new librar object, if successful.</param>
  ///<param name="bCheckValidName">Default is true. If true, entry name is unique in the library.</param>
  ///<returns>If successful, returns Acad::eOK.</returns>
  virtual Acad::ErrorStatus appendItem(const ACHAR *itemName, const AcmSymbol* pSym, AcDbObjectId& newId, bool bCheckValidName=true) = 0;
  ///<summary>Add the symbol library object to the library.</summary>
  ///<param name="newId">If successful, returns Acad::eOK.</param>
  ///<param name="bCheckValidName">Default is true. If true, the name, specify in the library object, is checked 
  ///against the existing objects, of the same standard and symbol standard, including legacy objects.</param>
  ///<param name="pLibObj ">Pointer of symbol library object to be added.This object should not have an owner.This 
  ///object should specify the standard name and symbol standard name.User should not free the object if append is 
  ///successful.</param>
  ///<returns>If successful, returns Acad::eOK.</returns>
  Acad::ErrorStatus appendItem(AmdtSymbolLibObject*, AcDbObjectId& newId, bool bCheckValidName=true);

  ///<summary>Modify an existing symbol library object based on the symbol.</summary>
  ///<param name="itemName">Name of library object to be modified.</param>
  ///<param name="pSym">Pointer to a Symbol with the data used for modification.This symbol provides the information
  ///on standad and symbol standard.Standard refers to original standard.</param>
  ///<returns>If successful, returns Acad::eOK.</returns>
  virtual Acad::ErrorStatus modifyItem(const ACHAR *itemName, AcmSymbol *pSym) = 0;

  ///<summary>Remove a symbol library object from the library.</summary>
  ///<param name="itemName">Name of the existing library object to be removed from the library</param>
  ///<param name="stdName">Original Standard name.</param>
  ///<param name="className">Symbol standard class name.</param>
  ///<returns>Return Acad::eOk, if there is no error.</returns>
  bool removeItem(const ACHAR *itemName, const ACHAR *stdName, const ACHAR* className);

  ///<summary>Rename an existing symbol library object based on the symbol.</summary>
  ///<param name="oldName">Name of the existing library object.</param>
  ///<param name="newName">New name of the library object.</param>
  ///<param name="stdName">Standard name. The library object is selected based on standard name and symbol standard 
  ///name.Standard name refers to original standard name.</param>
  ///<param name="className">Symbol standard class name. The library object is selected based on standard name and 
  ///symbol standard class name.</param>
  ///<returns>Return Acad::eOk, if successful</returns>
  bool renameItem(const ACHAR *oldName, const ACHAR *newName, const ACHAR *stdName, const ACHAR* className) const;

  ///<summary>Set the default status of an existing symbol library object .</summary>
  ///<param name="itemName">Name of the existing library object.</param>
  ///<param name="stdName">Original Standard name.</param>
  ///<param name="className">Symbol standard class name.</param>
  ///<param name="bDefault">Set the library object according to this value.</param>
  ///<returns>Return true, if there is no error.</returns>
  bool setIsDefaultItem(const ACHAR *itemName, const ACHAR *stdName, const ACHAR* className, bool bDefault) const;

  ///<summary>Check if a symbol library object of a specific name exist.</summary>
  ///<param name="itemName">Name of the existing library object.</param>
  ///<param name="stdName ">Original Standard name.</param>
  ///<param name="className">Symbol standard class name. </param>
  ///<returns>Return true, if object exist.</returns>
  bool isItemExist(const ACHAR *itemName, const ACHAR *stdName, const ACHAR* className) const;
  ///<summary>Get the object ID of a symbol library object.</summary>
  ///<param name="itemName">Name of the existing library object.</param>
  ///<param name="stdName">Symbol standard class name.</param>
  ///<param name="className">Original Standard name.</param>
  ///<param name="returnId">Object ID of the library object.</param>
  ///<param name="bCompatiableRev">Default is true. If true, the selection would include the specific revision 
  ///type and legacy object where symbol standard is empty.</param>
  ///<returns>Return true, if found.</returns>
  virtual bool find(const ACHAR *itemName, const ACHAR *stdName, const ACHAR* className, AcDbObjectId &returnId, bool bCompatiableRev=true) const;
  ///<summary>Get an array of object IDs of symbol library objects.</summary>
  ///<param name="stdName">Original Standard name.</param>
  ///<param name="className">Symbol standard class name.</param>
  ///<param name="ListId">Array of Object IDs of the library objects.</param>
  ///<param name="bCompatiableRev">Default is true. If true, the selection would include the specific revision 
  ///type and legacy object where symbol standard is empty.</param>
  ///<returns>Return true, if found.</returns>
  virtual bool find(const ACHAR *stdName, const ACHAR* className, AcDbObjectIdArray &ListId, bool bCompatiableRev=true) const;
  ///<summary>Get the object ID of the default symbol library object.</summary>
  ///<param name="stdName">Original Standard name.</param>
  ///<param name="className">Symbol standard class name.</param>
  ///<param name="returnId">Object ID of the default library object based on stdName and revision.</param>
  ///<returns>Return true, if there is no error.</returns>
  virtual bool getDefaultItem(const ACHAR *stdName, const ACHAR* className, AcDbObjectId &returnId) const;
  virtual Acad::ErrorStatus decomposeForSave(AcDb::AcDbDwgVersion ver,
    AcDbObject*& replaceObj,
    AcDbObjectId& replaceId,
    Adesk::Boolean& exchangeXData);

protected:
  Adesk::UInt16 classVersion() const;
private:
  Adesk::UInt16 mVersion;
};

inline Adesk::UInt16 
AmdtSymbolLibrary::classVersion() const
{ return mVersion; }

DBREF_DECLARE(AmdtSymbolLibrary)

#endif //