// NewTreeListCtrlView.cpp : implementation of the CaplTreeListCtrlView class
//

#include "stdafx.h"
#include "resource.h"

#include "apl_gui.h"
#include "HtmlGen.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#define ID_EDIT_FIELD   333
#define ID_TREE_LIST_HEADER 337
#define ID_TREE_LIST_CTRL   373
#define ID_TREE_LIST_SCROLLBAR   377


/////////////////////////////////////////////////////////////////////////////
// CaplTreeListCtrlView

IMPLEMENT_DYNCREATE(CaplTreeListCtrlView, CView)


BEGIN_MESSAGE_MAP(CaplTreeListCtrlView, CView)
	//{{AFX_MSG_MAP(CaplTreeListCtrlView)
	ON_WM_MOUSEACTIVATE()
	ON_WM_SIZE()
	ON_WM_HSCROLL()		
	ON_WM_CONTEXTMENU()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEWHEEL()
	ON_WM_VSCROLL()
	//}}AFX_MSG_MAP
	// Standard printing commands	
	ON_WM_CREATE()
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CaplTreeListCtrlView construction/destruction

CaplTreeListCtrlView::CaplTreeListCtrlView()
	: CView()
{
	m_TLInitialized=FALSE;	
	m_CurrentProgress=0;
	m_bAutofit=false;
	m_nImageId= -1;
	m_bBreakTooltips=false;
	m_LastSortCol = 0;
	m_bAscendingSort = FALSE;
	m_bUseCheckboxes=false;
	m_bUseEditlabels=false;
	n_bNoParentNotify=false;
	m_bManualInit=false;
}

CaplTreeListCtrlView::~CaplTreeListCtrlView()
{
}

CaplTreeListCtrlView *CaplTreeListCtrlView::CreateTreeListView(CWnd *parent, RECT rect, int id)
{
	if(parent==0) return 0;

	CaplTreeListCtrlView *view=
		(CaplTreeListCtrlView*)(RUNTIME_CLASS(CaplTreeListCtrlView)->CreateObject());
	ASSERT(view);
	if(view!=0)
	{
		view->Create(0,0,WS_BORDER|WS_VISIBLE|WS_CHILD|AFX_WS_DEFAULT_VIEW,rect,parent,id);
		view->OnInitialUpdate();
		view->MoveWindow(&rect);
	}
	return view;
}

/////////////////////////////////////////////////////////////////////////////
// CaplTreeListCtrlView diagnostics

#ifdef _DEBUG
void CaplTreeListCtrlView::AssertValid() const
{
	CView::AssertValid();
}

void CaplTreeListCtrlView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}



#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CaplTreeListCtrlView message handlers

void CaplTreeListCtrlView::OnInitialUpdate() 
{
	if(m_tree.m_wndHeader.m_hWnd!=0) return;
	CView::OnInitialUpdate();
	
	Initialize();	

	// create image list for tree
	//m_cImageList.Create(IDB_TREE_PICTURES, 16, 10, RGB(255, 255, 255));

//	m_cImageList.Create(IDB_TREE_PICTURES, 20, 10, RGB(255, 255, 255));/*!!!*/
	m_tree.SetImageList(&m_cImageList, TVSIL_NORMAL);

	CRect m_wndRect;
	GetClientRect(&m_wndRect);
	MoveWindow(0, 0, m_wndRect.Width(), m_wndRect.Height());
/*
	m_tooltip.Create(this);
	m_tooltip.Activate(TRUE);
	m_tooltip.AddTool(GetDlgItem(ID_TREE_LIST_CTRL),_T(" "));
*/
	m_tree.m_wndHeader.SetFont(m_tree.GetFont(),FALSE);
	m_TLInitialized = TRUE;		

//	m_tree.m_pwndHeader=m_wndHeader;
}


/////////////////////////////////////////////////////////////////////////////
// CaplTreeListCtrlView message handlers

