// ShowGanttDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ShowGanttDlg.h"
#include "htmlGen.h"
#include "PrintGant.h"
//#include "ximage.h"
//#include "ReportDict.h"
#include "GanttCtrl.h"

//#include <apl_image.h>

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

/////////////////////////////////////////////////////////////////////////////
// CShowGanttDlg dialog

CFilterStruct CShowGanttDlg::m_filter;


CShowGanttDlg::CShowGanttDlg(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CShowGanttDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CShowGanttDlg)
	//}}AFX_DATA_INIT
	m_api=0;
	m_project_mgr=0;
	//m_project=0;
	m_tree_view=0;
	m_gantt_view=0;
	m_splitter=0;
	//m_folder=0;
	m_cur_person=0;
	m_project_folder=0;
	m_bNoUpdaetGantt=false;

	m_bAutoExpand=false;
	m_prj4select=0;

	LoadViewOption();
}

CShowGanttDlg::~CShowGanttDlg()
{
}

bool CShowGanttDlg::SaveViewOption()
{
	int i;
	CString buf;
	// Сохранение выбранных для отображения столбцов
	for(i=0;i<m_setup.m_cols.GetSize();i++)
	{
		AfxGetApp()->WriteProfileInt(_T("gantt"),m_setup.m_cols[i].id,m_setup.m_cols[i].value);
	}

	// Сохраняем_ширины столбцов
	CaplTreeListHeaderCtrl *header=&(m_tree_view->m_tree.m_wndHeader);
	if(0!=header)
	{
		HDITEM hdi;
		enum   { sizeOfBuffer = 256 };
		TCHAR  lpBuffer[sizeOfBuffer];
		bool   fFound = false;

		hdi.mask = HDI_TEXT|HDI_WIDTH;
		hdi.pszText = lpBuffer;
		hdi.cchTextMax = sizeOfBuffer;

		for(i=0;i<header->GetItemCount();i++)
		{
			header->GetItem(i,&hdi);
			if(hdi.cxy>15)
			{
				buf=_T("width_"); buf+=hdi.pszText;
				AfxGetApp()->WriteProfileInt(_T("gantt"),buf,hdi.cxy);
			}
		}
	}

	// Сохранение столбца сортировки
	BOOL bAscending=m_tree_view->GetAscending();
	AfxGetApp()->WriteProfileInt(_T("gantt"),_T("bAscending"),bAscending);
	int iLastSortCol=m_tree_view-> GetLastSortCol();
	AfxGetApp()->WriteProfileInt(_T("gantt"),_T("iLastSortCol"),iLastSortCol);

	AfxGetApp()->WriteProfileInt(_T("gantt"),_T("m_bSelectProjects"),m_setup.m_bSelectProjects);
	AfxGetApp()->WriteProfileInt(_T("gantt"),_T("m_bSelectOutOfBoundsProjects"),m_setup.m_bSelectOutOfBoundsProjects);
	AfxGetApp()->WriteProfileInt(_T("gantt"),_T("m_colDays"),m_setup.m_colDays);

	// Положение сплитера
	RECT rect;
	m_splitter->GetWindowRect(&rect);
	ScreenToClient(&rect);
	AfxGetApp()->WriteProfileInt(_T("gantt"),_T("m_splitter"),rect.left);

	return true;
}
bool CShowGanttDlg::LoadViewOption()
{
	CString buf;
	//Читаем видимость и ширины столбцов
	for(int i=0;i<m_setup.m_cols.GetSize();i++)
	{
		m_setup.m_cols[i].value=AfxGetApp()->GetProfileInt(_T("gantt"),m_setup.m_cols[i].id,m_setup.m_cols[i].value);
		buf=_T("width_"); buf+=m_setup.m_cols[i].name;
		m_setup.m_cols[i].width=AfxGetApp()->GetProfileInt(_T("gantt"),buf,m_setup.m_cols[i].width);
	}

	m_setup.m_bSelectProjects = AfxGetApp()->GetProfileInt(_T("gantt"),_T("m_bSelectProjects"),0);
	m_setup.m_bSelectOutOfBoundsProjects = AfxGetApp()->GetProfileInt(_T("gantt"),_T("m_bSelectOutOfBoundsProjects"),0);
	m_setup.m_colDays = AfxGetApp()->GetProfileInt(_T("gantt"),_T("m_colDays"),0);

	return true;
}


void CShowGanttDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CShowGanttDlg)
	DDX_Control(pDX, IDC_VIEW_MODE, m_view_mode_ctrl);
	DDX_Control(pDX, IDC_ZOOMOUT, m_zoomout_btn);
	DDX_Control(pDX, IDC_ZOOMIN, m_zoomin_btn);
	DDX_Control(pDX, IDC_GANTT_BORDER, m_gantt_border_ctrl);
	DDX_Control(pDX, IDOK, m_ok_btn);
	DDX_Control(pDX, IDC_TREE_BORDER, m_tree_border_ctrl);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, ID_SHOW_COLOR_LEGEND, m_show_color_legend_btn);
	DDX_Control(pDX, IDC_FILTER_BTN, m_find_btn);
	DDX_Control(pDX, IDC_PRINT, m_print_btn);
	DDX_Control(pDX, IDC_SETUP, m_setup_btn);
	DDX_Control(pDX, IDC_EXPORT, m_exp2html_btn);
	DDX_Control(pDX, IDC_EXPORT_CSV, m_exp2csv_btn);
	DDX_Control(pDX, IDC_SHOW_PROGNOZ, m_ShowPrognozBtn);
	DDX_Control(pDX, IDC_FINDINTABLE, m_find_in_table_btn);
	DDX_Control(pDX, IDC_SHOW_RELATION, m_ShowRelationBtn);
	DDX_Control(pDX, IDC_SHOW_FACT, m_ShowFactBtn);
}


BEGIN_MESSAGE_MAP(CShowGanttDlg, CaplResizableDialog)
	//{{AFX_MSG_MAP(CShowGanttDlg)
	ON_WM_LBUTTONDBLCLK()
	ON_BN_CLICKED(IDC_ZOOMIN, OnZoomin)
	ON_BN_CLICKED(IDC_ZOOMOUT, OnZoomout)
	ON_COMMAND(WM_SPLITTER_MOVED, OnSplitterMoved)
	ON_BN_CLICKED(IDC_FILTER_BTN, OnFilterBtn)
	ON_BN_CLICKED(IDC_EXPAND_ALL, OnExpandAll)
	ON_BN_CLICKED(IDC_PRINT, OnPrint)
	ON_BN_CLICKED(IDC_EXPORT, OnExport)
	ON_BN_CLICKED(IDC_EXPORT_CSV, OnExportCSV)
	ON_WM_CONTEXTMENU()
	ON_BN_CLICKED(IDC_SETUP, OnSetup)
	ON_COMMAND(WM_SELCHANGE,OnSelChanged)
	ON_CBN_SELCHANGE(IDC_VIEW_MODE, OnSelchangeViewMode)
	ON_WM_MOUSEWHEEL()
	ON_WM_VSCROLL()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(ID_SHOW_COLOR_LEGEND, OnBnClickedShowColorLegend)
	ON_BN_CLICKED(IDC_SHOW_PROGNOZ, &CShowGanttDlg::OnBnClickedShowPrognoz)
	ON_BN_CLICKED(IDC_FINDINTABLE, &CShowGanttDlg::OnBnClickedFindintable)
	ON_BN_CLICKED(IDC_SHOW_RELATION, &CShowGanttDlg::OnBnClickedShowRelation)
	ON_BN_CLICKED(IDC_SHOW_FACT, &CShowGanttDlg::OnBnClickedShowFact)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CShowGanttDlg message handlers

