//////////////////////////////////////////////////////////////////////////////
//
//  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 __ACMPLSTFLTR_API_H
#define __ACMPLSTFLTR_API_H

#include "AdAChar.h"

class AcmCItFltrImp;
class AmdtItemFilterUtilImp;
class AcmPartList;

///<summary>This API is inherited from AcDbObject and acts as the parts list filter. 
///Its owner is always a parts list. 
///It contains the standard AcDbObject interface: dwgInFields, dwgOutFields.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtItemFilter : public AcDbObject
{
  friend class AcmSymbbInternals;
public:
  ACRX_DECLARE_MEMBERS(AmdtItemFilter);
  ///<summary>Constructs the item filter class. The constructor is protected.</summary>
  AmdtItemFilter();
  ///<summary>Destructs the item filter class.</summary>
  virtual ~AmdtItemFilter();
  ///<summary>Evaluates the parts list using the specified filter.</summary>
  virtual bool evaluate(const AcDbObjectId& rowId) const;
  ///<summary>Returns the name of the filter, which will be displayed in the parts list dialog box.</summary>
  virtual CString name() const ;
  ///<summary>Retrieves the filter type.</summary>
  ///<returns>Returns Acm::kFilterBasic of enum Acm::FilterType</returns>
  virtual Acm::FilterType type() const;
  ///<summary>This function is called to prepare a filter for use.</summary>
  virtual Acad::ErrorStatus makeFilterReady();
  ///<summary>Returns if the filter is excluded from evaluation or not.</summary>
  virtual bool excluded() const;
  ///<summary>Returns whether the filter is activated.</summary>
  bool isOn() const;
  ///<summary>Sets whether the filter is activated.</summary>
  void setIsOn(bool newStatus);
  
  virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler* pFiler);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;

  virtual Acad::ErrorStatus subErase(Adesk::Boolean erasing);

protected:
  Adesk::UInt16 classVersion() const;
  void *operator new[](size_t nSize) { assert(0); return NULL; }
  void operator delete[](void *p) { assert(0); }
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;

private:
  AcmCItFltrImp* mpImp;
};

inline bool 
AmdtItemFilter::excluded() const
{
  return true;
}

DBREF_DECLARE(AmdtItemFilter);

///<summary>This is class AmdtItemFilterCustom.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtItemFilterCustom : public AmdtItemFilter
{
public:

  enum Operators {
    kContains = 0,
    kDoesNotCont,
    kEqual,
    kNotEqual,
    kLess,
    kGreater,
    kLessEqual,
    kGreaterEqual
  };

  ACRX_DECLARE_MEMBERS(AmdtItemFilterCustom);
  AmdtItemFilterCustom();
  ///<summary>Returns the name of the filter, which will be displayed in the parts list dialog box.</summary>
  virtual CString name() const;
  ///<summary>Retrieves the filter type.</summary>
  ///<returns>Returns Acm::kFilterCustom.</returns>
  virtual Acm::FilterType type() const;
  ///<summary>This function is called to prepare a filter for use.</summary>
  virtual Acad::ErrorStatus makeFilterReady();

  virtual bool evaluate(const AcDbObjectId& rowId) const;
  ///<summary>Returns if the filter is excluded from evaluation or not.</summary>
  virtual bool excluded() const;

  void set(const ACHAR* colName, Operators oper, const ACHAR* string);
  Operators oper() const;
  const ACHAR* string() const;
  const ACHAR* attrib() const;

protected:
  ///<summary>Retrieves the COM class ID associated to the class.</summary>
  ///<param name="pClsid">Returns the COM class ID.</param>
  ///<returns>Returns Acad:eOk if the COM class ID is retreived successfully.</returns>
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;

private:

  bool setupDataType();
};