LONG FAR PASCAL CaplTreeListCtrlView::DummyWndProc(HWND h, UINT u, WPARAM w, LPARAM l)
{
	return ::DefWindowProc(h, u, w, l);
}

void CaplTreeListCtrlView::Initialize()
{
	// creates all the objects in frame -
	// header, tree, horizontal scroll bar
	if(m_tree.m_wndHeader.m_hWnd!=0) return;
	
	CaplSetResourceHandle setres(module_inst);

	CRect m_wndRect;
	GetWindowRect(&m_wndRect);
	CRect m_headerRect;

	// create the header
	if(m_tree.m_wndHeader.m_hWnd==0)
	{
		m_headerRect.left = m_headerRect.top = -1;
		m_headerRect.right = m_wndRect.Width();

		m_tree.m_wndHeader.Create(WS_CHILD | WS_VISIBLE | HDS_BUTTONS | HDS_HORZ, m_headerRect, this, ID_TREE_LIST_HEADER);
	}

	CSize textSize;
	// set header's pos, dimensions and image list
	{
		CDC *pDC = m_tree.m_wndHeader.GetDC();
		pDC->SelectObject(&m_tree.m_headerFont);
		textSize = pDC->GetTextExtent(_T("A"));
		m_tree.m_wndHeader.ReleaseDC(pDC); 

		m_tree.m_wndHeader.SetWindowPos(&wndTop, -1, -1, m_headerRect.Width(), textSize.cy+4, SWP_SHOWWINDOW);

		m_tree.m_cImageList.Create(IDB_HEADER, 10, 2, RGB(192,192,192));
		m_tree.m_wndHeader.SetImageList(&m_tree.m_cImageList);		
		m_tree.m_wndHeader.ReleaseDC(pDC);
	}

	CRect m_treeRect;

	// create the tree itself
	{
		GetWindowRect(&m_wndRect);

		m_treeRect.left=0;
		m_treeRect.top = textSize.cy+4;
		m_treeRect.right = m_headerRect.Width()-5;
		m_treeRect.bottom = m_wndRect.Height()-GetSystemMetrics(SM_CYHSCROLL)-4;

		DWORD dwStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS |TVS_INFOTIP;
		if(m_bUseCheckboxes) dwStyle |= TVS_CHECKBOXES; 
		if(m_bUseEditlabels) dwStyle |= TVS_EDITLABELS; 
		m_tree.Create(dwStyle,m_treeRect, this, ID_TREE_LIST_CTRL);
	}

	// finally, create the horizontal scroll bar
	{
		CRect m_scrollRect;
		m_scrollRect.left=0;
		m_scrollRect.top = m_treeRect.bottom;
		m_scrollRect.right = m_treeRect.Width()-GetSystemMetrics(SM_CXVSCROLL);
		m_scrollRect.bottom = m_wndRect.bottom;

		m_horScrollBar.Create(WS_CHILD | WS_VISIBLE | WS_DISABLED | SBS_HORZ | SBS_TOPALIGN, m_scrollRect, this, ID_TREE_LIST_SCROLLBAR);
	}

	SortTree(0, TRUE, m_tree.GetRootItem());
}

BOOL CaplTreeListCtrlView::VerticalScrollVisible()
{	
	int sMin, sMax;
	m_tree.GetScrollRange(SB_VERT, &sMin, &sMax);	
	return sMax!=0;
}

BOOL CaplTreeListCtrlView::HorizontalScrollVisible()
{
	int sMin, sMax;
	m_horScrollBar.GetScrollRange(&sMin, &sMax);
	return sMax!=0;
}

int CaplTreeListCtrlView::StretchWidth(int m_nWidth, int m_nMeasure)
{	
	if(m_nMeasure==0) return 0;
	return ((m_nWidth/m_nMeasure)+1)*m_nMeasure;//put the fixed for +1 in brackets f/0 error
}


