//
#ifndef __BOMMGR_H
#define __BOMMGR_H
//
//  BOMMgr.h - This class should work similar way as standard manager works for standards.
//             It mainly gets the current Bom, list BOM's gets their names, calls edit
//             for BOM's.
//
//  (C) Copyright 1994-2005 by Autodesk, Inc.  All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted, 
// provided that the above copyright notice appears in all copies and 
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting 
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. 
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC. 
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to 
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//

#include "AdAChar.h"

class AcmIterator;
class AcmDataDictionary;
class AcmCPartList;
class AcmBomReactor;

class AmiCompDefKey;
class AmiCompKey;
enum Acm::BomOverrideType;

#pragma warning(push)
#pragma warning(disable : 4275)
class DllImpExp AcmBOMManager : public AcRxService
{
public:
    ACRX_DECLARE_MEMBERS(AcmBOMManager);
// working with Bom Tables
    // Creates new BOM table for specified target. If targetId is kNull, tham Main Bom Table is created.
    // Each target could have max 1 Bom Table associated to it. If there is alread BOM Table,
    // eDuplicateEntry error code is returned. Created Bom Table is placed to dwg file at the appropriate
    // place and closed. Name must be used and must not be an empty string or NULL.
    //
    virtual Acad::ErrorStatus createBomTable(AcDbObjectId& aNewBomTableId,
                                             const AcDbObjectId targetId = AcDbObjectId::kNull,
                                             LPCTSTR name = NULL,
											                       bool addToBrowser = true,
                                             AcDbDatabase *pHostDb = NULL) = 0;

    virtual Acad::ErrorStatus createBomTable(AcDbObjectId& aNewBomTableId,
                                             const AmiCompDefKey* pTargetKey,
                                             LPCTSTR name = NULL) = 0;

    // Creates new BOM table for specified borderId.For more informations see above.

    virtual Acad::ErrorStatus createBorderBomTable(AcDbObjectId& aNewBomTableId,
                                           const AcDbObjectId borderId,LPCTSTR name = NULL,bool populate = false) = 0;
    //remove BOM table from current drawing
    virtual Acad::ErrorStatus removeBomTable(const AcDbObjectId& bomTableId) = 0;

    // Returns Id of BOM Table associated to assembly (subassembly) present.
    // If table doesn't exist, it returns eKeyNotFound. Name will contains the Bom Table name.
    // If tabRecId is kNull, than main BOM Table Id is returned.
    //
    virtual Acad::ErrorStatus getBomTable(AcDbObjectId& aBomTableId,CString& name,
                                          const AcDbObjectId& targetId,
                                          AcDbDatabase *pHostDb = NULL) const = 0;

    virtual Acad::ErrorStatus getBomTable(AcDbObjectId& aBomTableId,CString& name,
                                       const AmiCompDefKey* pTargetKey) const = 0;

    virtual Acad::ErrorStatus getBomTable(LPCTSTR name,AcDbObjectId& aBomTableId,AcDbDatabase *pDb=NULL) const = 0;

    virtual Acad::ErrorStatus getBOMIdByCompDef(const AcDbObjectId& cmpDefId, AcDbObjectId& bomId, AcDbDatabase *pHostDb = NULL) const = 0;

    // Returns Id of BOM Table associated to some borderId.
    // If table doesn't exist, it returns eKeyNotFound. Name will contains the Bom Table name.
    virtual Acad::ErrorStatus getBorderBomTable(AcDbObjectId& aBomTableId,CString& name,
                                       const AcDbObjectId& borderId) const = 0;

    // Check if BOM Table for specified target exists. If targetId is kNull, tham Main Bom Table is checked.
    // Each target could have max 1 Bom Table associated to it. If there is alread BOM Table,
    // eDuplicateEntry error code is returned.
    //
    virtual Acad::ErrorStatus existBomTable(const AcDbObjectId& targetId = AcDbObjectId::kNull, AcDbDatabase *pHostDb = NULL) const = 0;
    virtual Acad::ErrorStatus existBomTable(const AmiCompDefKey* pTargetKey) const = 0;
    virtual Acad::ErrorStatus existBomTable(LPCTSTR name, AcDbDatabase *pHostDb = NULL) const = 0;