BOOL CShowGanttDlg::OnInitDialog() 
{
	CaplResizableDialog::OnInitDialog();
	if(m_api==NULL)
	{
		EndDialog(0);
		return FALSE;
	}

	m_view_mode_ctrl.ResetContent();
	m_view_mode_ctrl.InsertString(0,APL_T("Годы"));
	m_view_mode_ctrl.InsertString(1,APL_T("Месяцы"));
	m_view_mode_ctrl.InsertString(2,APL_T("Недели"));
	m_view_mode_ctrl.SetCurSel(0);

	// предотвращаем потерю модальности после диалога с бочками из aplSocketTransport
	CORRECT_LOOSE_MODAL_ON_CLASS(&(m_api->m_data));

	// TODO: Add extra initialization here
	CRect rect;
	m_tree_border_ctrl.GetWindowRect(&rect);
	ScreenToClient(&rect); 

	m_tree_view = (CaplTreeListCtrlView*)(RUNTIME_CLASS(CaplTreeListCtrlView)->CreateObject());
	ASSERT(m_tree_view);
	m_tree_view->Create(0,0,WS_BORDER|WS_VISIBLE|WS_CHILD|AFX_WS_DEFAULT_VIEW,rect,this,IDC_TREE_VIEW);
	m_tree_view->m_cImageList.Create(IDR_PROJECT_ICON,20,2,RGB(255,0,255));
	m_tree_view->m_bBreakTooltips=true;
	m_tree_view->OnInitialUpdate();
	m_tree_view->m_tree.m_dlg=(CaplResizableDialog *)this;
	m_tree_view->MoveWindow(&rect);
	//m_tree_view->n_bNoParentNotify=true;

	RefreshColumnsList();

	aplInstallFindInTable(m_tree_view);


	RECT rect0;
	m_gantt_border_ctrl.GetWindowRect(&rect0);
	ScreenToClient(&rect0);
	m_gantt_view = (CGanttView*)(RUNTIME_CLASS(CGanttView)->CreateObject());
	ASSERT(m_gantt_view);
	m_gantt_view->Create(0,0,WS_BORDER|WS_VISIBLE|WS_CHILD|AFX_WS_DEFAULT_VIEW,rect0,this,IDC_GANTT_VIEW);
	m_gantt_view->m_tree_view=m_tree_view;
	m_gantt_view->m_gantt.m_api=m_api;
	m_gantt_view->m_gantt.m_project_mgr=m_project_mgr;
	m_gantt_view->m_gantt.m_dlg=this;
	m_gantt_view->OnInitialUpdate();
	m_gantt_view->MoveWindow(&rect0);

	m_splitter = new CaplSplitterBar;
	CRect r;
	r.top=rect0.top;
	r.bottom = rect0.bottom;
	r.left = rect.right;
	r.right = rect0.left;
	m_splitter->Create(WS_VISIBLE|WS_CHILD,r,this,IDC_SPLITTER_BAR);
	m_splitter->SetPanes(m_tree_view,m_gantt_view);
	m_splitter->ShowWindow(SW_SHOW);

	// Чтение положение сплитера
	int spliter_left=AfxGetApp()->GetProfileInt(_T("gantt"),_T("m_splitter"),-1);
	if(spliter_left>50)
	{
		RECT split_rect;
		m_splitter->GetWindowRect(&split_rect);
		ScreenToClient(&split_rect);
		int w=split_rect.right-split_rect.left;
		split_rect.left=spliter_left;
		split_rect.right=spliter_left+w;
		m_splitter->MoveWindow(&split_rect);
		m_splitter->MovePanes();
	}

	AddAnchor(IDOK,BOTTOM_RIGHT);
	AddAnchor(IDC_SPLITTER_BAR,TOP_LEFT,BOTTOM_LEFT);
	AddAnchor(IDC_TREE_VIEW,TOP_LEFT,BOTTOM_LEFT);
	AddAnchor(IDC_GANTT_VIEW,TOP_LEFT,BOTTOM_RIGHT);
	AddAnchor(IDC_EXPAND_ALL,TOP_LEFT);
	AddAnchor(IDC_VIEW_MODE,TOP_LEFT);
	AddAnchor(IDC_ZOOMIN,TOP_LEFT);
	AddAnchor(IDC_ZOOMOUT,TOP_LEFT);
	AddAnchor(IDC_FINDINTABLE,TOP_LEFT);
	AddAnchor(IDC_FILTER_BTN,BOTTOM_LEFT);
	AddAnchor(IDC_SETUP,BOTTOM_LEFT);
	AddAnchor(ID_SHOW_COLOR_LEGEND,BOTTOM_LEFT);
	AddAnchor(IDC_STATIC_SHOW,BOTTOM_LEFT);
	AddAnchor(IDC_SHOW_PROGNOZ,BOTTOM_LEFT);
	AddAnchor(IDC_SHOW_RELATION,BOTTOM_LEFT);
	AddAnchor(IDC_SHOW_FACT,BOTTOM_LEFT);
	AddAnchor(IDC_EXPORT,BOTTOM_LEFT);
	AddAnchor(IDC_EXPORT_CSV,BOTTOM_LEFT);
	AddAnchor(IDC_PRINT,BOTTOM_LEFT);

	int iOption=0;
	iOption=AfxGetApp()->GetProfileInt(_T("Gantt"),_T("m_bShowPrognoz"),0);
	m_gantt_view->m_bShowPrognoz=(1==iOption);
	iOption=AfxGetApp()->GetProfileInt(_T("Gantt"),_T("m_bShowRelations"),1);
	m_gantt_view->m_bShowRelations=(1==iOption);
	iOption=AfxGetApp()->GetProfileInt(_T("Gantt"),_T("m_bShowFact"),1);
	m_gantt_view->m_bShowFact=(1==iOption);

	m_ShowPrognozBtn.SetCheck(m_gantt_view->m_bShowPrognoz ? 1 : 0);
	m_ShowRelationBtn.SetCheck(m_gantt_view->m_bShowRelations ? 1 : 0);
	m_ShowFactBtn.SetCheck(m_gantt_view->m_bShowFact ? 1 : 0);
	
	int viewmode=AfxGetApp()->GetProfileInt(_T("Gantt"),_T("ViewMode"),0);
	m_view_mode_ctrl.SetCurSel(viewmode);
	OnSelchangeViewMode();
	
	m_ok_btn.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_ok_btn.SetFlat(FALSE);
	
	m_zoomin_btn.SetFlat(FALSE);
	m_zoomout_btn.SetFlat(FALSE);
	m_zoomin_btn.SetIcon(GetAplStdIco16(APLSTDICO_ZOOM_IN));
	m_zoomout_btn.SetIcon(GetAplStdIco16(APLSTDICO_ZOOM_OUT));
	m_zoomin_btn.SetTooltipText(APL_T("Увеличить масштаб"));
	m_zoomout_btn.SetTooltipText(APL_T("Уменьшить масштаб"));

	m_find_in_table_btn.SetFlat(FALSE);
	m_find_in_table_btn.SetIcon(GetAplTableIco(APL_TABLE_FIND));
	m_find_in_table_btn.SetTooltipText(APL_T("Найти в таблице"));

	m_show_color_legend_btn.SetIcon(IDI_SHOW_COLORS);
	m_show_color_legend_btn.SetFlat(FALSE);

	m_find_btn.SetIcon(GetAplTableIco(APL_TABLE_FILTER));
	m_find_btn.SetFlat(FALSE);
	m_print_btn.SetIcon(GetAplTableIco(APL_TABLE_PRINT));
	m_print_btn.SetFlat(FALSE);
	m_setup_btn.SetIcon(GetAplStdIco16(APLSTDICO_OPTIONS));
	m_setup_btn.SetFlat(FALSE);
	m_exp2html_btn.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	m_exp2html_btn.SetFlat(FALSE);
	m_exp2csv_btn.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	m_exp2csv_btn.SetFlat(FALSE);



	m_cur_person=m_project_mgr->GetCurrentPerson();
	bool use_ass_prj=false;
	if(m_api->m_project_mgr->m_show_ass_projects==1) use_ass_prj=true;
	
	// 03.07.2017 Убираем пришедший мусор
	for(int i=0;i<m_projects.GetSize();i++)
	{
		CaplInstance *prj_i=m_projects[i];
		bool bRemove=true;
		if(0!=prj_i)
		{
			if((0!=prj_i->GetType()) && (prj_i->GetAccessmode()<=aplRO))
			{
				if(m_api->m_data.IsKindOf(prj_i,m_project_mgr->e_project)) bRemove=false;
			}
		}
		if(bRemove) {m_projects.Remove(i); i--;}
	}



	m_filter.Initialize(m_api,m_project_mgr);
	UpdateProjectsList();

	if(m_bAutoExpand) OnExpandAll();

	if(0!=m_prj4select) // выделение нужного
	{
		HTREEITEM hItem=0, hParentItem=0;
		if(FindItem(m_prj4select, hItem, hParentItem))
		{
			if(0!=hItem) m_tree_view->m_tree.SelectItem(hItem);
		}
	}

	// Чтение столбца сортировки
	BOOL bAscending=AfxGetApp()->GetProfileInt(_T("gantt"),_T("bAscending"),TRUE);
	int iLastSortCol=AfxGetApp()->GetProfileInt(_T("gantt"),_T("iLastSortCol"),0);

	m_tree_view->m_tree.SortItems(iLastSortCol, bAscending, NULL);
	m_tree_view->SortTree(iLastSortCol,bAscending,m_tree_view->m_tree.GetRootItem());

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CShowGanttDlg::UpdateGanttView(bool bUpdateCalendar,bool renum)
{
	if(m_bNoUpdaetGantt) return;
	m_gantt_view->UpdateGanttView(bUpdateCalendar,renum);
}

bool CShowGanttDlg::Expanded(HTREEITEM hItem,UINT action, HWND hWnd)
{
	if(m_bNoUpdaetGantt) return true;
	UpdateGanttView(true);
	return true;
}


void CShowGanttDlg::Sort(int nCol)
{
	UpdateGanttView(false,true);
}

bool CShowGanttDlg::PointToVal(CPoint *point, int &i,HTREEITEM &hItem,CaplInstance **inst)
{
	*inst=0;
	hItem=NULL;
	if(point!=0)
	{
		i=-1; 
				
		CRect rect;
		m_tree_view->m_tree.GetWindowRect(&rect);
		if(!rect.PtInRect(*point)) return false;

		CPoint m_point_context_menu=*point;
		m_tree_view->m_tree.ScreenToClient(&m_point_context_menu);
	
		// Отсекание нажатия на header
		m_tree_view->m_tree.m_wndHeader.GetWindowRect(&rect);
		if(rect.PtInRect(*point)) return false;
		
		UINT htFlags = 0;
		hItem = m_tree_view->m_tree.HitTest(m_point_context_menu, &htFlags);  
		if(TVHT_ONITEMBUTTON & htFlags) return false;
		if(!hItem) return true;
		i=m_tree_view->m_tree.GetListItem(hItem);
		if(i<0) return true;
		CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(hItem);
		if(0==gitem) return true;
		*inst=gitem->prj;
	}
	return true;
}
void CShowGanttDlg::LbDblClick(UINT nFlags, CPoint point)
{
	CaplInstance *sel_project=0;
	HTREEITEM hItem;
	int i;
	if(false==PointToVal(&point,i,hItem,&sel_project)) return;
	if(!sel_project) return;
	if(!hItem) return;
	if(ShowProperties(sel_project))
	{
		RefreshItem(hItem);
		RefreshParentItems(hItem);
	}
}

void CShowGanttDlg::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CaplInstance *sel_project=0;
	HTREEITEM hItem;
	int i;
	if(false==PointToVal(&point,i,hItem,&sel_project)) return;
	if(!sel_project) return;
	if(!hItem) return;
	if(ShowProperties(sel_project))
	{
		RefreshAllItems();
		//RefreshItem(hItem);
		//RefreshParentItems(hItem);
	}
	CaplResizableDialog::OnLButtonDblClk(nFlags, point);
}