void CaplTreeListCtrlView::ResetScrollBar()
{
	// resetting the horizontal scroll bar

	int m_nTotalWidth=0, m_nPageWidth;

	CRect m_treeRect;
	m_tree.GetClientRect(&m_treeRect);

	CRect m_wndRect;
	GetClientRect(&m_wndRect);

	CRect m_headerRect;
	m_tree.m_wndHeader.GetClientRect(&m_headerRect);

	CRect m_barRect;
	m_horScrollBar.GetClientRect(m_barRect);

	m_nPageWidth = m_treeRect.Width();

	m_nTotalWidth = m_tree.GetColumnsWidth();

	if(m_nTotalWidth > m_nPageWidth)
	{
		// show the scroll bar and adjust it's size
		{
			m_horScrollBar.EnableWindow(TRUE);

			m_horScrollBar.ShowWindow(SW_SHOW);

			// the tree becomes smaller
			m_tree.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_wndRect.Height()-m_barRect.Height()-m_headerRect.Height(), SWP_NOMOVE);

			if(!VerticalScrollVisible())
				// i.e. vertical scroll bar isn't visible
			{
				m_horScrollBar.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_barRect.Height(), SWP_NOMOVE);
			}
			else
			{
				m_horScrollBar.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width() - GetSystemMetrics(SM_CXVSCROLL), m_barRect.Height(), SWP_NOMOVE);
			}
		}

		m_horScrollBar.SetScrollRange(0, m_nTotalWidth-m_nPageWidth);

		// recalculate the offset
		{
			CRect m_wndHeaderRect;
			m_tree.m_wndHeader.GetWindowRect(&m_wndHeaderRect);
			ScreenToClient(&m_wndHeaderRect);

			m_tree.m_nOffset = m_wndHeaderRect.left;
			m_horScrollBar.SetScrollPos(-m_tree.m_nOffset);
		}
	}
	else
	{
		m_horScrollBar.EnableWindow(FALSE);

		// we no longer need it, so hide it!
		{
			m_horScrollBar.ShowWindow(SW_HIDE);

			m_tree.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_wndRect.Height() - m_headerRect.Height(), SWP_NOMOVE);
			// the tree takes scroll's place
		}

		m_horScrollBar.SetScrollRange(0, 0);

		// set scroll offset to zero
		{
			m_tree.m_nOffset = 0;
			m_tree.Invalidate();
			CRect m_headerRect;
			m_tree.m_wndHeader.GetWindowRect(&m_headerRect);
			CRect m_wndRect;
			GetClientRect(&m_wndRect);
			m_tree.m_wndHeader.SetWindowPos(&wndTop, m_tree.m_nOffset, 0, max(StretchWidth(m_tree.GetColumnsWidth(),m_wndRect.Width()),m_wndRect.Width()), m_headerRect.Height(), SWP_SHOWWINDOW);
		}
	}
}

