#if !defined(AFX_APLEXLISTCTRL_H__BED707A4_303D_4F32_8073_5BAAA32E41A__INCLUDED)
#define AFX_APLEXLISTCTRL_H__BED707A4_303D_4F32_8073_5BAAA32E41A__INCLUDED

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

/////////////////////////////////////////////////////////////////////////////
// CaplExListCtrl window

#include "AplGuiEx.h"

class CaplExListItem;

struct CaplModeStruct
{
	aplEditTypes mode;
	int bShared;
	CStringArray *pStrs;
	CaplModeStruct() {mode = aplNone; pStrs = NULL;}
	void Free() 
	{ 
		if((bShared == 0)&&pStrs) 
			delete pStrs; 
		pStrs = NULL;
	}
	void Copy(aplEditTypes mo, CStringArray *ps, int bS)
	{
		if(pStrs && (bShared == 0)) delete pStrs; 
		pStrs = NULL;
		mode = mo;
		bShared = bS;
		if(ps)
		{
			if(!bS)
			{
				pStrs = new CStringArray;
				pStrs->Copy(*ps);
			}
			else
				pStrs = ps;
		}
	}
	void Copy(const CaplModeStruct &cms, int bS)
	{
		Copy(cms.mode, cms.pStrs, bS);
	}
	CaplModeStruct(aplEditTypes mo, CStringArray *ps, int bS)
	{
		pStrs = NULL;
		Copy(mo, ps, bS);
	}
};

struct CaplHeaderStruct : public CaplModeStruct
{
	int  iSortType;
	CaplHeaderStruct() {iSortType = 0;}
	CaplHeaderStruct(aplEditTypes mo, CStringArray *ps, int bS)
		: CaplModeStruct(mo,ps,bS)
	{
		iSortType = 0;
	}
};

//typedef CArray<CStringArray *,CStringArray *> CStringArrayArray;
typedef CArray<CaplModeStruct, CaplModeStruct &> CaplModeStructArray;

// строка в заголовке
class CaplExHeaderRow
{
public:
	int m_countItems;
	CHeaderCtrl m_hc;

	static int m_HH;

	CaplExHeaderRow(CWnd *par, int n, int Id, CFont &fo, bool bBorder);
	CaplExHeaderRow *m_subHeader;
	void InsertItem(int p, LPTSTR text, int w, UINT fmt, aplEditTypes mode = aplNone, CStringArray *pStrs=NULL);
	void DeleteItem(int p);
	void SetModes(CaplExListItem *li, int b, int e);
	int  Width();
	void SetWidth(int w);
	void SetWidthProp(int w);
	void HScroll(int pos, CRect &pre, int nb);
	void Clear();
	int  GetSortType(int n, bool bRevers);
	bool Split(int col, int count);
	void SetEnableSort(bool bSort);
	~CaplExHeaderRow() {Clear();}
};



// закладка
class CaplBookmarkItem
{
public:
	POSITION m_itempos;
	POSITION m_bmpos;
	int m_count;
	int m_absCount;
	CaplBookmarkItem(POSITION itp, int ac)
	{m_itempos = itp; m_count = 1; m_absCount = ac; m_bmpos = NULL;}
};

typedef CList<CaplBookmarkItem *, CaplBookmarkItem *> CBMList;

typedef CArray<aplEditTypes, aplEditTypes> CModeArray;


// непоcредственно элемент списка
class CaplExListItem
{
public:
	CaplExHeaderRow *m_header;
	CaplBookmarkItem *m_bookmark;
	CaplExListCtrlContent *m_subItems;
	CaplExListCtrlContent *m_thisList;
	CaplExListItem *m_parentItem;
//	SEditInfo *m_editInfo;
//	CStringArrayArray m_strsCombo;
//	CWordArray m_modes;
	int m_childCount;
	int m_absCount;
	int m_imageIndex;
	CStringArray m_cells;
	CaplModeStructArray m_smodes;
	DWORD m_data;
	void IncAbs(int n);
	void DecAbs(int n);
	CaplExListItem(CaplExListItem *parent);
	~CaplExListItem();
	void SetMode(int n, aplEditTypes mode, CStringArray *pStrs, int bS);
	void SetHeader(CaplExHeaderRow *h);
	aplEditTypes GetMode(int cell, CStringArray *&pStrs);

	void ResetArrays(bool text, bool mode);

	static int  menshe(CaplExListItem *fi, CaplExListItem *si, int pos);
	static int  bolshe(CaplExListItem *fi, CaplExListItem *si, int pos);
	bool GetInfo(int x, CRect &re, int &cell);
	void DelCell(int c);
	void AddCells(int b, int co);

	void Paint(CDC &dc, CRect &re, bool grid, bool sel, int iw, CImageList *pImageList);
	static int m_nDefRowHeight;
	static CPen m_gridPen;
	static bool m_Repaint;
	static COLORREF m_selColor;
};

typedef CList<CaplExListItem *, CaplExListItem *> CLIListBase;

class CLIList : public CLIListBase
{
protected:
	void Cut(CNode * from, int n, CLIList &dest);
public:
	void Sort(int pos, int (*fncmp)(CaplExListItem *,CaplExListItem *,int));
	bool MoveUp(POSITION pos);
	bool MoveDown(POSITION pos);
	static CaplExListItem *GetItemByHLI(HLISTITEM item);
	static HLISTITEM GetNextHLI(HLISTITEM item, bool bNext);
};

typedef void(*LPFN_ENUMLEVELLIST)(CaplExListCtrlContent *, int, int);

// список
class CaplExListCtrlContent
{
	static int m_bookmarkInt;
	static int m_bookmarkMaxIntInsert;
	static int m_bookmarkMaxIntAdd;
	static int m_bookmarkMinInDel;
	static CString m_sEmptyStr;
	static CaplExListCtrlContent *m_listWithSel;
public:
	DWORD m_data;
	CBMList m_bookmarks;
	CLIList m_items;
	int m_absCount;
	CaplExListCtrlContent *m_parentList;
	CaplExHeaderRow *m_header;
	POSITION m_parentItem;
	bool m_bExpanded;
	CaplExListCtrlContent();
	~CaplExListCtrlContent(){DeleteAll();}
	
	POSITION GetAt(int n);    // для вставки, удаления, вообще доступа по индексу
	POSITION Insert(CaplExListItem *item, POSITION pos);
	POSITION Add(CaplExListItem *item);
	void Delete(int pos);
	void Delete(POSITION pos);
	void DeleteAll();
	const CString &GetItemText(POSITION p, int i);
	bool SetItemText(POSITION p, int i, LPCTSTR str);
	bool SetItemData(POSITION p, DWORD da);
	DWORD GetItemData(POSITION p);
	int GetAbsIndex(POSITION p);  //для EnsureVisible & SelectItem

	bool MoveUp(POSITION pos);
	bool MoveDown(POSITION pos);

	static void Sort(CaplExListCtrlContent *lst, int sortcol, int type);
	static void DelCell(CaplExListCtrlContent *lst, int delcol, int p);
	static void AddCells(CaplExListCtrlContent *lst, int addcol, int n);
	void EnumLevelLists(int level, LPFN_ENUMLEVELLIST fn, int p1, int p2);

	void Paint(CDC &dc, int b, CRect &re, bool grid, int iw, CImageList *pImageList);
	int  Height();
	static void GetAbsAt(int n, POSITION &itempos, CaplExListCtrlContent *&lst); // для доступа по абсолютному номеру (при скроллинге)
	static void GetAbsNextItem(POSITION &itempos, CaplExListCtrlContent *&lst);
	static POSITION sm_curSel;
};


#endif