void CShowGanttDlg::OnZoomin() 
{
	// TODO: Add your control notification handler code here
	
	if(m_gantt_view->ZoomIn()) m_zoomout_btn.EnableWindow(true);
	else m_zoomin_btn.EnableWindow(false);
}

void CShowGanttDlg::OnZoomout() 
{
	// TODO: Add your control notification handler code here
	if(m_gantt_view->ZoomOut())m_zoomin_btn.EnableWindow(true);
	else m_zoomout_btn.EnableWindow(false);
	
}

void CShowGanttDlg::UpdateUserData()
{
	 UpdateGanttView(false,false);
}


BOOL CShowGanttDlg::DestroyWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	int cur_sel=m_view_mode_ctrl.GetCurSel();
	AfxGetApp()->WriteProfileInt(_T("Gantt"),_T("ViewMode"),cur_sel);

	AfxGetApp()->WriteProfileInt(_T("Gantt"),_T("m_bShowPrognoz"), m_gantt_view->m_bShowPrognoz ? 1:0);
	AfxGetApp()->WriteProfileInt(_T("Gantt"),_T("m_bShowRelations"), m_gantt_view->m_bShowRelations ? 1:0);
	AfxGetApp()->WriteProfileInt(_T("Gantt"),_T("m_bShowFact"), m_gantt_view->m_bShowFact ? 1:0);

	SaveViewOption();

	if(m_splitter) m_splitter->DestroyWindow();
	if(m_splitter) delete m_splitter;
	return CaplResizableDialog::DestroyWindow();
}

void CShowGanttDlg::OnSplitterMoved()
{
	ModifyAnchor(m_tree_view->m_hWnd);
	ModifyAnchor(m_gantt_view->m_hWnd);
	ModifyAnchor(m_zoomin_btn.m_hWnd);
	ModifyAnchor(m_zoomout_btn.m_hWnd);
	if(m_splitter) ModifyAnchor(m_splitter->m_hWnd);
	CRect rect;
	m_tree_view->m_tree.GetWindowRect(&rect);
	if(m_tree_view->m_tree.GetColumnsWidth()<rect.Width()) 
	{
		m_tree_view->m_bAutofit=true;
		m_tree_view->m_tree.m_wndHeader.SetAutofit(true);

	}
}

void CShowGanttDlg::OnSelChanged()
{
	m_gantt_view->Update(false);
}

void CShowGanttDlg::ExpandItem(HTREEITEM hItem,UINT action)
{
	RemoveSubItems(hItem);
	//теперь не так m_tree_view->m_tree.DeleteSubItems(hItem);	

	CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(hItem);
	CaplInstance *project=0;
	if(0!=gitem)project=gitem->prj;
	
	if(action==TVE_EXPAND)
	{
		AddProjects(project,hItem);	
	}
	else
	{
		m_tree_view->m_tree.InsertItem(_T("fictive"),hItem,TVI_LAST,true);
	}
}

/*bool CShowGanttDlg::Expand(UINT action)
{
	return true;
}*/

bool CShowGanttDlg::Expand(HTREEITEM hItem,UINT action)
{
	if(!hItem) return false;
	ExpandItem(hItem,action);
	return true;
}

void CShowGanttDlg::RemoveSubItems(HTREEITEM hitem)
{
	if(0==hitem) return;
	while(1)
	{
		HTREEITEM item1=m_tree_view->m_tree.GetChildItem(hitem);
		if(item1<=0) break;
		RemoveSubItems(item1);
		CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(item1);
		if(0!=gitem)
		{
			int i;
			for(i=0;i<m_gantt_view->m_items.GetSize();i++)
			{
				if(m_gantt_view->m_items[i]==gitem)
				{
					m_gantt_view->m_items.Remove(i);
					break;
				}
			}
		}
		m_tree_view->m_tree.DeleteItem(item1);
	}
}