void CaplTreeListCtrlView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	CRect m_treeRect;
	m_tree.GetClientRect(&m_treeRect);
	
	// if horizontal scroll bar 
	if(pScrollBar == &m_horScrollBar)
	{
		int m_nCurPos = m_horScrollBar.GetScrollPos();
		int m_nPrevPos = m_nCurPos;
		// decide what to do for each diffrent scroll event
		switch(nSBCode)
		{
			case SB_LEFT:			m_nCurPos = 0;
									break;
			case SB_RIGHT:			m_nCurPos = m_horScrollBar.GetScrollLimit()-1;
									break;
			case SB_LINELEFT:		m_nCurPos = max(m_nCurPos-6, 0);
									break;
			case SB_LINERIGHT:		m_nCurPos = min(m_nCurPos+6, m_horScrollBar.GetScrollLimit()-1);
									break;
			case SB_PAGELEFT:		m_nCurPos = max(m_nCurPos-m_treeRect.Width(), 0);
									break;
			case SB_PAGERIGHT:		m_nCurPos = min(m_nCurPos+m_treeRect.Width(), m_horScrollBar.GetScrollLimit()-1);
									break;
			case SB_THUMBTRACK:
			case SB_THUMBPOSITION:  if(nPos==0)
									    m_nCurPos = 0;
								    else
									    m_nCurPos = min(StretchWidth(nPos, 6), m_horScrollBar.GetScrollLimit()-1);
								    break;
		}		

		m_horScrollBar.SetScrollPos(m_nCurPos);
		m_tree.m_nOffset = -m_nCurPos;

		// smoothly scroll the tree control
		{
			CRect m_scrollRect;
			m_tree.GetClientRect(&m_scrollRect);
			m_tree.ScrollWindow(m_nPrevPos - m_nCurPos, 0, &m_scrollRect, &m_scrollRect);
		}

		CRect m_headerRect;
		m_tree.m_wndHeader.GetWindowRect(&m_headerRect);
		CRect m_wndRect;
		GetClientRect(&m_wndRect);		

		m_tree.m_wndHeader.SetWindowPos(&wndTop, m_tree.m_nOffset, 0, max(StretchWidth(m_tree.GetColumnsWidth(),m_treeRect.Width()),m_wndRect.Width()), m_headerRect.Height(), SWP_SHOWWINDOW);
	}
	
	CView::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CaplTreeListCtrlView::SortTree(HTREEITEM hParent)
{
	if(m_LastSortCol>-1)
	{
		if(hParent==TVI_ROOT)
			SortTree(m_LastSortCol, m_bAscendingSort, m_tree.GetRootItem());
		else
			SortTree(m_LastSortCol, m_bAscendingSort, hParent);
	}
}

void CaplTreeListCtrlView::SortTree(int nCol, BOOL bAscending, HTREEITEM hParent)
{		
	HTREEITEM hChild=NULL;
	HTREEITEM hPa = hParent;
	
	while(hPa!=NULL)
	{
		if(m_tree.ItemHasChildren(hPa))
		{			
			m_tree.SortItems(nCol, bAscending, hPa);
			SortTree(nCol, bAscending, m_tree.GetChildItem(hPa));			
		}			

		hPa = m_tree.GetNextSiblingItem(hPa);
	}
	
	m_LastSortCol = nCol;
	m_bAscendingSort = bAscending;

	for(int i=0;i<m_tree.GetColumnsNum();i++)
	{
		m_tree.m_wndHeader.SetItemImage(i, -1);
	}

	if(bAscending)
		m_tree.m_wndHeader.SetItemImage(nCol, 0);
	else
		m_tree.m_wndHeader.SetItemImage(nCol, 1);

	/*else
	{	
		HTREEITEM ChildOfParent=NULL;
		HTREEITEM ChildOfPChild=NULL;
		while(hPa!=NULL)
		{
			if(m_tree.ItemHasChildren(hPa))
			{
				ChildOfParent=m_tree.GetChildItem(hPa);
				while(ChildOfParent!=NULL)
				{						
					m_tree.SortItems(nCol,bAscending,ChildOfParent);
					ChildOfParent = m_tree.GetNextSiblingItem(ChildOfParent);
				}
				
			}
			hPa = m_tree.GetNextSiblingItem(hPa);
		}	
	}*/	
}