    // Returns the list of all Bom Tables in the current drawing and all xrefed drawings (if xrefInc is kTrue)
    // If there is not table at all, it just returns
    // Note that it is critical for the caller to understand that it is up to the
    // caller responsibility to check the returned bomId.database() for any further action expecially with the ext-objectId
    // Never ever try to dwgout the xrefed objectId! 
    virtual Acad::ErrorStatus getAllBomTables(AcDbObjectIdArray& array,
                                              Adesk::Boolean xrefed = Adesk::kFalse,
                                              AcDbDatabase *pHostDb = NULL) const = 0;

    // get the current Bom table.
    virtual Acad::ErrorStatus getCurrentBom(AcDbObjectId& bomId,
                                            AcDbDatabase *pDb = NULL) const = 0;
    // specifies current Bom, to be used for editing and querying purpose. The target modifcation is used
    // to be able to use selected target to setup current bom.
    //
    virtual Acad::ErrorStatus setCurrentBomTarget(const AcDbObjectId& targetId) = 0;
    virtual Acad::ErrorStatus setCurrentBomTarget(const AmiCompDefKey* pTargetKey) = 0;
    virtual Acad::ErrorStatus setCurrentBom(const AcDbObjectId& bomId, bool addToBrowser = true, AcDbDatabase * pHostDb = NULL) = 0;
    virtual Acad::ErrorStatus setCurrentBom(const CString& bomName, bool addToBrowser = true, AcDbDatabase * pHostDb = NULL) = 0;
    
    virtual void setInputBom(const CString& bomName)=0;//400298 
    virtual void getInputBom(CString& bomName, AcDbObjectId& inputBomId)=0;//400298 

    // Gets tha main data about Bom Table, such as Name and list of other values. It returns all actual
    // values together with thir names. Name is used to specify BOM Table name.
    // Bom table data doesn't contain item number and number if items.
    //
    virtual Acad::ErrorStatus getBomData(const AcDbObjectId& bomId,CString& name,
                                         CMapStringToString& valueMap) const = 0;

    // Sets Main Bom data. If Bom table already contains any,
    // all of the previous data will be removed and new data will be inserted. If it doesn't
    // new data are created and initialized using valueMap. Data doesn't contain item number
    // and number if items.
    //
    virtual Acad::ErrorStatus setBomData(const AcDbObjectId& bomId, LPCTSTR name,
                                         const CMapStringToString& valueMap) const = 0;

    // Gets the BOM table properties, such as expansion type, separator, and assembly path usage,
    // associated sheet IDs, associatd Target ID.
    //
    virtual Acad::ErrorStatus getBomProperties(const AcDbObjectId& bomId,
                                                bool& isStructuralyExpanded, // true - structural, false - expanded
                                                bool& isUsingAssmPath,       // true - 1-2, false 2.
                                                CString& structSeparator,    // separator - default is "-"
                                                AcDbObjectIdArray& assocLayoutIds, // which layouts allows to create parts list from this BOM
                                                AcDbObjectId& targetId       // associated target
                                                ) const = 0;

    // Gets the BOM table properties, such as expansion type, separator, and assembly path usage,
    // associated sheet IDs, associated border ID. You cannot use this method to change associatd Target ID.
    // use createBomTable instead.
    // The method return eOk, if everything is Ok, otherwise error status of inherit operation (enotOpen...)
    // If parts lists and balloons will be regenerated, regen is set ot true, otherwise it is false.
    //
    virtual Acad::ErrorStatus setBomProperties(const AcDbObjectId& bomId,
                                                bool isStructuralyExpanded, // true - structural, false - expanded
                                                bool isUsingAssmPath,       // true - 1-2, false 2.
                                                LPCTSTR structSeparator,    // separator - default is "-"
                                                AcDbObjectIdArray assocLayoutIds, // which layouts allows to create parts list from this BOM
                                                bool& regen
                                              ) const = 0;

    // sorting support. Use Iterator and set the sorting priority to each item
    // you like to change the sort order. Than call this method to update aprts lists.
    // AMBOM dialog and Parts List dialog do this automatically, so you do not need to
    // call it, if it will be called later
    virtual Acad::ErrorStatus applySort(const AcDbObjectId& bomId) const = 0;

    // BOM Iterator is used to iterate through all items in Bom table in specified order. The created class must
    // be than deleted at callers responsibility. The sort parameter specifies wheather to take current sort
    // state or not. If not, the items are in the same order as created.
    // The expand parameter specifies if it will include expanded (shaded in dialog) items as well.
    //
    virtual AcmIterator* newItemIterator(const AcDbObjectId& bomId,
                                         Acm::PartListDirection sort =Acm::kTopDown,
                                         Adesk::Boolean expanded = Adesk::kFalse) const = 0;
    virtual AcmIterator* newItemIterator(const AcDbObjectId& bomId,
                                         const AcmCPartList* pSymb,
                                         Adesk::Boolean expanded = Adesk::kFalse) const = 0;