void CShowGanttDlg::CreateTreeItem(CaplInstance *project,HTREEITEM hParent,const char *id,const char *type)
{
	if(!project) return;
	CString id_s=_T("");
	if(id) id_s=id;
	else m_api->m_data.GetAttr(project,m_project_mgr->a_project_id,id_s);
	
	HTREEITEM hItem=m_tree_view->m_tree.InsertItem(id_s,hParent);
	CGanttItem *gitem=new CGanttItem;
	gitem->prj=project;
	gitem->hTreeItem=hItem;
	m_gantt_view->m_items.Add(gitem);
	m_tree_view->m_tree.SetItemData(hItem,(long)gitem);
	if(hItem) 
	{
		HTREEITEM fictitem=m_tree_view->m_tree.InsertItem(_T("fictive"),hItem,TVI_LAST,true);
		m_tree_view->m_tree.SetItemData(fictitem,(long)0);
	}
	RefreshItem(hItem);
}

void CShowGanttDlg::AddProjects(CaplInstance *parent,HTREEITEM hParent)
{
	if(!parent)return;
	if(parent->GetAccessmode()>aplRO)return;

	int i;
	CString num_s,parent_type=_T("");
	aplExtent ext_project;
	CString buf=_T("");
	CaplInstance *parent_lock=0;
	if(parent) 	
	{
		parent_lock=m_api->m_project_mgr->CheckMyLock(parent,false);
		if(parent_lock) m_api->m_data.GetAttr(parent_lock,m_project_mgr->a_project_adm_ver_content,ext_project);
		else m_api->m_data.GetAttr(parent,m_project_mgr->a_project_content,ext_project);
	}
	if(0==ext_project.GetSize()) return;

	m_project_mgr->LoadProjectInfo(ext_project,true);
	
	for(i=0;i<ext_project.GetSize();i++)
	{
		if(ext_project[i]->GetAccessmode()>aplRO) continue;
		if(!m_filter.FilterProject(ext_project[i])) continue;
		CreateTreeItem(ext_project[i],hParent);
	}
	if(m_api->m_project_mgr->m_show_ass_projects==1)
	{
		aplExtent ext_ref_project;
		m_project_mgr->LoadSubProjects(parent,ext_ref_project);
		m_project_mgr->LoadProjectInfo(ext_ref_project,true);
		for(i=0;i<ext_ref_project.GetSize();i++)
		{
			if(ext_ref_project[i]->GetAccessmode()>aplRO) continue;
			if(!m_filter.FilterProject(ext_ref_project[i])) continue;
			CreateTreeItem(ext_ref_project[i],hParent);
		}
	}

	m_tree_view->SortTree(hParent);
}

void CShowGanttDlg::InsertSubProjects(aplExtent &ext_top)
{
	aplExtent ext_sub;
	for(int i=0;i<ext_top.GetSize();i++)
	{
		for(int j=0;j<m_projects.GetSize();j++)
		{
			CaplInstance *parent=0;
			m_api->m_data.GetAttr(m_projects[j],m_project_mgr->a_project_parent,parent);
			if(parent==ext_top[i])
			{
				HTREEITEM hParent;
				if(FindItem(ext_top[i],hParent))
				{
					CreateTreeItem(m_projects[j],hParent);
					ext_sub.Add(m_projects[j]);
					break;
				}
			}
		}
	}
	if(ext_sub.GetSize()) InsertSubProjects(ext_sub);
}

void CShowGanttDlg::UpdateProjectsList()
{
	LockWindowUpdate();
	long trd=aplStartWaitDlg(APL_T("Идет обработка данных"));
	m_tree_view->m_tree.DeleteAllItems();
	CString buf=_T("");
	aplExtent ext_top;
	for(int i=0;i<m_projects.GetSize();i++)
	{
		CaplInstance *prj_i=m_projects[i];
		if(0==prj_i) continue;
		if(prj_i->GetType()==0) continue;
		if(prj_i->GetAccessmode()>aplRO) continue;

		if(m_filter.m_filter_type==APL_RECURS_TO_ROOT_ALL)
		{
			// Этот кусок написан Созвездием для себя. Добавлен 04.03.2024
			aplExtent subProjects;
			aplExtent currProjects;

			currProjects.Add(prj_i);
			m_api->m_project_mgr->GetAllSubProject(currProjects, subProjects, true);
			m_api->m_project_mgr->LoadProjectInfo(subProjects);

			ext_top.Clear();

			if(m_filter.FilterProject(prj_i))
			{
				CreateTreeItem(prj_i,NULL);
				ext_top.Add(prj_i);
			}
				

			for(int p = 0; p < subProjects.GetSize(); p++)
			{
				if(m_filter.FilterProject(subProjects[p]))
				{
					CreateTreeItem(subProjects[p],NULL);
					ext_top.Add(subProjects[p]);
				}
			}


			continue;
		}

		if(m_filter.m_filter_type==APL_FILTER_ALL)
		{
			if(!m_filter.FilterProject(prj_i)) continue;
		}
	/* 02.04.2011
		if(m_folder || m_project)
		{
			CreateTreeItem(m_projects[i],NULL);
		}
		else
		{*/
			//02.04.2011 if(m_filter.m_filter_type==APL_FILTER_TO_ROOT || m_projects[i]==m_project || (m_folder && m_api->m_folder_mgr.FindInFolder(m_folder,m_projects[i])))
			if(m_filter.m_filter_type==APL_FILTER_TO_ROOT )
			{
				CreateTreeItem(prj_i,NULL);
				ext_top.Add(prj_i);
			}
			else
			{
				CaplInstance *parent=0;
				m_api->m_data.GetAttr(prj_i,m_project_mgr->a_project_parent,parent);

				if(0!=parent) // убираем те, ктороые будут подпроектами
				{
					bool bNoShow=false;
					for(int j=0;j<m_projects.GetSize();j++)
					{
						if(m_projects[j]==parent)
						{
							bNoShow=true;
							break;
						}
					}
					if(bNoShow) continue;
				}
				CreateTreeItem(prj_i,NULL);
				ext_top.Add(prj_i);
			}
	//	}
	}
	if(ext_top.GetSize()) InsertSubProjects(ext_top);
	aplEndWaitDlg(trd);
	UpdateGanttView(true);
	UnlockWindowUpdate();
	//m_tree_view->m_tree.m_wndHeader.SetAutofit(true);
}