BOOL CaplTreeListCtrlView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
{
	HD_NOTIFY *pHDN = (HD_NOTIFY*)lParam;
	
	if((wParam == ID_TREE_LIST_HEADER) && (pHDN->hdr.code == HDN_ITEMCLICK))
	{
		if(m_tree.m_bSortRoot)
		{
			int nCol = pHDN->iItem;

			BOOL bAscending = FALSE;

			if(m_tree.m_wndHeader.GetItemImage(nCol)==-1)
				bAscending = TRUE;
			else
			if(m_tree.m_wndHeader.GetItemImage(nCol)==1)
				bAscending = TRUE;

			/* 03.07.2017 Перенесено в SortTree
			for(int i=0;i<m_tree.GetColumnsNum();i++)
			{
				m_tree.m_wndHeader.SetItemImage(i, -1);
			}

			if(bAscending)
				m_tree.m_wndHeader.SetItemImage(nCol, 0);
			else
				m_tree.m_wndHeader.SetItemImage(nCol, 1);
			*/

			m_tree.SortItems(nCol, bAscending, NULL);
			SortTree(nCol, bAscending, m_tree.GetRootItem());
		}

		m_tree.UpdateWindow();
		
		CWnd *parent_wnd=GetParent();
		if(parent_wnd && parent_wnd->m_hWnd)
			parent_wnd->SendMessage(WM_NOTIFY, wParam, lParam);
	}
	else
	if((wParam == ID_TREE_LIST_HEADER) && (pHDN->hdr.code == HDN_ITEMCHANGED))
	{
		int m_nPrevColumnsWidth = m_tree.GetColumnsWidth();
		m_tree.RecalcColumnsWidth();
		ResetScrollBar();
		
		// in case we were at the scroll bar's end,
		// and some column's width was reduced,
		// update header's position (move to the right).
		CRect m_treeRect;
		m_tree.GetClientRect(&m_treeRect);
		
		CRect m_headerRect;
		m_tree.m_wndHeader.GetClientRect(&m_headerRect);
		
		if((m_nPrevColumnsWidth > m_tree.GetColumnsWidth()) &&
			(m_horScrollBar.GetScrollPos() == m_horScrollBar.GetScrollLimit()-1) &&
			(m_treeRect.Width() < m_tree.GetColumnsWidth()))
		{
			m_tree.m_nOffset = -m_tree.GetColumnsWidth()+m_treeRect.Width();
			m_tree.m_wndHeader.SetWindowPos(&wndTop, m_tree.m_nOffset, 0, 0, 0, SWP_NOSIZE);
		}	
		
		m_tree.Invalidate();
		
	}
	else
	{
		if((wParam == ID_TREE_LIST_CTRL) && (pHDN->hdr.code == TVN_SELCHANGED))
		{
			if(m_tree.m_dlg && n_bNoParentNotify == false)
			{
				NMHDR *pNMHDR = (NMHDR*)lParam;
				NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

				if(m_tree.m_dlg)
				{
					m_tree.m_dlg->ItemChange(pNMTreeView);
					return TRUE;
				}
			}
		}
		if (!n_bNoParentNotify)
		{
			CWnd *parent_wnd=GetParent();
			if(parent_wnd && parent_wnd->m_hWnd)
			{
				parent_wnd->SendMessage(WM_NOTIFY, wParam, lParam);
				if(parent_wnd->IsKindOf(RUNTIME_CLASS(CDialog)) && wParam==ID_TREE_LIST_CTRL)
				{
					parent_wnd->SendMessage(WM_NOTIFY, GetDlgCtrlID(), lParam);
				}
			}
		}
		return TRUE;
	}
	
	return CView::OnNotify(wParam, lParam, pResult);
}

void CaplTreeListCtrlView::OnContextMenu(CWnd* pWnd, CPoint point) 
{	
	GetParent()->SendMessage(WM_CONTEXTMENU, (WPARAM)pWnd, MAKELPARAM(point.x, point.y) ); 
}