    // returns list of parts lists associated to the BOM table
    //
    virtual Acad::ErrorStatus getBomPartsLists(const AcDbObjectId& bomId,
                                              AcDbObjectIdArray& partsListIdArray) const = 0;

// working with data associated to parts
    // Creates Part data for specified Part. If the Part has already associated data,
    // it returns eAlreadyInDb. The Part data will be initialized using valueMap.
    // Part data doesn't contain item number. Number of items is initialized when the reference
    // to the part is created.
    //
    virtual Acad::ErrorStatus createPartData( const AcDbObjectId& partId,
                                              const CMapStringToString& valueMap) const = 0;
    // formerly getDataId.
    // Check if part reference is one of known types isKindOf(AcDbBlockReference or AcDbPartRef)
    // otherwise returns eIllegalEntityType. If part reference has DataEntry associated, it will return
    // all actual values together with thir names, otherwise returns eKeyNotFound.
    // Part data doesn't contain item number. Number of items returned is associated to the part reference
    // only.
    // Second one can be used together with Iterator
    //
    virtual Acad::ErrorStatus getPartData(const AcDbObjectId& referenceId,
                                          Adesk::UInt32& numOfItems,          // number of items
                                          CMapStringToString& valueMap) const = 0;
    virtual Acad::ErrorStatus getPartData(const AmiCompKey*  pCompKey,
                                          Adesk::UInt32& numOfItems,          // number of items
                                          CMapStringToString& valueMap) const = 0;
    virtual Acad::ErrorStatus getPartData(const AcDbObjectId& partId,
                                          CMapStringToString& valueMap) const = 0;

    // formerly createDataForBlock.
    // Sets Bom data for specified reference to a part. If the part has already associated data,
    // all of the previous data will be removed and new data will be inserted. If it doesn't
    // have bom data associated, new data is created and initialized using valueMap.
    // Part data doesn't contain item number. Number of items is initialozed to 1 by default and
    // is stored on per reference basis.
    //
    virtual Acad::ErrorStatus setPartData(const AcDbObjectId& referenceId,
                                          Adesk::UInt32 numOfItems,           // number of items
                                          const CMapStringToString& valueMap,
                                          Adesk::Boolean = Adesk::kFalse) const = 0;
    virtual Acad::ErrorStatus setPartData(const AmiCompKey* pCompKey,
                                          Adesk::UInt32 numOfItems,           // number of items
                                          const CMapStringToString& valueMap,
                                          Adesk::Boolean = Adesk::kFalse) const = 0;
    virtual Acad::ErrorStatus setPartData(const AcDbObjectId& partId,
                                          const CMapStringToString& valueMap) const = 0;

    // BOM Data Iterator is used to iterate through all bom data in current dwg and in all XREFes drawings.
    // The created class must be than deleted at callers responsibility.
    // If mainOnly is true, than only Data associated to any Bom Tbale wil be returned.
    //
    virtual AcmIterator* newPartDataIterator(Adesk::Boolean mainOnly = Adesk::kFalse,
                                             Adesk::Boolean noXref = Adesk::kTrue,
                                             AcDbDatabase *pHostDb = NULL) const = 0;

// working with items in current bom table
// all those member functions need setCurrentBom be called prior to use them.
    // formerly appendToBom
    // Checks if referenceId has bom data associated. If yes, it creates new item in the current Bom
    // Table and associate the reference to the row. If no, eKeyNotFound is returned.
    // If itemNo string is used, its value is used to initialize the item number for created row.
    // If NULL or empty value is used, it find last one and intialize the new item with last+1.
    // If number of items is left default, Bom Tbale will try to determine the accual number of items,
    // otherwise it will use the specified value and let the user determine the number of items by himself.
    // Created item could be removed by opening as AcDbObject and erasing it from the drawing
    //
    virtual Acad::ErrorStatus createItem(AcDbObjectId& itemId,            // created item
                                         const AcDbObjectId& bomId,
                                         const AcDbObjectIdArray& refIdArray, // reference to a part
                                         LPCTSTR itemNo) const = 0;   // initial number of items
    virtual Acad::ErrorStatus createItem(AcDbObjectId& itemId,            // created item
                                         const AcDbObjectId& bomId,
                                         const AmiCompKey* pCompKey, // reference to a part
                                         LPCTSTR itemNo) const = 0;   // initial number of items