///<summary>This is class AmdtItemFilterStdParts.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtItemFilterStdParts : public AmdtItemFilterCustom
{
public:
  ///<summary>Enumerates all available filter options for a Parts List Standard parts filter.</summary>
  enum FilterOption {
    ///<summary>Specifies a Standard parts filter that filters the contents of a Parts List by Standard parts.</summary>
    kStdPartsOnly = 0,
    ///<summary>Specifies a Standard parts filter that filters the contents of a Parts List by non-Standard parts.</summary>
    kExcludeStdParts
  };

public:
  ACRX_DECLARE_MEMBERS(AmdtItemFilterStdParts);
  AmdtItemFilterStdParts();
  ///<summary>Returns the name of the filter, which will be displayed in the parts list dialog box.</summary>
  virtual CString name() const;
  ///<summary>Retrieves the filter type.</summary>
  ///<returns>Returns Acm::kFilterStdParts.</returns>
  virtual Acm::FilterType type() const;
  ///<summary>This function is called to prepare a filter for use.</summary>
  virtual Acad::ErrorStatus makeFilterReady();

  ///<summary>Sets the filter option.</summary>
  ///<param name="enOption">Input parameter. Specifies the filter option to set.Input parameter. 
  ///Refer to the AmdtItemFilterStdParts::FilterOption for the available filter options.</param>
  void setOption(FilterOption enOption);
  ///<summary>Retrieves the filter option.</summary>
  ///<returns>Returns one of the enumerated item from the AmdtItemFilterStdParts::FilterOption enumerated type.</returns>
  AmdtItemFilterStdParts::FilterOption option() const;

protected:
  ///<summary>Retrieves the COM class ID associated to the class.</summary>
  ///<param name="pClsid">COM class ID.</param>
  ///<returns>Returns Acad::eOk if the COM class ID is reteived successfully.</returns>
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;
};

///<summary>This is class AmdtItemFilterBalloonedOnly.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtItemFilterBalloonedOnly : public AmdtItemFilter
{
public:
  ACRX_DECLARE_MEMBERS(AmdtItemFilterBalloonedOnly);
  AmdtItemFilterBalloonedOnly();
  ///<summary>Returns the name of the filter, which will be displayed in the parts list dialog box.</summary>
  virtual CString name() const;
  ///<summary>Retrieves the filter type.</summary>
  ///<returns>Returns Acm::FilterBallooned.</returns>
  virtual Acm::FilterType type() const;

  virtual bool evaluate(const AcDbObjectId& rowId) const;
  ///<summary>This function is called to prepare a filter for use.</summary>
  virtual Acad::ErrorStatus makeFilterReady();
  virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler* pFiler);
  ///<summary>Returns if the filter is excluded from evaluation or not.</summary>
  virtual bool excluded() const;

  virtual Acad::ErrorStatus subErase(Adesk::Boolean erasing);

protected:
  ///<summary>Retrieves the COM class ID associated to the class.</summary>
  ///<param name="pClsid">Returns the COM class ID.</param>
  ///<returns>Returns Acad::eOk if the COM class ID is retrieved successfully.</returns>
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;
};

///<summary>A utility class for Parts List filters.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtItemFilterUtil
{
public:
  ///<summary>The constructor.</summary>
  AmdtItemFilterUtil();
  ///<summary>The destructor.</summary>
  virtual ~AmdtItemFilterUtil();

public:
  ///<summary>Retrieves the filter name of a specified filter type.</summary>
   //<param name="enType">Input parameter. Specifies the filter type to retrieve the filter name.Input parameter. 
   ///Refer to the Acm::FilterType enumerated type for the available filter types.</param>
  ///<returns>Returns the filter name string.</returns>
  CString filterName(Acm::FilterType enType) const;

  ///<summary>Retrieves the filter type of a specified filter name.</summary>
  ///<param name="strName">Input parameter. Specifies the filter name to retrieve the filter type.</param>
  ///<param name="enType">Output parameter. Returns the filter type of the specified filter name.</param>
  ///<returns>Returns true if the filter type of the specified filter name is found.</returns>
  bool filterType(CString strName, Acm::FilterType& enType) const;

  ///<summary>Specifies whether a filter type is excluded from use in the current context.</summary>
  ///<param name="enType">Input parameter. Specifies the filter type to retrieve the exclusion state.Input parameter. 
  ///Refer to the Acm::FilterType enumerated type for the available filter types.</param>
  ///<param name="bUpdate">Input parameter. Default is true. 
  ///Specifies whether the exclusion state is to be evaluated and updated in the current context before retrieving the state.</param>
  ///<returns>Returns true if the filter is excluded from use in the current context.</returns>
  bool filterExcluded(Acm::FilterType enType, bool bUpdate = true);

  ///<summary>Checks if a filter type is valid for use by a Parts List in the current context.</summary>
  ///<param name="enType">Input parameter. Specifies the filter type to check.Input parameter. 
  ///Refer to the Acm::FilterType enumerated type for the available filter types.</param>
  ///<param name="pPartList">Input parameter. Default is NULL. Specifies a Parts List to validate the filter type.
  ///Input parameter. Default is NULL. This part of the validation is ignored if no Parts List is specified.</param>
  ///<returns>Returns true if the filter is valid for use by the specified Parts List in the current context.</returns>
  bool filterValid(Acm::FilterType enType, const AcmPartList* pPartList = NULL);

private:
  AmdtItemFilterUtilImp* m_pFilterUtilImp;
};

#endif