void CaplTreeListCtrlView::OnSize(UINT nType, int cx, int cy) 
{
	SetScrollRange(SB_HORZ, 0, 0);
	SetScrollRange(SB_VERT, 0, 0);

	if(::IsWindow(m_tree.m_hWnd))
	{ // затычка для дырки при которой криво работаа структура работ в АЛП под Win7 при Release 
		CRect r1,r2;
		m_tree.m_wndHeader.GetWindowRect(r1);
		m_tree.GetWindowRect(r2);
		if(r1.top==r2.top)
		{
			//CString buf,buf1="Мовю виндов!";
			//buf.Format(" %i ",r1.bottom-r1.top);
			//buf1+=buf;
			//buf.Format("\n\n Rect 1 %i  %i  %i %i ",r2.left,r2.top, r2.right,  r2.bottom);
			//buf1+=buf;
			m_tree.ScreenToClient(&r2);
			//buf.Format("\n\n Rect 2 %i  %i  %i %i ",r2.left,r2.top, r2.right,  r2.bottom);
			//buf1+=buf;
			r2.top+=(r1.bottom-r1.top);
			m_tree.MoveWindow(r2,true);
			//AfxMessageBox(buf1);
		}
	}

	if(m_TLInitialized)
	{	
		// resize all the controls	
		CRect m_wndRect;
		GetClientRect(&m_wndRect);

		CRect m_headerRect;
		m_tree.m_wndHeader.GetClientRect(&m_headerRect);
		m_tree.m_wndHeader.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_headerRect.Height(), SWP_NOMOVE);

		CRect m_scrollRect;
		m_horScrollBar.GetClientRect(&m_scrollRect);

		m_tree.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_wndRect.Height() - m_scrollRect.Height(), SWP_NOMOVE);

		CRect m_treeRect;
		m_tree.GetClientRect(&m_treeRect);
		m_horScrollBar.MoveWindow(0, m_treeRect.bottom, m_wndRect.Width(), m_scrollRect.Height());

		if(m_tree.GetColumnsWidth() > m_treeRect.Width())
		{
			// show the horz scroll bar
			{
				CRect m_barRect;
				m_horScrollBar.GetClientRect(&m_barRect);			

				m_horScrollBar.EnableWindow(TRUE);

				m_horScrollBar.ShowWindow(SW_SHOW);

				// the tree becomes smaller
				m_tree.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_wndRect.Height()-m_barRect.Height()-m_headerRect.Height(), SWP_NOMOVE);

				int tfdsfsd=m_wndRect.Width() - GetSystemMetrics(SM_CXVSCROLL);
				m_horScrollBar.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width() - GetSystemMetrics(SM_CXVSCROLL), m_barRect.Height(), SWP_NOMOVE);
				
			}

			m_horScrollBar.SetScrollRange(0, m_tree.GetColumnsWidth()-m_treeRect.Width());

		}
		else
		{
			// hide the scroll bar
			{
				m_horScrollBar.EnableWindow(FALSE);

				m_horScrollBar.ShowWindow(SW_HIDE);

				// the tree becomes larger
				m_tree.SetWindowPos(&wndTop, 0, 0, m_wndRect.Width(), m_wndRect.Height()-m_headerRect.Height(), SWP_NOMOVE);				
			}

			m_horScrollBar.SetScrollRange(0, 0);
		}

		m_tree.ResetVertScrollBar();
		
		// Reset the header control position and scroll
		// the tree control as required.
		int m_nCurPos = m_horScrollBar.GetScrollPos();
		m_tree.m_nOffset = -m_nCurPos;
	
		// smoothly scroll the tree control
	    {
		CRect m_scrollRect;
		m_tree.GetClientRect(&m_scrollRect);
		m_tree.ScrollWindow(m_nCurPos, 0, &m_scrollRect, &m_scrollRect);
		}
		m_tree.m_wndHeader.GetWindowRect(&m_headerRect);	
		GetClientRect(&m_wndRect);

		m_tree.m_wndHeader.SetWindowPos(&wndTop, m_tree.m_nOffset, 0,max(StretchWidth(m_tree.GetColumnsWidth(),m_treeRect.Width()),m_wndRect.Width()), m_headerRect.Height(),SWP_SHOWWINDOW);			
		if(m_bAutofit) m_tree.m_wndHeader.SetAutofit();
	}
}

int CaplTreeListCtrlView::OnMouseActivate( CWnd* pDesktopWnd, 
                                  UINT nHitTest, 
                                  UINT message )
{
  return MA_ACTIVATE;
}

BOOL CaplTreeListCtrlView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	CWnd* parent = GetParent();
	if(parent)
		parent->SendMessage(WM_MOUSEWHEEL, (WPARAM)zDelta,MAKELPARAM(pt.x,pt.y));
	return -1;
}

void CaplTreeListCtrlView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	CWnd* parent = GetParent();
	if(parent && parent->IsKindOf(RUNTIME_CLASS(CDialog)))
		parent->SendMessage(WM_VSCROLL, (WPARAM)nPos,(LPARAM)pScrollBar);
}

