#if !defined(AFX_DlgObjectProperties_H__AF411833_39CE_4B0D_A270_FE0CD3E73C32__INCLUDED_)
#define AFX_DlgObjectProperties_H__AF411833_39CE_4B0D_A270_FE0CD3E73C32__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DlgObjectProperties.h : header file
//

//!!!!!WARNING!!!!!
// If you change any of the below typedefs you will have to be carefull to maintain the Allocate_... functions
// which support them. They need to know how to point internally to the various portions of the data when allocated
// since none of them use fixed size arrays internally.
//

  typedef BOOL (_stdcall * FileFilterCallback)(LPCSTR szCurrentFileName);
  typedef enum {
      eSingleSubdirectory = 0,
      eRootOnly,
      eAllSubdirectories
  } DIRECTORYSEARCHTYPE;
    
  typedef enum {
    efloat =0,
    eint,
    eLPSTR,
    eBOOL,
    eVector3D
  } CDOPVARTYPE;

  typedef struct _TAG_CDOPPROPERTIES_TO_EDIT_ENTRY
  {
    char        szPropertyTag[128]; // should be formated as <page name>\<entry name>
    char        szPropertyTagForDisplay[48]; // for header column
    CDOPVARTYPE ePropertyType;      // should be one of the above enum types, if more are added they
                                    // need to be added to the below union, and to the code that switches
                                    // based on the variable type
    //
    // The below do not need to be initialized. But since we don't copy the structure and use the
    // pointer passed in instead it allows you to use the values in fPresent and uPropValue on return
    // from the function if you need to use the data after calling DoModal() on the dialog;
    //
    UINT        uiReserved1_CTRLID;
  } CDOPPROPERTIES_TO_EDIT_ENTRY;


  typedef struct _TAG_CDOPPROPERTIES_TO_EDIT_ARRAY
  {
    int nCount;
    CDOPPROPERTIES_TO_EDIT_ENTRY * ppProperties_To_Edit_Entry[1];// using 1 just to set the memory, actual buffer is bigger when allocated and assigned
  } CDOPPROPERTIES_TO_EDIT_ARRAY;


  typedef struct _TAG_CDOPPROPERTYVALUE
  {
    BOOL        fPresent;
    union {
      int nValue;
      float fltValue;
      BOOL  fValue;
      char szValue[128];
      struct {
        float x;
        float y;
        float z;
      } v3dValues; // for vector3d type values
    } uPropValue;


  } CDOPPROPERTYVALUE;

  typedef struct _TAG_CDOPPROPERTIES_OBJECT_PROPERTIES
  {
    int nProperties; // must match nCount from CDOPPROPERTIES_TO_EDIT_ARRAY!!!!!!
    BOOL fDirty;
    BOOL fReadOnly;
    char szObjectName[MAX_PATH+1];
    CDOPPROPERTYVALUE  * ppObjectProperties[1]; // using 1 just to set the memory, actual buffer is bigger when allocated and assigned
  } CDOPPROPERTIES_OBJECT_PROPERTIES;

  typedef struct _TAG_CDOPPROPERTIES_OBJECT_LIST
  {
    int nObjectCount;
    CDOPPROPERTIES_OBJECT_PROPERTIES * ppPropertiesArray[1];// using 1 just to set the memory, actual buffer is bigger when allocated and assigned
  } CDOPPROPERTIES_OBJECT_LIST;

/////////////////////////////////////////////////////////////////////////////
// CDlgObjectProperties dialog


class CDlgObjectProperties : public CDialog
{


public:
                           


public:
  // Construction
public:
	CDlgObjectProperties(CWnd* pParent = NULL);   // standard constructor
  ~CDlgObjectProperties();
// Dialog Data
	//{{AFX_DATA(CDlgObjectProperties)
	enum { IDD = IDD_OBJECTPROPERTIES };
	CListBox	m_lbObjectList;
	//}}AFX_DATA


// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CDlgObjectProperties)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:

	// Generated message map functions
	//{{AFX_MSG(CDlgObjectProperties)
	virtual BOOL OnInitDialog();
	afx_msg void OnSelchangeObjectlist();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
  void CreateSubControlsForProperties();
  void ClearObjectDataSet();
  BOOL SaveObjectData();
  BOOL LoadObjectData(LPCSTR szDirectoryToSearchFor /*Directory passed in must end in a backslash*/, DIRECTORYSEARCHTYPE eSearchType);
  BOOL LoadDataFilesFromSubdirectory(CString strSubdirectory);
  BOOL LoadObjectDataFromFile(CString strFullWeaponFilename, BOOL fReadOnly );
  void OnOK();
  void OnCancel();
  BOOL DisableAllControls();
  BOOL EnableControlsForCurrentSelection();
  BOOL MoveCurSelDataToOrFromControls(BOOL fToControls);
       
public:
  //
  // These functions have to be called before DoModal is called since they set important information
  //

  // 
  // Sets the root directory to search under. Only goes one level deep currently
  //
  BOOL SetObjectFilesDirectory(LPCSTR lpszDirectoryPath); 
  //
  // Sets the root file name type to search for like "*.data"
  //
  BOOL SetFileNameToSearchSubdirectoriesFor(LPCSTR lpszFileSearchString);
  //
  // Allows additional control over what files are accepted. ie... you can filter out "basic.data"
  //
  BOOL SetFileFilterCallBack(FileFilterCallback fnFilterFunction)
  {
    m_fnFilterFunction = fnFilterFunction;
    return TRUE;
  };
  //
  // Specify the properties of the files that you want editted here.
  //
  //
  // !!!WARNING: We only store the pointer, we don't copy the data so be sure to 
  //  verify that the data is in scope the whole time the dialog is up.
  //
  BOOL SetPropertyListToEdit(CDOPPROPERTIES_TO_EDIT_ARRAY * ppteaPropertyToEdit)
    {m_paPropertiesToEdit = ppteaPropertyToEdit; return TRUE;};

