#pragma once

#include "resource.h"
class CINKSDoc;
class CINKSView;
#include <Map>
class CCommonObject;

class CTreeItem
{
	friend class CTreeBar;
public:
	CTreeItem(CString strNodeName, CString strDisplay, CString strOrigin, HTREEITEM hItem, CTreeItem *pParent = NULL, int nType = -1);
	~CTreeItem();
	void SetModifiedInSession(bool bModified) {m_bModified = bModified;}
	void SetDoc(CINKSDoc *pDoc) {m_pDoc = pDoc;}
	void SetView(CINKSView *pView) {m_pView = pView;}
	bool FileInProject() {return m_bFileInProject;}
	int GetType() {return m_nType;}
	CTreeItem* GetParent() {return m_pParent;}

private:
	bool NeedUpdate() {return m_bNeedUpdate;}
	void SetNeedUpdate(bool bNeedUpdate) {m_bNeedUpdate = bNeedUpdate;}
	bool ModifiedInSession() {return m_bModified;}

public:
	CArray<CTreeItem*, CTreeItem*> m_arrayContent;
	CMap<CString, LPCTSTR, CTreeItem*, CTreeItem*> m_mapContent;
	HTREEITEM m_hItem;
	CString m_strNodeName;
	CString m_strDisplayName;
	CString m_strFilename;
	CString m_strOrigin;
	CStringList m_slContent;
	bool m_bFileInProject;
	CINKSDoc *m_pDoc;
	bool m_bItemOK;
	bool m_bNeedUpdate;		// if missing some files

private:
	CTreeItem *m_pParent;
	
	CINKSView *m_pView;
	int m_nType;			// 0-Project; 1-Scheme; 2-Block; 3-Gate; 4-Wire; 5-Tag
	bool m_bModified;		// if modified in this session (from last save)


};

class CTreeBar : public CDialogBar
{
	DECLARE_DYNAMIC(CTreeBar)


public:
	CTreeBar(CWnd* pParent = NULL);   // standard constructor
	virtual ~CTreeBar();

	BOOL Create(CWnd *pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
	CTreeItem* AddTreeItem(CString strName, CString strOrigin, CTreeItem *sParent, int nType, bool bFileInProject, CString strAppendDisplayName, bool bCreatedInSession = false);
	
	void RemoveAll();
	CTreeItem* RegisterNewCommonObject(CString strName, CString strOrigin, CString strParent, int nType, bool bFileInProject, CINKSDoc *pDoc); // when adding new elements to opened scheme/block
	CTreeItem* RegisterNewCommonObject(CCommonObject *pObj, CINKSDoc *pDoc); // when adding new elements to opened scheme/block
	bool CanDeregisterCommonObject(CString strName, CINKSDoc *pOwnerDoc);
	void DeRegisterCommonObject(CString strName, CINKSDoc *pOwnerDoc);

	void OpenElement(CTreeItem *pItem);				// opens scheme | block (pDoc->onopenfile()) (for dblclk);;pObj = if opening block, need to remember its drawing info(CommonObject*)
	CTreeItem* OpenElement(HTREEITEM hItem);		// opens scheme | block (pDoc->onopenfile()); returns *CTreeItem that is opened (for dblclk)

	void PushIntoTheBlock(CString strName, CString strParent, CINKSDoc *pOwnerDoc);		// opens file strName if visible, expands strParent and opens strName otherwise
	void PushOutOfTheBlock(CString strName);
	void SetModified(CTreeItem *pItem, bool bModified = true);
	void SetErrorItem(CTreeItem *pItem);
	void SetSelectedItem(CString strName);
	void OutXlmContent(CString strElemName, stringstream &ss);
	CTreeItem* GetProjectItem();
	

private:
	void AddDummyChild(CTreeItem *pParent);
	CTreeItem* GetTreeItem(HTREEITEM hItem);
	CTreeItem* GetTreeItem(CString strItem, CTreeItem *pParent);
	
	void PopulateItem(CTreeItem *pItem);
	void DeleteChildren(CTreeItem *pItem);
	bool FileExists(CString strFilename, bool bInProject);
	bool CheckItem(CTreeItem *pItem); // checks if item has correct source (orogin file, etc.)
	bool IsItemExpanded(HTREEITEM hItem);
	bool EnsureExpanded(CTreeItem *pItem);

public:
	CTreeCtrl *m_pSchemeTree;
	CString m_strProjectFilename;
	CString m_strProjectPath;
	CString m_strAppPath;
	CMap<CString, LPCTSTR, CTreeItem*, CTreeItem*> m_mapContent;
	CTreeItem *m_pSelectedItem;

private:
	CImageList m_ImgList;
	
// Dialog Data
	enum { IDD = IDD_TREEBAR };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnTvnItemexpandingTree1(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnNMDblclkTree1(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnNMRclickTree1(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnProjecttypeCreatenewscheme();
	afx_msg void OnSchemetypeCollapseintoblock();
public:
	afx_msg void OnSchemetypeDelete();
};