void CaplTreeListCtrlView::OnDraw(CDC* pDC) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	
}

void CaplTreeListCtrlView::Expand(HTREEITEM item, UINT flag)
{
	if(m_tree.m_dlg) m_tree.m_dlg->Expand(item,TVE_EXPAND);
	m_tree.Expand(item,TVE_EXPAND);
	if(flag&APL_EXPAND_RECURSIVE) 
	{
		HTREEITEM ht = m_tree.GetNextItem(item,TVGN_CHILD);
		while(ht!=0)
		{
			Expand(ht,flag);
			ht = m_tree.GetNextItem(ht,TVGN_NEXT);
		}
	}
}

bool CaplTreeListCtrlView::AppentItem2TextFile(HTREEITEM hItem, CString &txt, CString &razd, CString &spacer, bool bSelectdOnly, bool bOnlyWithData, int level, bool bOnlyExpanded/*=true*/, bool bChilds/*=false*/)
{
	if(hItem!=TVI_ROOT)
	{
		int state = m_tree.GetItemState(hItem, TVIS_SELECTED|TVIS_EXPANDED/*|TVIS_DROPHILITED*/);
		if(state&TVIS_SELECTED || !bSelectdOnly || bChilds)
		{
			CString line;
			CHeaderCtrl* pHeadC = (CHeaderCtrl*)&(m_tree.m_wndHeader);
			int SubItemCount = pHeadC->GetItemCount();

			for (int nSubItem = 0; nSubItem < SubItemCount; nSubItem++)
			{
				if (nSubItem!=0) line += razd;
				line +=_T('"');
				if (nSubItem==0) {for(int i=0;i<level;i++) line+= spacer;}
				line += m_tree.GetItemText(hItem, nSubItem);
				line +=_T('"');
			}
			line += _T("\n");
			txt+=line;
		}
	}

	level++;
	bool bExp(false);
	if (hItem!=TVI_ROOT && !bOnlyExpanded)
	{
		int state = m_tree.GetItemState(hItem, TVIS_EXPANDED);
		if (!(state&TVIS_EXPANDED))
		{
			m_tree.Expand(hItem, TVE_EXPAND);
			bExp = true;
		}
	}

	HTREEITEM hChildItem = m_tree.GetNextItem(hItem, TVGN_CHILD);
	while (hChildItem)
	{
		int data=1;
		if(bOnlyWithData) data= m_tree.GetItemData(hChildItem);
		if(data!=0) AppentItem2TextFile(hChildItem, txt, razd, spacer, bSelectdOnly,bOnlyWithData, level, bOnlyExpanded, bChilds);
		hChildItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
	}

	if (bExp)
		m_tree.Expand(hItem, TVE_COLLAPSE);

	return true;
}

