// ReportParam.cpp: implementation of the CReportParam class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PapamPropDlg.h"
#include "ReportDict.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CReportParam::CReportParam(CaplReportMgr* dict)
{
	ASSERT(dict);
	m_ReportMgr = dict;
	m_type = STRING_PARAM;
	m_str_val = _T("");
	m_inst_val = NULL;
	m_int_val = 0;
	m_inst = NULL;

	m_crc32_val = 0;

	m_ReportMgr->m_data_source.m_params.Add(this);
}

CReportParam::~CReportParam()
{
}

void CReportParam::Update(bool set)
{
	if(set)
	{
		if(m_inst == NULL)
			m_inst = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_param);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_param_name,m_name);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_param_type,m_type);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_param_value,GetText());
	}
	else
	{
		if(m_inst == NULL) return;
		int tmpInt;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_param_name, m_name);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_param_type, tmpInt);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_param_value, m_str_val);
		m_type = (TParamTypes)tmpInt;
		if(m_type==INT_PARAM)
		{
			m_int_val = _atoi(m_str_val);
			m_str_val = _T("");
		}
	}
}

void CReportParam::SetParam(CString val, TParamTypes mode)
{
	m_type = mode;
	m_str_val = val;
}

void CReportParam::SetParam(int val)
{
	m_type = INT_PARAM;
	m_int_val =val;
}

void CReportParam::SetParam(CaplInstance* val)
{
	m_type = OBJ_PARAM;
	m_inst_val = val;
}

TParamTypes CReportParam::GetType() const
{
	return m_type;
}

CString CReportParam::GetText()
{
	if(m_type==STRING_PARAM || m_type==DATE_PARAM)
		return m_str_val;
	else if(m_type==INT_PARAM)
	{
		CString str;
		str.Format(_T("%d"),m_int_val);
		return str;
	}
	else if(m_type==CRC32_PARAM)
	{
		if(m_crc32_val==0)
		{
			CString file_name = m_ReportMgr->m_data->m_file.GetFilePath();
			if(!file_name.IsEmpty())
				m_crc32_val = GetFileCRC32(file_name);
		}
		CString str;
		str.Format(_T("0x%X"), m_crc32_val);
		return str;
	}	

	return _T("");
}

void CReportParam::SetType(TParamTypes type)
{
	ASSERT(type>=0 && type<=CRC32_PARAM);
	m_type = type;
	m_str_val = _T("");
	m_int_val = 0;
	m_inst_val = NULL;
}

bool CReportParam::ShowProp()
{
	HINSTANCE hInst = AfxGetResourceHandle();
	AfxSetResourceHandle(dllInst);
	CParamPropDlg dlg(m_ReportMgr);
	dlg.m_param = this;
	if(dlg.DoModal()==IDOK) 
	{
		AfxSetResourceHandle(hInst);
		return true;
	}
	AfxSetResourceHandle(hInst);
	return false;
}

int CParamArray::GetSize()
{
	return m_Data.GetSize();
}

CReportParam* CParamArray::GetAt(int i)
{
	if(i<0 || i>m_Data.GetSize()) return NULL;
	return m_Data.GetAt(i);
}

void CParamArray::RemoveAll()
{
	int cnt = m_Data.GetSize();
	for(int i=0; i<cnt;i++)
	{
		CReportParam* par = m_Data.GetAt(i);
		if(par!=0)
			DELETE_OBJECT(par);
	}
	m_Data.RemoveAll();
}

