// ReplaceInstDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ReplaceInstDlg.h"
#include "ReplaceInstDlg.h"
#include "aplNetStepData.h"


// CReplaceInstDlg dialog

IMPLEMENT_DYNAMIC(CReplaceInstDlg, CaplTranslateDialog)

CReplaceInstDlg::CReplaceInstDlg(CWnd* pParent /*=NULL*/)
	: CaplTranslateDialog(CReplaceInstDlg::IDD, pParent)
{
	m_data = 0;
	m_bResult = false;
	m_inst1 = 0; m_inst2 = 0;
	m_bCheckSelect = true;
	m_bAutoRun = false;
	m_bAutoHide = false;
}

CReplaceInstDlg::~CReplaceInstDlg()
{

}

void CReplaceInstDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplTranslateDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_ST_HEADER, m_header_ctrl);
	DDX_Control(pDX, IDC_LOG, m_log_ctrl);
	DDX_Control(pDX, IDC_RUN, m_run_btn);
}


BEGIN_MESSAGE_MAP(CReplaceInstDlg, CaplTranslateDialog)
	ON_BN_CLICKED(IDC_RUN, &CReplaceInstDlg::OnBnClickedRun)
END_MESSAGE_MAP()


// CReplaceInstDlg message handlers

void CReplaceInstDlg::AddLog(LPCTSTR txt)
{
	m_log_ctrl.SetSel(-1,-1);
	m_log_ctrl.ReplaceSel(txt);
}
void CReplaceInstDlg::PrintInst(CaplInstance *inst, CString &str)
{
  str = _T("");
  if(0==inst) return;
  str.Format(_T("%s (#%i)"),LPCTSTR(inst->GetType()->name), inst->GetId());

  int i;
  CaplValue val;
  CString v,buf;
  for(i = 0;i<inst->GetType()->all_attrs.GetSize();i++)
  {
	  CaplAttr *attr=inst->GetType()->all_attrs[i];
	  CaplValue *val = 0;
	  m_data->GetAttr(inst,attr,&val);
	  if(val)
	  {	
		  val->Print(v);
		  buf.Format(_T(" %s = %s,"),LPCTSTR(attr->name),LPCTSTR(v));
		  str+=buf;
	  }
  }
}


BOOL CReplaceInstDlg::OnInitDialog()
{
	CaplTranslateDialog::OnInitDialog();

	m_log_ctrl.SetLimitText(1024*1024);

	// TODO:  Add extra initialization here
	CString n1,n2;
	PrintInst(m_inst1,n1);
	PrintInst(m_inst2,n2);

	CString buf;
	buf.Format(APL_T("Замена %s\n на         %s"),LPCTSTR(n1),LPCTSTR(n2));
	m_header_ctrl.SetWindowText(buf);

	if(m_bAutoRun) OnBnClickedRun();
	if(m_bAutoRun && m_bAutoHide) EndDialog(0); 

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



void CReplaceInstDlg::OnBnClickedRun()
{
	int i,j,k;
	int iCountAttr = 0, iCountAttrVal = 0;
	CString buf;
	CaplEntity *ent_inst1=m_inst1->GetType();

	for(i = 0;i<m_data->entities.GetSize();i++)
	{
		CaplEntity *ent=m_data->entities[i];
		for(j = 0;j<ent->attrs.GetSize();j++)
		{
			CaplAttr *attr=ent->attrs[j];

			bool bCheck = false, bAggr = false;
			
			if(attr->type==aplINSTANCE)
			{
				//проверяем типы
				CaplEntity *ent_t=attr->inst_type;
				if(0==ent_t)bCheck = true; // на всякий случай
				else 
				{
					if(ent_t==ent_inst1) bCheck = true;
					else
					{
						for(k = 0;k<ent_t->all_subtypes.GetSize();k++)
						{
							if(ent_inst1==ent_t->all_subtypes[k])
							{ 
								bCheck = true;
								break;
							}
						}
					}
				}
			}
			else if(attr->type==aplSELECT && m_bCheckSelect ) bCheck = true;
			else if(attr->type==aplAGGR && m_bCheckSelect) { bCheck = true; bAggr = true;}

			if( bCheck)
			{
				iCountAttr++;
				buf.Format(APL_T("Проверяем %s.%s"), LPCTSTR(ent->name),LPCTSTR(attr->name));
				AddLog(buf);

				aplExtent ext;
				CaplLoadData ld(m_data,DEF_SOURCE);
				ld.AddQuery(0, _T('b'),m_inst1->GetId(),ent,attr,true,false);
				ld.LoadEx(true,&ext);
				buf.Format(APL_T(" Найдено %i."), ext.GetSize());
				AddLog(buf);

				if(ext.GetSize()>0)
				{
					if(bAggr)
					{
						AddLog(APL_T(" Зачитываем данные..."));
						CaplLoadData ld(m_data,DEF_SOURCE);
						ld.AddQuery(0, _T('b'),m_inst1->GetId(),ent,attr,true,true);
						ld.LoadEx(true,&ext);
					}

					int iCurCount = 0;
					AddLog(APL_T(" Заменяем ..."));
					for(k = 0;k<ext.GetSize();k++)
					{
						iCountAttrVal++;
						if(!bAggr)	m_data->PutAttr(ext[k],attr,m_inst2);
						else
						{
							CaplAggr aggr,aggr2;
							m_data->GetAttr(ext[k],attr,aggr);
							int k1;
							for(k1 = 0;k1<aggr.GetSize();k1++)
							{
								CaplValue av;
								aggr.GetByIndex(k1,av);
								if(av.type==aplINSTANCE &&  av.instval==m_inst1)
								{
									av.Set(m_inst2	);				
								}
								aggr2.Add(av);
							}
							m_data->PutAttr(ext[k],attr,aggr2);
						}

						if(iCurCount>=10000)
						{
							int prc=(100*k)/ext.GetSize();
							buf.Format(APL_T("\r\n     Сохраняем %i (%i%%)"), k,prc);
							AddLog(buf);
							m_data->NET_SaveChanges();
							iCurCount = 0;
						}
						iCurCount++;
					}
					AddLog(APL_T(" Сохраняем ..."));
					m_data->NET_SaveChanges();
					AddLog(_T(" Ok \r\n"));
				}
				else AddLog(_T("\r\n"));
			}
		}
	}
	buf.Format(APL_T("\r\nИтого обработано %i атрибутов.  Заменено %i значений."),iCountAttr,iCountAttrVal);
	AddLog(buf);
	m_bResult = true;
	m_run_btn.EnableWindow(FALSE);
}