bool CaplTreeListCtrlView::SaveListDoc(bool all, const TCHAR *file, const TCHAR *report_header, bool bOnlyWithData, bool bOnlyExpanded/*=true*/, bool bChilds/*=false*/)
{
	if(file!=0)m_file_name=file;
	m_file_name.Replace(_T(':'),_T(' '));
	m_file_name.Replace(_T('*'),_T(' '));
	m_file_name.Replace(_T('/'),_T(' '));

	CFileDialog save_dialog(FALSE, _T("txt"), LPCTSTR(m_file_name),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		 APL_T("Текстовые файлы CSV (*.csv)|*.csv|Текстовые файлы (*.txt)|*.txt|Файлы HTML (*.html; *.htm)|*.html; *.htm|Все файлы (*.*)|*.*||"));
 	if (save_dialog.DoModal() == IDOK)
	{
		m_file_name = save_dialog.GetPathName();
		CString ext = save_dialog.GetFileExt();
		ext.MakeLower();
		if(ext==_T("html") || ext==_T("htm"))
		{
			if(CHtmlGen::CreateEmptyTitle(m_file_name)<0) return false;
			BYTE flag = HG_ADD_TO_FILE;
			if(all) {flag|=HG_ALL_ITEMS;}
			else {flag|=HG_SELECTED_ITEMS;}
			CHtmlGen::GenerateByListCtrl(&m_tree,m_file_name,flag);
			CHtmlGen::CreateEmptyPS(m_file_name);
			AfxMessageBox( APL_T("Список сохранен!"));
			return true;
		}
		CaplStringFile save_file(m_file_name, CFile::modeCreate | CFile::modeWrite | CFile::typeText);
		CString line;
		// запись поясняющего текста

		CString razd=_T("\t");
		CString spacer=_T(" ");
		line=save_dialog.GetFileExt();
		line.MakeLower();
		if(line==_T("csv")) { razd=_T(";"); spacer=_T(" ");}
		
		// запись заголовка файла
		if(report_header!=0)
		{
			if(report_header[0]!=_T('\0'))
			{
				save_file.WriteString(report_header);
				save_file.WriteString(_T("\n\n"));	
			}
		}
	
		// запись заголовка таблицы
		CHeaderCtrl* pHeadC = (CHeaderCtrl*)&(m_tree.m_wndHeader);
		int SubItemCount = pHeadC->GetItemCount();
		HDITEM HeaderItem;
		TCHAR buf[256];
		line = _T("");
		int i;
		for (i = 0; i < SubItemCount; i++)
		{
			if (i) line += razd;
			line +=_T('"');
			HeaderItem.mask = HDI_TEXT;
			HeaderItem.pszText = buf;
			HeaderItem.cchTextMax = 256;
			pHeadC->GetItem(i, &HeaderItem);
			line += buf;
			line +=_T('"');
		}
		line += _T("\n\n");
		save_file.WriteString(line);
		/*HTREEITEM hItem;
		UINT state=0;
		// Проверка выделенных
		hItem= m_tree.GetFirstVisibleItem();
		while( hItem!= 0){
			state = m_tree.GetItemState(hItem, TVIS_SELECTED);
			if(state&TVIS_SELECTED || all){
				line = "";
				for (int nSubItem = 0; nSubItem < SubItemCount; nSubItem++)
				{
					if (nSubItem) line += razd;
					line +=_T('"');
					line += m_tree.GetItemText(hItem, nSubItem);
					line +=_T('"');
					
				}
				line += _T("\n");
				save_file.WriteString(line);
			}

			hItem = m_tree.GetNextVisibleItem(hItem);
		}*/
		CString txt;
		HTREEITEM htItem(TVI_ROOT);
		if (!all)
			htItem = m_tree.GetSelectedItem();
		AppentItem2TextFile(htItem,txt,razd,spacer,!all,bOnlyWithData,-1,bOnlyExpanded, bChilds);
		save_file.WriteString(txt);
		save_file.Close();
		AfxMessageBox( APL_T("Список сохранен!"));
		return true;
	}
	return false;
}

void CaplTreeListCtrlView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CWnd *parent=GetParent();
	//if(parent && !m_tree.m_dlg)
	if(parent)
	{
		if(m_tree.m_dlg) m_tree.m_dlg->LbDblClick(nFlags, point);
		else parent->SendMessage(WM_LBUTTONDBLCLK,(WPARAM)MK_LBUTTON,MAKELPARAM(point.x,point.y));				
	}
	
	CView::OnLButtonDblClk(nFlags, point);
}

void CaplTreeListCtrlView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CWnd *parent=GetParent();
	//if(parent && !m_tree.m_dlg)
	if(parent)
	{
		if(m_tree.m_dlg) m_tree.m_dlg->LbDown(nFlags, point);
		else parent->SendMessage(WM_LBUTTONDOWN,(WPARAM)MK_LBUTTON,MAKELPARAM(point.x,point.y));				
	}
	
	CView::OnLButtonDown(nFlags, point);
}

int CaplTreeListCtrlView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	if(m_bManualInit)
		Initialize();

	return 0;
}