void CParamArray::DeleteAll()
{
	int i;
	int cnt = m_Data.GetSize();
	if(cnt==0) return;
	CaplReportMgr* dict = m_Data.GetAt(0)->GetDict();
	for(i=0; i<cnt;i++)
	{
		CReportParam* par = m_Data.GetAt(i);
		if(par==0) continue;
		if(par->m_inst!=0)
			par->GetDict()->m_data->DeleteInstance(par->m_inst);
		DELETE_OBJECT(par);
	}
	m_Data.RemoveAll();
	//Удаляем ссылки у всех елементов...
	RE_Array els;
	aplExtent del;

	CReportElement* elem;
	CRectReportElement* RectElem;
	cnt = dict->m_sheets.GetSize();
	for(i=0; i<cnt;i++)
	{
		CReportSheet* sheet = dict->m_sheets.GetAt(i);
		if(sheet->m_els.GetSize()>0)
		{
			int els_cnt = sheet->m_els.GetSize();
			for(int j=0;j<els_cnt;j++)
			{
				elem = sheet->m_els.GetAt(j);
				if(elem->GetType()==E_RECT)
				{
					RectElem = (CRectReportElement*)elem;
					if(RectElem->m_value.GetType()!=INST_VAL) continue;
					del.Add(RectElem->m_value.m_inst);
					els.Add(sheet->m_els.GetAt(j));
				}
			}
		}
		else
		{
			aplExtent ext;
			sheet->Update();
			dict->m_data->GetAttr(sheet->m_inst,dict->a_rep_sheet_els,ext);
			int els_cnt = ext.Size;
			for(int j=0;j<els_cnt;j++)
			{
				if(dict->m_data->IsKindOf(ext[j],dict->e_report_rect))
				{
					CaplInstance* tval;
					dict->m_data->GetAttr(ext[j],dict->a_elem_text_val,tval);
					int type;
					dict->m_data->GetAttr(tval,dict->a_val_type,type);
					if(type!=INST_VAL) continue;
					del.Add(tval);
				}
			}
		}
	}
	cnt = del.Size;
	for(i=0; i<cnt;i++)
	{
		dict->m_data->PutAttr(del[i], dict->a_val_inst, 0);
		dict->m_data->PutAttr(del[i], dict->a_val_type, TEXT_VAL);
		dict->m_data->PutAttr(del[i], dict->a_val_text, _T(""));
	}
	cnt = els.GetSize();
	for(i=0; i<cnt;i++)
	{
		elem = els.GetAt(i);
		if(elem->GetType()==E_RECT)
			((CRectReportElement*)elem)->m_value.SetText(_T(""));
	}
}

void CParamArray::RemoveAt(int i)
{
	if(i<0 || i>m_Data.GetSize()) return;
	CReportParam* par = m_Data.GetAt(i);
	if(par!=0) delete par;
	m_Data.RemoveAt(i);
}

int CParamArray::Find(CReportParam *par)
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		if(par==m_Data.GetAt(i)) return i;

	}
	return -1;
}

int CParamArray::Find(CString &name)
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		if(name==m_Data.GetAt(i)->m_name) return i;
	}
	return -1;
}

int CParamArray::Find(CaplInstance *inst)
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		if(inst==m_Data.GetAt(i)->m_inst) return i;
	}
	return -1;
}

int CParamArray::Add(CReportParam *par)
{
	if(par==0) return -1;
	return m_Data.Add(par);
}

bool CParamArray::IsUnique(CString name, CReportParam* par)
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		if(name==m_Data.GetAt(i)->m_name && par!=m_Data.GetAt(i)) return false;
	}
	return true;
}

CaplReportMgr* CReportParam::GetDict()
{
	return m_ReportMgr;
}

int CParamArray::Find(int type)
{
	for(int i=0; i<m_Data.GetSize();i++)
		if(type==m_Data.GetAt(i)->GetType()) return i;
	return -1;
}


CConditionArray::CConditionArray(CaplReportMgr* mgr)
{
	ASSERT(mgr);
	m_report_mgr = mgr;
	m_data.RemoveAll();
}

CConditionArray::~CConditionArray()
{
	RemoveAll();
}

CConditionArray& CConditionArray::operator = (CConditionArray& CondArr)
{
	RemoveAll();
	int cnt = CondArr.GetSize();
	for(int i=0; i<cnt; i++)
	{
		CCondition* nCond = new CCondition(m_report_mgr);
		CCondition* Cond = CondArr.GetAt(i);
		*nCond = *Cond;
		m_data.Add(nCond);
	}
	return *this;
}

int CConditionArray::Add(CCondition* cond)
{
	ASSERT(cond);
	return m_data.Add(cond);
}

void CConditionArray::RemoveAll()
{
	int cnt = m_data.GetSize();
	for(int i=0; i<cnt; i++)
	{
		delete m_data[i];
	}
	m_data.RemoveAll();
}

void CConditionArray::RemoveAt(int ind)
{
	ASSERT(ind<=0);
	int cnt = m_data.GetSize();
	ASSERT(ind<=cnt);
	delete m_data[ind];
	m_data.RemoveAt(ind);
}

void CConditionArray::Update(bool set)
{
	int cnt = m_data.GetSize();
	for(int i=0; i<cnt;i++)
	{
		CCondition* cond = m_data.GetAt(i);
		cond->Update(set);
	}
}

int CConditionArray::GetSize()
{
	return m_data.GetSize();
}

CCondition* CConditionArray::GetAt(int ind)
{
	return m_data.GetAt(ind);
}