void CShowGanttDlg::RefreshItem(HTREEITEM hItem)
{
	if(m_bNoUpdaetGantt) return;
	if(!hItem) return;
	if(m_tree_view->m_tree.IsItemFictive(hItem)) return;

	CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(hItem);
	CaplInstance *project=0;
	if(0!=gitem)project=gitem->prj;
	if(!project) return;
	if(project->GetAccessmode()>aplRO)return;

	m_tree_view->m_tree.SetItemColor(hItem,RGB(0,0,0),false);
	m_tree_view->m_tree.SetItemBold(hItem,false,false);
	
	CaplInstance *lock=m_project_mgr->CheckMyLock(project,false);

	CString buf=_T("");
	m_tree_view->m_tree.SetItemImage(hItem,1,1);
	int count=0;
	CaplInstance *customer=0;

	if(m_setup.m_cols[0].value) 
	{
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_id,buf);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_id,buf);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}

	if(m_setup.m_cols[1].value) 
	{
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_number,buf);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_number,buf);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}

	if(m_setup.m_cols[2].value) 
	{
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_name,buf);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_name,buf);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	if(m_setup.m_cols[3].value) 
	{
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_descr,buf);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_descr,buf);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}

	if(m_setup.m_cols[4].value) 
	{
		buf=_T("");
		CaplInstance *type=0;
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_type,type);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_type,type);
		if(type) m_api->m_data.GetAttr(type,m_project_mgr->a_project_type_name,buf);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	if(m_setup.m_cols[5].value) 
	{
		buf=_T("");
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_customer,customer);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_customer,customer);
		if(customer) 
		{
			if(m_api->m_data.IsKindOf(customer, m_api->m_appr_mgr.e_person)) m_api->m_appr_mgr.GetPersonName(customer,buf);
			else if(m_api->m_data.IsKindOf(customer, m_api->m_appr_mgr.e_org)) m_api->m_data.GetAttr(customer,m_api->m_appr_mgr.a_org_name,buf); 
		}
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	m_api->m_data.GetAttr(project,m_project_mgr->a_project_state,buf);
	if(m_setup.m_cols[6].value) 
	{
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	bool b_project_in_content=true;
	CaplInstance *parent=0;
	m_api->m_data.GetAttr(project,m_project_mgr->a_project_parent,parent);
	if(parent) b_project_in_content=m_project_mgr->IsProjectInContentOfParent(project);
	int image=1;
	if(!b_project_in_content) image+=5;
	if(buf==APL_T("в работе")) image++;
	else if(buf==APL_T("остановлен")) image+=2;
	else if(buf==APL_T("отменен")) image+=3;
	else if(buf==APL_T("завершен")) image+=4;

	if(lock)image+=10;
	m_tree_view->m_tree.SetItemImage(hItem,image,image);

	COleDateTime dt;
	if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_date_planned_begin,buf);
	else m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_planned_begin,buf);

	if(m_setup.m_cols[7].value) 
	{
		if(buf!=_T(""))
		{
			aplString2Date(buf,dt);
			if(dt.GetStatus()==COleDateTime::valid)	
			{
				buf=dt.Format(_T("%d.%m.%Y"));
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_actual_begin,buf);
	if(m_setup.m_cols[8].value) 
	{
		if(buf!=_T(""))
		{
			aplString2Date(buf,dt);
			if(dt.GetStatus()==COleDateTime::valid)	
			{
				buf=dt.Format(_T("%d.%m.%Y"));
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	CString date_planned_end=_T(""),date_actual_end=_T("");
	if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_date_planned_end,date_planned_end);
	else m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_planned_end,date_planned_end);
	if(m_setup.m_cols[9].value) 
	{
		buf=_T("");
		if(date_planned_end!=_T(""))
		{
			aplString2Date(date_planned_end,dt);
			if(dt.GetStatus()==COleDateTime::valid)	
			{
				buf=dt.Format(_T("%d.%m.%Y"));
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_actual_end,date_actual_end);
	if(m_setup.m_cols[10].value) 
	{
		buf=_T("");
		if(date_actual_end!=_T(""))
		{
			aplString2Date(date_actual_end,dt);
			if(dt.GetStatus()==COleDateTime::valid)	
			{
				buf=dt.Format(_T("%d.%m.%Y"));
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	CaplInstance *kurator=0;
	if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_kurator,kurator);
	else m_api->m_data.GetAttr(project,m_project_mgr->a_project_kurator,kurator);
	if(m_setup.m_cols[11].value) 
	{
		if(kurator)
		{
			if(m_api->m_data.IsKindOf(kurator,m_api->m_appr_mgr.e_person))
			{
				aplExtent ext;
				m_api->m_appr_mgr.FindPersonOrganizations(kurator,ext);
				if(ext.GetSize()) 
				{
					m_api->m_data.GetAttr(ext[0],m_api->m_appr_mgr.a_org_name,buf);
					m_tree_view->m_tree.SetItemText(hItem,count,buf);
				}
			}
			else
			{
				m_api->m_data.GetAttr(kurator,m_api->m_appr_mgr.a_org_name,buf);
				m_tree_view->m_tree.SetItemText(hItem,count,buf);
			}
		}
		count++;
	}
	if(m_setup.m_cols[12].value) 
	{
		buf=_T("");
		if(kurator)
		{
			if(m_api->m_data.IsKindOf(kurator, m_api->m_appr_mgr.e_person)) m_api->m_appr_mgr.GetPersonName(kurator,buf);
			else if(m_api->m_data.IsKindOf(kurator, m_api->m_appr_mgr.e_org)) m_api->m_data.GetAttr(kurator,m_api->m_appr_mgr.a_org_name,buf); 
		}
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	if(m_setup.m_cols[13].value) 
	{
		CString executors=_T("");
		aplExtent ext0;
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_executors,ext0);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_executors,ext0);
		for(int i=0;i<ext0.GetSize();i++)
		{
			if(m_api->m_data.IsKindOf(ext0[i], m_api->m_appr_mgr.e_person)) m_api->m_appr_mgr.GetPersonName(ext0[i],buf);
			else if(m_api->m_data.IsKindOf(ext0[i], m_api->m_appr_mgr.e_org)) m_api->m_data.GetAttr(ext0[i],m_api->m_appr_mgr.a_org_name,buf); 
			if(buf!=_T(""))
			{
				executors+=buf; 
				if(i!=(ext0.GetSize()-1)) executors+=_T(", "); 
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,executors);
		count++;
	}
	if(m_setup.m_cols[14].value) 
	{
		//трудоемкость
		double num=0;
		CaplInstance *labor=0,*inst=0;
		CString labor_str=_T("");
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_labor_useness,labor);
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_labor_useness,labor); 
		if(labor)
		{
			m_api->m_data.GetAttr(labor,m_project_mgr->a_labor_value,num);
			if(num)
				labor_str.Format(_T("%g"),num);
			m_api->m_data.GetAttr(labor,m_project_mgr->a_labor_unit,inst);
			if(inst)
			{	
				if(!num) 
					labor_str+=_T("0");
				labor_str+=_T(" ");
				m_api->m_charact_mgr.GetUnitName(inst,buf);
				labor_str+=buf;
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,labor_str);
		count++;
	}
	if(m_setup.m_cols[15].value) 
	{
		//фактическая трудоемкость
		double num=0;
		CaplInstance *labor=0,*inst=0;
		CString labor_str=_T("");
		m_api->m_data.GetAttr(project,m_project_mgr->a_project_labor_useness_actual,labor); 
		if(labor)
		{
			m_api->m_data.GetAttr(labor,m_project_mgr->a_labor_value,num);
			if(num)
				labor_str.Format(_T("%g"),num);
			m_api->m_data.GetAttr(labor,m_project_mgr->a_labor_unit,inst);
			if(inst)
			{	
				if(!num) 
					labor_str+=_T("0");
				labor_str+=_T(" ");
				m_api->m_charact_mgr.GetUnitName(inst,buf);
				labor_str+=buf;
			}
		}
		m_tree_view->m_tree.SetItemText(hItem,count,labor_str);
		count++;
	}
	if(m_setup.m_cols[16].value) 
	{
		//плановый объем продукции
		double num=0;
		CString buf=_T("0");
		if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_prd_amount_planned,num); 
		else m_api->m_data.GetAttr(project,m_project_mgr->a_project_prd_amount_planned,num); 
		if(num) buf.Format(_T("%g"),num);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	if(m_setup.m_cols[17].value) 
	{
		//фактический объем продукции
		double num=0;
		CString buf=_T("0");
		m_api->m_data.GetAttr(project,m_project_mgr->a_project_prd_amount_actual,num); 
		if(num) buf.Format(_T("%g"),num);
		m_tree_view->m_tree.SetItemText(hItem,count,buf);
		count++;
	}
	if(m_setup.m_cols[18].value) 
	{
		// % выполнения
		double percentage=0;
		CString percentage_str=_T("");

		// 20.03.2023  Убрано использование a_project_adm_ver_persentage  чтобы не было путаницы
		//if(lock) m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_persentage,percentage); 
		//else m_api->m_data.GetAttr(project,m_project_mgr->a_project_persentage,percentage); 
		m_api->m_data.GetAttr(project,m_project_mgr->a_project_persentage,percentage); 

		if(percentage) percentage_str.Format(_T("%g"),percentage);
		m_tree_view->m_tree.SetItemText(hItem,count,percentage_str);
		count++;
	}

//Выделение просраченых 
	COleDateTime cur_dt=COleDateTime::GetCurrentTime();
	CString cur_date=_T("");
	cur_dt.SetDateTime(cur_dt.GetYear(),cur_dt.GetMonth(),cur_dt.GetDay(),0,0,0);
	aplDate2String(cur_dt,cur_date);
	//Выделение тех, которые грядут (по дате, которая установлена в настройках)
	if(m_setup.m_bSelectProjects)
	{
		COleDateTime fut_dt;
		fut_dt.SetDateTime(cur_dt.GetYear(),cur_dt.GetMonth(),cur_dt.GetDay(),23,59,59);
		fut_dt+=m_setup.m_colDays;
		CString fut_date=_T("");
		aplDate2String(fut_dt,fut_date);
		if(fut_date>=date_planned_end && date_planned_end!=_T(""))
		{
			if(date_actual_end==_T(""))
			{
				m_tree_view->m_tree.SetItemColor(hItem,RGB(0,0,255),false);
			}
		}
	}
	if(m_setup.m_bSelectOutOfBoundsProjects)
	{
		if(cur_date>date_planned_end && date_planned_end!=_T(""))
		{
			if(date_actual_end==_T("") || date_actual_end>date_planned_end)
			{
				m_tree_view->m_tree.SetItemColor(hItem,RGB(255,0,0),false);
			}
		}
	}

}

void CShowGanttDlg::RefreshItems(HTREEITEM hItem)
{
	if(!hItem) return;
	if(m_bNoUpdaetGantt) return;
	
    while(hItem)
	{
		if(hItem) 
		{
			RefreshItem(hItem);
			if(m_tree_view->m_tree.ItemHasChildren(hItem))
				RefreshItems(m_tree_view->m_tree.GetChildItem(hItem));
			
		}
		hItem = m_tree_view->m_tree.GetNextSiblingItem(hItem);
	}
}

void CShowGanttDlg::RefreshAllItems()
{
	if(m_bNoUpdaetGantt) return;
	RefreshItems(m_tree_view->m_tree.GetRootItem());
}

void CShowGanttDlg::RefreshParentItems(HTREEITEM hItem)
{
	if(!hItem) return;
	HTREEITEM pItem=m_tree_view->m_tree.GetParentItem(hItem);
	if(pItem) 
	{
		RefreshItem(pItem);
		RefreshParentItems(pItem);
	}
}

bool CShowGanttDlg::FindItem(CaplInstance *project,HTREEITEM &hItem,HTREEITEM hParentItem)
{
	if(!project) return false;
	if(project->GetAccessmode()>aplRO) return false;
	hItem=NULL;
	if(hParentItem==NULL) hParentItem=m_tree_view->m_tree.GetRootItem();

	HTREEITEM hCurItem = hParentItem;	
	while(hCurItem)
	{
		if(hCurItem) 
		{
			CaplInstance *cur_project=0;
			CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(hCurItem);
			if(0!=gitem) cur_project=gitem->prj;

			if(cur_project==project)
			{
				hItem=hCurItem;
				return true;
			}
			if(m_tree_view->m_tree.ItemHasChildren(hCurItem))
			{
				if(FindItem(project,hItem,m_tree_view->m_tree.GetChildItem(hCurItem)))
					return true;
			}
		}
		hCurItem = m_tree_view->m_tree.GetNextSiblingItem(hCurItem);
	}
	return false;
}

void CShowGanttDlg::OnFilterBtn() 
{
	CFilterDlg dlg;
	dlg.m_filter=&m_filter;
	dlg.m_api=m_api;
	dlg.m_project_mgr=m_project_mgr;
	if(dlg.DoModal()==IDOK)
	{

		if(dlg.m_filter_type==APL_FILTER_ALL || dlg.m_filter_type==APL_FILTER_TO_ROOT || dlg.m_filter_type==APL_RECURS_TO_ROOT_ALL) 
		{
			UpdateProjectsList();
		}
		else
		{
			HTREEITEM hCurItem=m_tree_view->m_tree.GetNextSelectedItem();
			if(hCurItem)
			{
				ExpandItem(hCurItem,TVE_COLLAPSE);
				ExpandItem(hCurItem,TVE_EXPAND);
			}
		}
	}	
}

void CShowGanttDlg::OnExpandAll() 
{
	HTREEITEM hItem=m_tree_view->m_tree.GetRootItem();
	AfxGetApp()->DoWaitCursor(1);
	m_bNoUpdaetGantt=true;
	while (hItem!=NULL)
	{
		m_tree_view->Expand(hItem);
		hItem=m_tree_view->m_tree.GetNextSiblingItem(hItem);
	}
	m_bNoUpdaetGantt=false;
	RefreshAllItems();
	AfxGetApp()->DoWaitCursor(-1);
	UpdateGanttView(true);
}

void CShowGanttDlg::ExportTable(long mode)
{
	bool b_err=false;
	CString b_err_msg=APL_T("Ошибка экспорта!");
	CString f_name=_T("");
	CString buf=_T(""),buf0=_T("");
	TCHAR tmp_dir[256];
	CString title=_T("");
	/*if(m_folder) 
	{
		m_api->GetItemName(m_folder,buf);
		f_name+=APL_T("Свойства проектов папки '")+buf+_T("'");
		title=APL_T("Диаграммы Ганта по проектам папки '")+buf+_T("'");
	}
	else if(m_project)
	{
		CaplInstance *lock=m_api->m_project_mgr->CheckMyLock(m_project,false);
		if(lock) m_api->m_data.GetAttr(lock,m_api->m_project_mgr->a_project_adm_ver_id,buf);
		else m_api->m_data.GetAttr(m_project,m_api->m_project_mgr->a_project_id,buf);
		f_name+=APL_T("Свойства проекта '")+buf+_T("'");
		title=APL_T("Диаграммы Ганта по проекту '")+buf+_T("'");
	}
	else
	{*/
		f_name+=APL_T("Свойства проектов");
		title=APL_T("Диаграммы Ганта по всем проектам");
	//}
	f_name.Replace(_T('/'),_T('_'));
	f_name.Replace(_T('.'),_T('_'));
	f_name.Replace(_T(':'),_T('_'));
	f_name+=_T(".html");
	CString short_f_name=f_name;
	if(GetTempPath(256,tmp_dir))
		f_name=tmp_dir+f_name;
	CHtmlGen hg(0,0,_T("project_export.html"),f_name);
	if(hg.CreateTitle(_T(""))<0) 
	{
		b_err=true;
		b_err_msg=APL_T("Не удалось создать заголовок документа! Отсутствует файл pdm_project.html шаблона?");
	}
	if(!b_err)
	{
		//CHtmlGen::GenerateByListCtrl(&m_tree_view->m_tree,f_name,HG_VISIBLE_ITEMS|HG_ADD_TO_FILE);
		CHtmlGen::GenerateByListCtrl(&m_tree_view->m_tree,f_name,HG_ALL_ITEMS|HG_ADD_TO_FILE);
		//создание фрейма
		buf= APL_T("<HTML><HEAD><TITLE>Диаграммы Ганта</TITLE></HEAD>\n");
		buf+=_T("<FRAMESET COLS=\"70, 30\">\n");
			
		buf0= APL_T("<HTML><HEAD><TITLE>Диаграммы Ганта</TITLE></HEAD>\n");
		buf0+=_T("<p><Center><font size=3><b>")+title+_T("</b></font></Center></p>");
		buf0+=_T("<img border=\"0\" src=\"gantt.jpg\">\n");
		buf0+=_T("</HTML>");
		f_name=tmp_dir;
		f_name+=APL_T("Diagramm.html");
		if(CHtmlGen::WriteStrToFile(buf0,f_name)!=0)
		{
			AfxMessageBox(APL_T("Ошибка создания фрейма!"));
			return;
		}
		buf+=APL_T("<FRAME name=\"diagram\" src=\"Diagramm.html\">\n");

		buf+=_T("<FRAME name=\"table\" src=\"")+short_f_name+_T("\">\n");

		buf+=_T("</FRAMESET></HTML>");
		f_name=tmp_dir;
		f_name+=APL_T("Gantt_Diagramm.html");
		if(CHtmlGen::WriteStrToFile(buf,f_name)!=0)
		{
			AfxMessageBox(APL_T("Ошибка создания фрейма!"));
			return;
		}
		int exec_result;
		if(mode==APL_MODE_EDIT)
		{
			exec_result=(int)aplShellExecute(NULL, _T("edit"), f_name, NULL, NULL, SW_SHOWNORMAL);
			if(exec_result<=32)
			{
				if(exec_result==SE_ERR_NOASSOC)
				{
					exec_result=(int)aplShellExecute(NULL, _T("open"), f_name, NULL, NULL, SW_SHOWNORMAL);
				}
				if(exec_result<=32) 
				{
					b_err=true;
					b_err_msg=APL_T("Не удалось открыть сгенерированный файл. Возможно в системе нет приложений,ассоциированных с файлами типа .html");
				}
			}
		}
		else if(mode==APL_MODE_PRINT)
		{
			exec_result=int(aplShellExecute(NULL, _T("print"), f_name, NULL, NULL, SW_SHOWNORMAL, false));
			if(exec_result<=32)
			{
				b_err=true;
				b_err_msg=APL_T("Не удалось напечатать сгенерированный файл. Возможно в системе нет приложений,ассоциированных с файлами типа .html");
			}
		}
		else if(mode==APL_MODE_OPEN)
		{
			exec_result=int(aplShellExecute(NULL, _T("open"), f_name, NULL, NULL, SW_SHOWNORMAL));
			if(exec_result<=32)
			{
				b_err=true;
				b_err_msg=APL_T("Не удалось напечатать сгенерированный файл. Возможно в системе нет приложений,ассоциированных с файлами типа .html");
			}
		}
	}
	if(b_err) AfxMessageBox(b_err_msg);
}


void CShowGanttDlg::OnPrint() 
{
	//CaplPrintGant pg;
	//pg.PrintGant(&m_tree_view->m_tree);
	//ExportTable(APL_MODE_PRINT);	

	CDC memDC;
	CBitmap bmp;
	if(!m_gantt_view->m_gantt.Paint2DC(memDC,bmp)) return ;

	//CaplImage::SaveBitmapAs((HBITMAP)bmp,"d:\\000000.bmp",100);

	CString buf=APL_T("Диаграмма Ганта ");
	COleDateTime odt=COleDateTime::GetCurrentTime();
	buf+=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
	aplPrintDC(memDC,LPCTSTR(buf));

	memDC.DeleteDC();
}

void CShowGanttDlg::GetAllTreeItems(HTREEITEM hItem)
{
	if(!hItem) return;

	/*CString sdate;
	
    while(hItem)
	{
		if(hItem) 
		{
			CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(hItem);
			CaplInstance *project=0;
			if(0!=gitem)project=gitem->prj;
			if(project)
			{
				CaplInstance *lock=m_project_mgr->CheckMyLock(project,false);
				CGanttItem new_item;
				new_item.itemData=(DWORD)project;
				new_item.hTreeItem=hItem;
				if(lock)
				{
					m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_id,new_item.id);
					m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_name,new_item.name);
					m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_date_planned_begin,sdate);
					aplString2Date(sdate,new_item.pl_date_begin);
					m_api->m_data.GetAttr(lock,m_project_mgr->a_project_adm_ver_date_planned_end,sdate);
					aplString2Date(sdate,new_item.pl_date_end);
				}
				else
				{
					m_api->m_data.GetAttr(project,m_project_mgr->a_project_id,new_item.id);
					m_api->m_data.GetAttr(project,m_project_mgr->a_project_name,new_item.name);
					m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_planned_begin,sdate);
					aplString2Date(sdate,new_item.pl_date_begin);
					m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_planned_end,sdate);
					aplString2Date(sdate,new_item.pl_date_end);

				}
				if(new_item.id.GetLength()>m_gantt_view->m_gantt.m_max_id_length) m_gantt_view->m_gantt.m_max_id_length=new_item.id.GetLength();

				m_api->m_data.GetAttr(project,m_project_mgr->a_project_persentage,new_item.percentage);
				m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_actual_begin,sdate);
				aplString2Date(sdate,new_item.act_date_begin);
				m_api->m_data.GetAttr(project,m_project_mgr->a_project_date_actual_end,sdate);
				aplString2Date(sdate,new_item.act_date_end);
				//теперь определяется для всех сразу m_project_mgr->GetWorkedProjectEndPrognoz(project,new_item.act_date_end_prognoz);

				int newItemNum=m_gantt_view->m_gantt.InsertItem(new_item);	

				HTREEITEM hParent=m_tree_view->m_tree.GetParentItem(hItem);
				CGanttItem *gParentItem=0;
				if(hParent)
				{
					gParentItem=m_gantt_view->m_gantt.FindItem(hParent);
					if(gParentItem)	gParentItem->last_sub_item=newItemNum;
				}
			}
			if(m_tree_view->m_tree.ItemHasChildren(hItem))
				GetAllTreeItems(m_tree_view->m_tree.GetChildItem(hItem));
			
		}
		hItem = m_tree_view->m_tree.GetNextSiblingItem(hItem);
	}*/
}

void CShowGanttDlg::OnExport() 
{
	/*int i;
	CArray<CGanttItem,CGanttItem> old_items;
	for(i=0;i<m_gantt_view->m_gantt.m_items.GetSize();i++)
	{
		CGanttItem new_item;
		new_item=m_gantt_view->m_gantt.m_items[i];
		old_items.Add(new_item);
	}

	m_gantt_view->m_gantt.RemoveAllItems();
	GetAllTreeItems(m_tree_view->m_tree.GetRootItem());

	m_gantt_view->m_gantt.UpdateCalendar(false);*/
	
	//собственно экспорт
	CString buf=_T(""),f_name=_T("");
	TCHAR tmp_dir[256];
	if(GetTempPath(256,tmp_dir))f_name=tmp_dir;
	f_name+=_T("gantt.jpg");
	bool saved=m_gantt_view->m_gantt.ExportDiagramBmp(f_name); 
	if(!saved)	AfxMessageBox(APL_T("Ошибка сохраниения диаграммы Ганта!"));
	//возвращаем все назад
	/*m_gantt_view->m_gantt.RemoveAllItems();
	for(i=0;i<old_items.GetSize();i++)
	{
		CGanttItem new_item;
		new_item=old_items[i];
		m_gantt_view->m_gantt.InsertItem(new_item);
	}
	m_gantt_view->m_gantt.UpdateCalendar(false);*/

	if(saved) ExportTable(APL_MODE_OPEN);	

}

void CShowGanttDlg::OnExportCSV() 
{
	m_tree_view->SaveListDoc(true,0,0,true);
}

void CShowGanttDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here
	int i=0;
	CaplInstance *sel_project=0;
	HTREEITEM hItem=NULL;
	if(false==PointToVal(&point,i,hItem,&sel_project)) return;

	HTREEITEM hParent=NULL;
	if(hItem) hParent=m_tree_view->m_tree.GetParentItem(hItem);
	CaplInstance *sel_parent=0;
	if(hParent)
	{
		CGanttItem *gitem=(CGanttItem*)m_tree_view->m_tree.GetItemData(hParent);
		if(0!=gitem)sel_parent=gitem->prj;
	}		
	if(!sel_project) return;
	
	CMenu menu;CMenu* pPopup;
    VERIFY(menu.LoadMenu(IDR_CONTEXT_MENU));

	pPopup = menu.GetSubMenu(0);
	bool b_old_show_messages=m_project_mgr->m_bShowMessages;
	m_project_mgr->m_bShowMessages=false;


	/*if(!sel_project)
	{
		pPopup->EnableMenuItem(ID_SHOW_PROPERTIES, MF_BYCOMMAND | MF_GRAYED);
		pPopup->EnableMenuItem(ID_DELETE_REL, MF_BYCOMMAND | MF_GRAYED);
		pPopup->EnableMenuItem(ID_DELETE, MF_BYCOMMAND | MF_GRAYED);
	}*/

	if(!sel_parent) pPopup->EnableMenuItem(ID_DELETE_REL, MF_BYCOMMAND | MF_GRAYED);

	CaplMenu::Install(this);

	BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON |TPM_RETURNCMD,	point.x, point.y,this); // use main window for cmds

	switch(res)
	{
		case ID_CREATE_PROJECT:
			{
				CaplInstance *new_project=m_project_mgr->CreateProject(sel_project);
				if(new_project)
				{
					RefreshItem(hItem);
					RefreshParentItems(hItem);
					m_projects.Add(new_project);
					/*02.04.2011
					if(!sel_project) 
					{
						if(m_folder) m_api->m_folder_mgr.AddToFolder(m_folder,new_project); 
						else if(m_project_folder) m_api->m_folder_mgr.AddToFolder(m_project_folder,new_project); 
					}*/
					if(m_filter.FilterProject(new_project))
					{
						if(hItem) m_tree_view->Expand(hItem);
						else CreateTreeItem(new_project,hItem);
						UpdateGanttView(true);
					}
				}
			}
			break;
		case ID_SHOW_PROPERTIES:
			{
				if(ShowProperties(sel_project))
				{
					RefreshAllItems();
					//RefreshItem(hItem);
					//RefreshParentItems(hItem);
				}
			}
			break;
		case ID_DELETE_REL:
			{
				if(AfxMessageBox(APL_T("Вы действительно хотите удалить связь ?"),MB_YESNO)==IDYES)
				{
					if(m_project_mgr->RemoveProjectFromParent(sel_project,sel_parent))
					{
						//RefreshParentItems(hItem);
						m_tree_view->m_tree.DeleteItem(hItem);
						RefreshAllItems();
						UpdateGanttView(true);
					}
				}
			}
			break;
		case ID_DELETE:
			{
				if(AfxMessageBox(APL_T("Вы действительно хотите удалить описание проекта?"),MB_YESNO)==IDYES)
				{
					if(m_project_mgr->DeleteProject(sel_project))
					{
						RefreshParentItems(hItem);
						m_tree_view->m_tree.DeleteItem(hItem);
						UpdateGanttView(true);
					}
				}
			}
			break;
		default:break;
	}	
	m_project_mgr->m_bShowMessages=b_old_show_messages;
	
}

bool CShowGanttDlg::ShowProperties(CaplInstance *project)
{
	if(!project) return false;
	if(project->GetAccessmode()>aplRO) return false;
	if(m_project_mgr->ShowProjectProperties(project)) 
	{
		UpdateGanttView(true);
		return true;
	}
	return false;
}

void CShowGanttDlg::OnSetup() 
{
	CSetupDlg dlg;
	dlg.m_setup=&m_setup;
	if(dlg.DoModal()==IDOK)
	{
		RefreshColumnsList();
		RefreshAllItems();
	}	
}

void CShowGanttDlg::RefreshColumnsList()
{
	m_tree_view->m_tree.DeleteAllColumns(); //удаляем все столбцы 
	m_tree_view->m_bAutofit=false;
	m_tree_view->m_tree.m_wndHeader.SetAutofit(false);
	int col=0;
	int count=0;
	for(int i=0;i<m_setup.m_cols.GetSize();i++)
	{
		if(m_setup.m_cols[i].value)
		{
			m_tree_view->m_tree.InsertColumn(count, m_setup.m_cols[i].name, LVCFMT_LEFT, m_setup.m_cols[i].width);
			count++;
		}
	}
	CRect rect;
	m_tree_view->GetWindowRect(&rect);
	if(m_tree_view->m_tree.GetColumnsWidth()<rect.Width()) 
	{
		m_tree_view->m_bAutofit=true;
		m_tree_view->m_tree.m_wndHeader.SetAutofit(true);

	}
	m_tree_view->ResetScrollBar();
	m_tree_view->SortTree(0, TRUE, m_tree_view->m_tree.GetRootItem());
}

void CShowGanttDlg::OnSelchangeViewMode() 
{
	int view_mode;	
	int cur_sel=m_view_mode_ctrl.GetCurSel();
	if(cur_sel==0) view_mode=APL_MODE_YEARS;
	else if(cur_sel==1) view_mode=APL_MODE_MONTHS;
	else view_mode=APL_MODE_WEEKS;
	m_gantt_view->m_gantt.m_view_mode=view_mode;
	if(view_mode==APL_MODE_YEARS) m_gantt_view->m_gantt.SetPixelsInDay(3);
	else if(view_mode==APL_MODE_MONTHS) m_gantt_view->m_gantt.SetPixelsInDay(6);
	else if(view_mode==APL_MODE_WEEKS) m_gantt_view->m_gantt.SetPixelsInDay(18);
	m_gantt_view->Update(true);

}

BOOL CShowGanttDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	// TODO: Add your message handler code here and/or call default
	UpdateGanttView(false);
	return CaplResizableDialog::OnMouseWheel(nFlags, zDelta, pt);
}

void CShowGanttDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	UpdateGanttView(false);
}


void CShowGanttDlg::OnDestroy() 
{
	if(m_tree_view)aplDeInstallFindInTable(m_tree_view);

	CaplResizableDialog::OnDestroy();
}

void CShowGanttDlg::OnBnClickedShowColorLegend() {CaplProjectManager::ShowColorLegend();}


LRESULT CShowGanttDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class

	if(message==WM_SELCHANGE && (wParam==m_tree_view->m_tree.GetDlgCtrlID()))
	{
		//UpdateGanttView(false);
		//m_gantt_view->m_gantt.Invalidate();
		m_gantt_view->m_gantt.HideToolTip();
		m_gantt_view->Update(false);
	}
	return CaplResizableDialog::DefWindowProc(message, wParam, lParam);
}