    // formerly appendToBom
    // this is to allow new unassociated item to be created. It cretes new bom data, initialize them using value map
    // and than creates new item. valueMap can contain any number of data similar as setBomPartData.
    //
    virtual Acad::ErrorStatus createItem(AcDbObjectId& itemId,            // created item
                                         const AcDbObjectId& bomId,
                                         LPCTSTR itemNo,                  // item number
                                         Adesk::UInt32 numOfItems,        // number of items
                                         const CMapStringToString& valueMap) const = 0;   // other values to initialize bom data

    // formerly setRowValues.
    // Sets Item values - item number and num of items are specific to this item, other data (valueMap) are shared
    // by other bom tables as well. ValueMap contains column's name - value. ValueMap is checked agains the Bom standard
    // used to create bom table. If the map contains unknown entries, (doesn't match to any column defined in bom standard),
    // it is stripped from the map.
    // If user try to call setItemData on expanded item, it returs eInvalidContext.
    // If user try to set the number of items (other than -1), which is calculated automatically,
    // it returns eInvalidData
    //
    virtual Acad::ErrorStatus setItemData(const AcDbObjectId& itemId,
                                          LPCTSTR itemNo,                  // item number
                                          Adesk::UInt32 numOfItems,        // number of items
                                          const CMapStringToString& valueMap) const = 0;