  // Specifies whether the list box should show the whole name of the object including
  // directory path. Cuts off everything up until the last "\"
  BOOL ShowFullObjectNames(BOOL fShowFullObjectName) 
    {m_fShowFullObjectName = fShowFullObjectName; return TRUE;}; 
  // Specifies whether the static for each property should show the whole name including
  // the page name or just the entry name
  BOOL ShowFullPropertyName(BOOL fShowFullPropertyName) 
    {m_fShowFullPropertyName = fShowFullPropertyName; return TRUE;}; 
  // Specify whether you want to search just the root directory, the 
  // first subdirectory or all subdirectories
  BOOL SetSearchWhichSubdirectories(DIRECTORYSEARCHTYPE eSearchType)
    {m_eSearchType = eSearchType; return TRUE;};
  
  
  //
  // These structure have to be setup correctly when allocated and should never be created on the stack
  // 
  //
  CDOPPROPERTIES_TO_EDIT_ARRAY * Allocate_CDOPPROPERTIES_TO_EDIT_ARRAY(int nPropertyCount, CDOPPROPERTIES_TO_EDIT_ARRAY * * ppCDOPPROPERTIES_TO_EDIT_ARRAY = NULL);
  CDOPPROPERTIES_OBJECT_PROPERTIES * Allocate_CDOPPROPERTIES_OBJECT_PROPERTIES(int nPropertyCount, CDOPPROPERTIES_OBJECT_PROPERTIES * * ppCDOPPROPERTIES_OBJECT_PROPERTIES = NULL);
  CDOPPROPERTIES_OBJECT_LIST * Allocate_CDOPPROPERTIES_OBJECT_LIST(int nObjectCount, int nPropertyCount, CDOPPROPERTIES_OBJECT_LIST ** ppCDOPPROPERTIES_OBJECT_LIST = NULL);
  //
  // Memcpy and memcmp can not be used on these structures since they contain pointers to memory
  //
  BOOL Copy_CDOPPROPERTIES_TO_EDIT_ARRAY(CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY_DEST, CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY_SRC);
  BOOL Copy_CDOPPROPERTIES_OBJECT_PROPERTIES(CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST, CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC);
  BOOL Copy_CDOPPROPERTIES_OBJECT_LIST(CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST_DEST, CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST_SRC);
  BOOL IsEqual_CDOPPROPERTIES_TO_EDIT_ARRAY(CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY1, CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY2);
  BOOL IsEqual_CDOPPROPERTIES_OBJECT_PROPERTIES(CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES1, CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES2);
  BOOL IsEqual_CDOPPROPERTIES_OBJECT_LIST(CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST1, CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST2);
  //
  // This function allows you to create the properties array easily by calling this function with the format:
  //    CreatePropertiesToEditArray(2, 
  //                                  efloat, "GameData\Heat",
  //                                  eint, "GameData\Ammo");
  //
  CDOPPROPERTIES_TO_EDIT_ARRAY * CreatePropertiesToEditArray(int nCount, ...);


  BOOL UpdateControlData(BOOL fToControls);
  LPCSTR GetEntryNameToPropertyName(LPCSTR szPropertyName);
  LPCSTR GetPageNameToPropertyName(LPCSTR szPropertyName) ;

  // Override to do parameter checking

  virtual int DoModal();

protected:
  BOOL GetBOOLFromControl(UINT uiID, BOOL * pfDest);
  BOOL GetfloatFromControl(UINT uiID, float * pfltDest);
  BOOL GetLPSTRFromControl(UINT uiID, LPSTR pszDest);
  BOOL GetintFromControl(UINT uiID, int * pnDest);
  BOOL GetVector3DFromControl(UINT uiID, float * pfltx, float * pflty, float * pfltz);
  BOOL GetBOOLFromButton(UINT uiID, BOOL * pfDest);
  BOOL SetBOOLToButton(UINT uiID, BOOL fSrc);
  BOOL SetBOOLToControl(UINT uiID, BOOL fSrc);
  BOOL SetfloatToControl(UINT uiID, float fltSrc);
  BOOL SetLPSTRToControl(UINT uiID, LPSTR pszSrc);
  BOOL SetintToControl(UINT uiID, int nSrc);
  BOOL SetVector3DToControl(UINT uiID, float fltx, float flty, float fltz);



  // Data

  // Object list, these are the "files" that we are editting.
  CDOPPROPERTIES_OBJECT_LIST  * m_pObjectList;

  // This is the properties list that the caller is requesting. It is just a pointer to
  // the callers memory. 
  CDOPPROPERTIES_TO_EDIT_ARRAY * m_paPropertiesToEdit;

  // Root directory to search in
  CString m_strObjectFilesRootDirectory;

  // Wild card specification for what files we are looking for ie... "*.data"
  CString m_strFileNameToSearchSubdirectoriesFor;

  // Currently selected index in the list box control
  int m_nCurSel;

  // This function if specified gets called for ever file we think should be added
  // it will 
  FileFilterCallback m_fnFilterFunction;
  BOOL m_fShowFullObjectName;
  BOOL m_fShowFullPropertyName;
  DIRECTORYSEARCHTYPE m_eSearchType;
  CDOPPROPERTIES_OBJECT_PROPERTIES * m_popCurObjectPropertiesArray;
  UINT m_nLastControlID;
  BOOL m_fDirty;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DlgObjectProperties_H__AF411833_39CE_4B0D_A270_FE0CD3E73C32__INCLUDED_)