bool CConditionArray::Compare(int ind)
{
	bool ok = true;
	int cnt = m_data.GetSize();
	for(int i=0; i<cnt; i++)
	{
		CCondition* cond = m_data.GetAt(i);
		CaplReportValue* val = m_report_mgr->m_data_source.GetAt(ind,cond->m_column);
		if(i==0)
			ok = cond->Compare(val);
		else
		{
			if(cond->m_flag&aplCOMPARE_OR)
				ok = ok || cond->Compare(val);
			else
				ok = ok && cond->Compare(val);
		}
	}
	return ok;
}

void CConditionArray::GetExtent(aplExtent& ext)
{
	ext.Clear();
	int cnt = m_data.GetSize();
	for(int i=0; i<cnt;i++)
	{
		CCondition* cond = m_data.GetAt(i);
		ext.Add(cond->m_inst);
	}
}

void CSectionLevelArray::Clear()
{
	m_Data.RemoveAll();
}

int CSectionLevelArray::Add(CSectionLevel* level)
{
	if(level==0) return -1;
	return m_Data.Add(level);
}

void CSectionLevelArray::RemoveAt(int i)
{
	if(i<0 || i>=m_Data.GetSize()) return;
	CSectionLevel* level = m_Data.GetAt(i);
	level->m_columns.RemoveAll();
	if(level!=0) delete level;
	m_Data.RemoveAt(i);
	return;
}

CSectionLevel* CSectionLevelArray::GetAt(int i)
{
	if(i<0 || i>=m_Data.GetSize()) return NULL;
	return m_Data.GetAt(i);
}

void CSectionLevelArray::RemoveAll()
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		CSectionLevel* level = m_Data.GetAt(i);
		delete level;
	}
	m_Data.RemoveAll();
}

int CSectionLevelArray::GetSize()
{
	return m_Data.GetSize();
}

int CSectionLevelArray::Find(CSectionLevel* level)
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		CSectionLevel* lev = m_Data.GetAt(i);
		if(level==lev) return i;
	}
	return -1;
}

int CSectionLevelArray::Find(CString name)
{
	for(int i=0; i<m_Data.GetSize();i++)
	{
		CSectionLevel* lev = m_Data.GetAt(i);
		if(lev->m_name==name) return i;
	}
	return -1;
}

CGroupColArray::CGroupColArray()
{
	m_data.RemoveAll();
}

CGroupColArray::~CGroupColArray()
{
	RemoveAll();
}

CGroupColArray& CGroupColArray::operator = (CGroupColArray& GCArr)
{
	RemoveAll();
	int cnt=  GCArr.GetSize();
	CaplReportMgr* Mgr = NULL;
	for(int i=0; i<cnt;i++)
	{
		if(Mgr==NULL) 
			Mgr = GCArr.GetAt(i)->m_ReportMgr;
		CGroupCol* nGC = new CGroupCol(Mgr);
		CGroupCol* GC = GCArr.GetAt(i);
		*nGC=*GC;
		m_data.Add(nGC);
	}
	return *this;
}

int CGroupColArray::Add(CGroupCol* cond)
{
	ASSERT(cond);
	return m_data.Add(cond);
}

void CGroupColArray::RemoveAll()
{
	int cnt = m_data.GetSize();
	for(int i=0; i<cnt; i++)
	{
		delete m_data[i];
	}
	m_data.RemoveAll();
}

void CGroupColArray::RemoveAt(int ind)
{
	ASSERT(ind>=0);
	int cnt = m_data.GetSize();
	ASSERT(ind<=cnt);
	delete m_data[ind];
	m_data.RemoveAt(ind);
}

int CGroupColArray::GetSize()
{
	return m_data.GetSize();
}

CGroupCol* CGroupColArray::GetAt(int ind)
{
	return m_data.GetAt(ind);
}


void CGroupColArray::GetExtent(aplExtent& ext)
{
	ext.Clear();
	int cnt = m_data.GetSize();
	for(int i=0; i<cnt;i++)
	{
		ext.Add(m_data.GetAt(i)->m_inst);
	}
}

void CGroupColArray::Append(CGroupColArray* arr)
{
	int cnt = arr->GetSize();
	for(int i=0; i<cnt;i++)
	{
		m_data.Add(arr->GetAt(i));
	}
	arr->Clear();
}

void CGroupColArray::Clear()
{
	m_data.RemoveAll();
}

void CParamArray::Clear()
{
	m_Data.RemoveAll();
}

bool CGroupColArray::Move(int oPos, int nPos)
{
	if(oPos<0 || nPos<0) return false;
	CGroupCol* col = m_data.GetAt(oPos);
	m_data.RemoveAt(oPos);
	m_data.InsertAt(nPos, col);

	return true;
}