//***************************************************************************************

void CShowGanttDlg::OnBnClickedShowPrognoz()
{
	BOOL bShow=m_ShowPrognozBtn.GetCheck();
	if(bShow)
	{
		m_gantt_view->m_bShowPrognoz=true;

		if(false==m_gantt_view->m_bShowFact)
		{
			m_gantt_view->m_bShowFact=true;
			m_ShowFactBtn.SetCheck(1);
		}
	}
	else m_gantt_view->m_bShowPrognoz=false;

	UpdateGanttView(true);
}

void CShowGanttDlg::OnBnClickedShowRelation()
{
	BOOL bShow=m_ShowRelationBtn.GetCheck();
	if(bShow) m_gantt_view->m_bShowRelations=true; else m_gantt_view->m_bShowRelations=false;
	UpdateGanttView(true);
}

void CShowGanttDlg::OnBnClickedShowFact()
{
	BOOL bShow=m_ShowFactBtn.GetCheck();
	if(bShow) m_gantt_view->m_bShowFact=true;
	else
	{
		m_gantt_view->m_bShowFact=false;

		if(true==m_gantt_view->m_bShowPrognoz)
		{
			m_gantt_view->m_bShowPrognoz=false;
			m_ShowPrognozBtn.SetCheck(0);
		}
	}
	UpdateGanttView(true);
}

//***************************************************************************************

void CShowGanttDlg::OnBnClickedFindintable()
{
	if(m_tree_view) aplShowFindInTable(m_tree_view); 
}