    // formerly getRowValues.
    // Gets Item values - item number and num of items are specific to this item, other data (valueMap) are shared
    // by other bom tables as well. ValueMap contains column's name - value. ValueMap is created using Bom standard
    // used to create bom table, so it contains only those values, which match some of  bom table column definition.
    //
    virtual Acad::ErrorStatus getItemData(const AcDbObjectId& itemId,
                                          CString& itemNo,
                                          Adesk::UInt32& numOfItems,
                                          CMapStringToString& valueMap,
                                          const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;
    virtual Acad::ErrorStatus getItemRawData(const AcDbObjectId& itemId,
                                             CString& itemNo,
                                             Adesk::UInt32& numOfItems,
                                             CMapStringToString& valueMap,
                                             const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;
    virtual Acad::ErrorStatus getItemData(const AcDbObjectId& refId,
                                          const AcDbObjectId& bomId,
                                          AcDbObjectId& itemId,
                                          CString& itemNo,
                                          Adesk::UInt32& numOfItems,
                                          CMapStringToString& valueMap,
                                          const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;
    virtual Acad::ErrorStatus getItemData(const AmiCompKey* pCompKey,
                                          const AcDbObjectId& bomId,
                                          AcDbObjectId& itemId,
                                          CString& itemNo,
                                          Adesk::UInt32& numOfItems,
                                          CMapStringToString& valueMap,
                                          const AcDbObjectId& bomStdId=AcDbObjectId::kNull)const = 0;

    virtual Acad::ErrorStatus getBlockData(const AcDbObjectId& blockId,          // ID of Block Table record
                                           AcDbObjectId& bomRowId,               // output
                                           AcDbObjectId& dataEntryId) const = 0; // output
    // Get BOM data relating to a Block Table record & its contents (vendor, price, etc.) from BOM
    virtual Acad::ErrorStatus getBlockData(const AcDbObjectId& blockId,             // ID of Block Table record
                                           CString& itemNo,                         // output
                                           Adesk::UInt32& numOfItems,               // output
                                           CMapStringToString& valueMap) const = 0; // output

    // Returns status of the itemcalcNumItem setting for BomRow - the status variable, which specify whether
    // to calculate number of pieces for the specified row. If Item cannot be opened for read, it returns appropriate
    // error code.
    //
    virtual Acad::ErrorStatus getItemStatus(const AcDbObjectId& itemId,
                                            Adesk::Boolean& isAutoCalcEnabled,
                                            Adesk::Boolean& isExpanded,             // true only if isExpandable is true
                                            Adesk::Boolean& isExpandable) const =0; // true if bom table for part exists

    // Sets the autoCalc status for item. If Item cannot be opened for write, it returns appropriate
    // error code.
    //
    virtual Acad::ErrorStatus setAutoCalc(const AcDbObjectId& rowId,
                                          Adesk::Boolean isAutoCalcEnabled) const =0;

    // Expands item or collapse item to include/exclude inherited parts from subassembly. If the item cannot be expanded,
    // it returns eNotApplicable. If the operation couldn't be finished succesfully, no item is added. After this operation,
    // the isExpanded status will change for current Item.
    //
    virtual Acad::ErrorStatus expandItem(const AcDbObjectId& itemId,
                                         Adesk::Boolean expand = Adesk::kTrue) const = 0;

// working with references associated to the item
    // adds graphical definition to represent same part. Both definitions will use same data
    // similarly as front view and bottom view
    //
    virtual Acad::ErrorStatus addPartGrfDef(const AcDbObjectId& referenceId,
                                            const AcDbObjectId& newGrfDefId) const = 0;

    // removes the graphical definition of the part reference. Its graphical definition will
    // no longer represents the part. It will find which Bom data is associated it and
    // than removes its definition. If the definition is referenced, references will be removed
    // as well.
    //
    virtual Acad::ErrorStatus removePartGrfDef(const AcDbObjectId& referenceId) const = 0;

    // returns list of all references to the same part ( together with theirs number of items ?)
    // As the input parameter, you can use any of the part reference.
    //
    virtual Acad::ErrorStatus getPartGrfDefs(const AcDbObjectId& referenceId,
                                             AcDbObjectIdArray& refIdArray,
                                             AcDbIntArray& numOfItAr) const = 0;

    // adds reference to the Item. Reference is validated before it is appended. If the refrence
    // is BlockReference, than its BlockTableRecord has to be associated to Bom data
    //
    virtual Acad::ErrorStatus addItemReference(const AcDbObjectId& itemId,
                                               const AcDbObjectIdArray& refIdArray) const = 0;
    virtual Acad::ErrorStatus addItemReference(const AcDbObjectId& itemId,
                                               const AmiCompKey* pCompKey) const = 0;
    // check existing item reference
    //
    virtual Adesk::Boolean existItemReference(const AcDbObjectId& itemId,
                                              const AcDbObjectIdArray& refIdArray) const = 0;
    virtual Adesk::Boolean existItemReference(const AcDbObjectId& itemId,
                                              const AmiCompKey* pCompKey) const = 0;
    // removes the reference to this item. If the reference has any balloon associated to it,
    // they will be erased as well.
    //
    virtual Acad::ErrorStatus removeItemReference(const AcDbObjectId& itemId,
                                                  const AcDbObjectIdArray& refIdArray) const = 0;
    virtual Acad::ErrorStatus removeItemReference(const AcDbObjectId& itemId,
                                                  const AmiCompKey* pCompKey) const = 0;
    // returns list of reference to the item ( together with theirs number of items ?)
    //
    virtual Acad::ErrorStatus getItemReferences(const AcDbObjectId& itemId,
                                                AcmCObjArray<AcDbObjectIdArray>& referenceArray,
                                                AcDbIntArray& numItemArray) const = 0;

    //Caller is responsible for deleteing memory allocated by this method.
    //use amiDeleteKey for each memeber of returned array.
    virtual Acad::ErrorStatus getItemReferences(const AcDbObjectId& itemId,
                                                AcmCObjPtrArray<AmiCompKey>& referenceArray,
                                                AcDbIntArray& numItemArray) const = 0;

    // returns list of balloons associated to the item (and reference)
    // If reference Id is not used (== kNull), all balloons are returned.
    //
    virtual Acad::ErrorStatus getItemBalloons(const AcDbObjectId& itemId,
                                              AcDbObjectIdArray& ballIdArray,
                                              const AcDbObjectId& refId) const = 0;

    // returns list of balloons associated to the item (and references)
    // If no reference Id is provided, all balloons are returned.
    //
    virtual Acad::ErrorStatus getItemBalloons(const AcDbObjectId& itemId,
                                              AcDbObjectIdArray& ballIdArray,
                                              const AcDbObjectIdArray& refIds) const = 0;

    //returns id of bom table which associated to given sheetId
    virtual AcDbObjectId sheetBomTable(const AcDbObjectId& sheetId) const = 0;

    //sets sheet Id to be associated to bom table Id
    virtual bool setSheetBomTable(const AcDbObjectId& sheetId,const AcDbObjectId& bomId) const = 0;

/////// reactor methods
    virtual void attachBomReactor(AcmBomReactor* pReactor) = 0;
    virtual void removeBomReactor(AcmBomReactor* pReactor) = 0;

//select of bom parts
    virtual bool selectBomEntity(AcDbObjectIdArray& subentPath,const bool intoNested=false) = 0;

    virtual void activateMainCache(AcDbDatabase *pHostDb = NULL) = 0;
    virtual void deactivateMainCache(AcDbDatabase *pHostDb = NULL) = 0;

  
   enum ExportBOMType{ eEXPORT_MDB = 1, eEXPORT_MDB97, eEXPORT_EXCEL97, eEXPORT_EXCEL95, eEXPORT_DB5,
                       eEXPORT_DBIV, eEXPORT_DBIII, eEXPORT_FOXVIS, eEXPORT_FOX26, eEXPORT_FOX25, 
                       eEXPORT_TXT, eEXPORT_CSV, eEXPORT_HTML, eEXPORT_ALLFILE };

    // format: one of the enumerated export format defined above in this header file
    // bomId: the bom table to export
    // path: the full path of the exported file
    // tableName: the table name in the database of the exported file (applicable only to certain format)
    // overwrite: overwrite table of the same tableName if already exists
    // Notes: It makes use of the current BOM Standard. In order to use other BOM Standard, call the API to
    // switch to that BOM Standard first.
    virtual Acad::ErrorStatus exportBOM(ExportBOMType format,
                                        const AcDbObjectId& bomId,                                     
                                        LPCTSTR path,                                  
                                        LPCTSTR tableName,
                                        bool overwrite) const = 0;

    // format: one of the enumerated export format defined above in this header file
    // partlistId: the part list to export
    // path: the full path of the exported file
    // tableName: the table name in the database of the exported file (applicable only to certain format)
    // overwrite: overwrite table of the same tableName if already exists
    // Notes: It makes use of the current BOM Standard. In order to use other BOM Standard, call the API to
    // switch to that BOM Standard first.
    virtual Acad::ErrorStatus exportPartlist(ExportBOMType format,
                                             const AcDbObjectId& partlistId,
                                             LPCTSTR path,                                  
                                             LPCTSTR tableName,
                                             bool overwrite) const = 0;

    enum ImportBOMType{ eIMPORT_MDB = 1, eIMPORT_EXCEL97, eIMPORT_EXCEL95, eIMPORT_DB5, eIMPORT_DBIV,
                        eIMPORT_DBIII, eIMPORT_FOXVIS, eIMPORT_FOX26, eIMPORT_FOX25, eIMPORT_TXT,
                        eIMPORT_CSV };

    // format: one of the enumerated import format defined above in this header file
    // bomId: the bom table that data will be imported to
    // path: the full path of the imported file
    // tableName: the table name in the database of the imported file to be imported (applicable only to certain format)
    // overwrite: overwrite existing data in the bom table
    // Notes: It makes use of the current BOM Standard. In order to use other BOM Standard, call the API to
    // switch to that BOM Standard first.
    virtual Acad::ErrorStatus importBOM(ImportBOMType format,
                                        const AcDbObjectId& bomId,                                      
                                        LPCTSTR path,                                  
                                        LPCTSTR tableName,
                                        bool overwrite) = 0;

    // format: one of the enumerated import format defined above in this header file
    // partlistId: the part list that data will be imported to
    // path: the full path of the imported file
    // tableName: the table name in the database of the imported file to be imported (applicable only to certain format)
    // overwrite: overwrite existing data in the bom table that owns the part list
    // Notes: It makes use of the current BOM Standard. In order to use other BOM Standard, call the API to
    // switch to that BOM Standard first.
    virtual Acad::ErrorStatus importPartlist(ImportBOMType format,                                     
                                             const AcDbObjectId& partlistId,
                                             LPCTSTR path,                                  
                                             LPCTSTR tableName,
                                             bool overwrite) = 0;

    // itemId: parent item
    // childItemIds: children items of parent item
    // skipPhantom: if true phantom child will be skipped
    // Notes: This API only applies to Structured BOM table. The parent item must have been expanded
    // so that its child items are present. Any violation of these will return Acad::InvalidInput.
    // Only immediate child items are returned.
    virtual Acad::ErrorStatus getStructuredChildItems(const AcDbObjectId& itemId,
                                                      AcDbObjectIdArray& childItemIds,
                                                      bool skipPhantom = true) const = 0;

    // itemId: child item
    // parentItemId: parent item of the child item
    // skipPhantom: if true, phantom parent will be skipped
    // Notes: This API only applies to Structured BOM table.
    // Any violation will return Acad::InvalidInput.
    virtual Acad::ErrorStatus getStructuredParentItem(const AcDbObjectId& itemId,
                                                      AcDbObjectId& parentItemId,
                                                      bool skipPhantom = true) const = 0;

    // itemId: bom row item
    // defIds: array of object ids of definition
    //  none for eNonModal
    //  first and only one comp def id for eCompDef
    //  array of part definition ids for ePartRef and eBlockDef
    // itemType: one of the defined enum type
    enum ItemType{ eUnknown, eNonModal, ePartRef, eBlockDef, eCompDef };

    virtual Acad::ErrorStatus getItemDefinition(const AcDbObjectId& itemId, 
                                                AcDbObjectIdArray& defIds, 
                                                ItemType& itemType) const = 0;
    // getItemDefinition is deprecated in flavour of getItemPartDefinition:-
    // getItemDefinition do not get the definitions for part references. Instead
    // part references are obtained. The definitions are now provided via 
    // getItemPartDefinition which works for other entities as well. The 
    // part references obtain via getItemDefinition can instead be obtained via
    // getItemReferences.
    #pragma deprecated(getItemDefinition)

    // This supersedes getItemDefinition.
    // Returns the definition corresponding to the bom item.
    // itemId: bom row item
    // defIds: array of object ids of definition
    //  none for eNonModal
    //  first and only one comp def id for eCompDef
    //  array of part definition ids for ePartRef and eBlockDef
    // itemType: one of the defined enum type
    virtual Acad::ErrorStatus getItemPartDefinition(const AcDbObjectId& itemId, 
      AcDbObjectIdArray& defIds, 
      ItemType& itemType) const = 0;

    // This is an enhanced version of the current getPartData(partId, valueMap) API which return the valueMap
    // with evaluated data and also return an extra parameter for the no. of items. Evaluation of the data
    // is based on the bomStdId passed in. If the partId is a data entry id, numOfItems is not applicable.
    virtual Acad::ErrorStatus getEvaluatedPartData(const AcDbObjectId& partId,
                                                   Adesk::UInt32& numOfItems,
                                                   CMapStringToString& valueMap,
                                                   const AcDbObjectId& bomStdId=AcDbObjectId::kNull) const = 0;

    // This is an equivalence of getPartData(partId, valueMap) which return the attribute of a given key.
    // If evaluate is true, evaluated value will be returned else raw data ie. formula will be returned.
    virtual Acad::ErrorStatus getPartAttribute(const AcDbObjectId& partId,
                                               const CString& key,
                                               CString& attrib,
                                               bool evaluate = true,
                                               const AcDbObjectId& bomStdId=AcDbObjectId::kNull) const = 0;

    // This is an equivalence of setPartData(partId, valueMap) which set the attribute for a given key.    
    virtual Acad::ErrorStatus setPartAttribute(const AcDbObjectId& partId,
                                               LPCTSTR key,
                                               LPCTSTR attrib) = 0;

    // This is an equivalence of getItemData(itemId,itemNo,numOfItems,valueMap) which return the attribute of a given key.
    // If evaluate is true, evaluated value will be returned else raw data ie. formula will be returned.
    virtual Acad::ErrorStatus getItemAttribute(const AcDbObjectId& itemId,
                                               const CString& key,
                                               CString& attrib,
                                               bool evaluate = true,
                                               const AcDbObjectId& bomStdId=AcDbObjectId::kNull) const = 0;

    // This is an equivalence of getItemData(itemId,itemNo,numOfItems,valueMap) which set the attribute for a given key.
    virtual Acad::ErrorStatus setItemAttribute(const AcDbObjectId& itemId,
                                               LPCTSTR key,
                                               LPCTSTR attrib) = 0;

    // This sets the predefined list value for the item with the specified attribute key
    virtual Acm::ErrorStatus setItemPreDefinedListValue(const AcDbObjectId& itemId,
                                                        const ACHAR* key,
                                                        const ACHAR* preDefListValue) = 0;

    // This sets the predefined list value for the part with the specified attribute key
    virtual Acm::ErrorStatus setPartPreDefinedListValue(const AcDbObjectId& partId,
                                                        const ACHAR* key,
                                                        const ACHAR* preDefListValue) = 0;

    // itemId: bom row item
    // numOfItems: calculated no. of items accounting for ref. qty ie. as seen from BOM dlg box
    // numOfItems: calculated no. of items NOT accounting for ref. qty ie. instance ref. qty not included
    virtual Acad::ErrorStatus getCalculatedItemCount(const AcDbObjectId& itemId,
                                                     Adesk::UInt32& numOfItems,
                                                     Adesk::UInt32& numOfItemsIgnoreRefQty) const = 0;

    enum ItemDataType{ ePhantomState, eExcludeFromPartlistState };

    // itemId: bom row item
    // dataType: one of the item data type defined above
    // data: true or false
    // Notes: Applicable to both ePhantomState and eExcludeFromPartlistState data type.
    // 'data' is true if item is phantom or excluded from partlist, false otherwise.
    virtual Acad::ErrorStatus getItemExtendedData(const AcDbObjectId& itemId, 
                                                  const ItemDataType& dataType,
                                                  bool& data) const = 0;

    // itemId: bom row item
    // dataType: one of the item data type defined above
    // data: true or false
    // Notes: Applicable only to eExcludeFromPartlistState data type.
    // Set 'data' to true to set item to excluded from partlist or false otherwise.
    virtual Acad::ErrorStatus setItemExtendedData(const AcDbObjectId& itemId, 
                                                  const ItemDataType& dataType,
                                                  bool data) = 0;

    // itemIds: list of bom row items to merge
    virtual Acad::ErrorStatus mergeItems(const AcDbObjectIdArray& itemIds) = 0;

    // bomId: bom table id
    // isBorderBom: true if bom table is border bom else false
    // isVisible: false if bom table is hidden else true
    virtual Acad::ErrorStatus getExtendedBomProperties(const AcDbObjectId& bomId, 
                                                       bool& isBorderBom, 
                                                       bool& isVisible) const = 0;

    // itemId: input only. bom row item
    // priority: value indicating whether item should be ahead(low value) or at 
    //           the end(high value) for sort purpose
    virtual Acad::ErrorStatus setItemSortPriority(const AcDbObjectId& itemId,
                                                 int priority) = 0 ;
    virtual Acad::ErrorStatus getItemSortPriority(const AcDbObjectId& itemId,
                                                 int &priority) const = 0;

    virtual Acad::ErrorStatus getBomOverride(
      const AcDbObjectId& itemId, // id of bom item/partref/data entry
      const ACHAR *attribute,
      ACHAR *& originalValue,
      ACHAR *& originalData,
      ACHAR *& currentValue,
      ACHAR *& currentData,
      Acm::BomOverrideType &overrideType,
      bool &editable
    ) const = 0;

    virtual Acad::ErrorStatus removeAttribute(
      const AcDbObjectId& itemId,  // id of bom item/partref/data entry
      const ACHAR *attribute) = 0;

};
#pragma warning(pop)
//
// This class allows one to sequentially retrieve the objects in
// the BOM dictionary, and keeps track of what the last object retrieved was.
//
class AcmIterator
{
public:
    virtual ~AcmIterator();
    // item access
    virtual AcDbObjectId  objectId() const = 0;
    virtual Acad::ErrorStatus getData(CMapStringToString& valueMap) const = 0;
    virtual Acad::ErrorStatus setData(const CMapStringToString& valueMap) = 0;
    virtual int numEntries() const = 0;
    // sorting priority
    virtual Acad::ErrorStatus getSortPriority(int& priority) const = 0;
    virtual Acad::ErrorStatus setSortPriority(int priority) = 0;
    // movement
    virtual Adesk::Boolean done() = 0;
    virtual Adesk::Boolean next() = 0;
    virtual Adesk::Boolean setPosition(int idx) = 0;
    virtual Adesk::Boolean setPosition(const AcDbObjectId& id) = 0;
};

inline AcmIterator::~AcmIterator()
{
}


//void registerStdClassesWithAcad();
//void unloadStdClassesFromAcad();

DllImpExp AcmBOMManager* getAcmBomMgr();

#define BOMMGR_SERVICE_NAME  ACRX_T(/*MSG0*/"AcmBomManagerService")
#define acmBomMgr            getAcmBomMgr()
#define isBomMgrReady()      acrxServiceIsRegistered(BOMMGR_SERVICE_NAME)
#define LockBomMgr()         (isBomMgrReady() ? acmBomMgr->addDependency(), TRUE : FALSE )
#define UnlockBomMgr()       (isBomMgrReady() ? acmBomMgr->removeDependency(), TRUE : FALSE )

Acm::ErrorStatus registerBomMgr();
Acm::ErrorStatus unloadBomMgr();

#endif
