// Condition.cpp: implementation of the CReportBound class.
//
//////////////////////////////////////////////////////////////////////

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

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

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

CCondition::CCondition(CaplReportMgr* mgr)
{
	ASSERT(mgr);
	m_report_mgr = mgr;
	m_inst = NULL;
	m_type = aplEQUAL;
	m_value_type = aplNOTYPE;
	m_str_value = _T("");
	m_int_value = 0;
	m_double_value = 0;
}

CCondition::~CCondition()
{
}

void CCondition::Set(int type, int val)
{
	m_type = type;
	m_value_type = aplINTEGER;
	m_int_value = val;
}

void CCondition::Set(int type, CString &val)
{
	m_type = type;
	m_value_type = aplSTRING;
	m_str_value = val;
}

void CCondition::Set(int type, double val)
{
	m_type = type;
	m_value_type = aplREAL;
	m_double_value = val;
}

bool CCondition::Compare(CString &val)
{
	if(m_value_type!=aplSTRING) return false;
	CString buf;
	buf = m_str_value;
	if(m_str_value.GetLength()>0)
	{
		if(m_str_value[0]==_T('$'))//Значит необходимо сравнить со значением параметра
		{
			buf = m_str_value.Right(m_str_value.GetLength()-1);
			int ind = m_report_mgr->m_data_source.m_params.Find(buf);
			if(ind>-1)
				buf = m_report_mgr->m_data_source.m_params.GetAt(ind)->GetText();
			else
				return true;
		}
	}
	buf.MakeLower();
	val.MakeLower();
	if(m_type==aplEQUAL)
		return val.Compare(buf)==0;
	else if(m_type == aplBELOW)
		return val.Compare(buf)>0;
	else if(m_type == aplMORE)
		return val.Compare(buf)<0;
	else if(m_type==aplNOEQUAL)
		return val.Compare(buf)!=0;
	return false;
}

bool CCondition::Compare(int val)
{
	if(m_value_type!=aplINTEGER) return false;
	int int_val = m_int_value;
	if(m_str_value.GetLength()>0)
	{
		if(m_str_value[0]==_T('$'))//Значит необходимо сравнить со значением параметра
		{
			CString buf = m_str_value.Right(m_str_value.GetLength()-1);
			int ind = m_report_mgr->m_data_source.m_params.Find(buf);
			if(ind>-1)
				buf = m_report_mgr->m_data_source.m_params.GetAt(ind)->GetText();
			else
				return true;
			int_val = _atoi(buf);
		}
		else
			return false;
	}
	if(m_type==aplEQUAL)
		return val==int_val;
	else if(m_type == aplBELOW)
		return val<int_val;
	else if(m_type == aplMORE)
		return val>int_val;
	else if(m_type==aplNOEQUAL)
		return val!=int_val;
	return false;
}

bool CCondition::Compare(double val)
{
	if(m_value_type!=aplREAL) return false;
	double d_val = m_double_value;
	if(m_str_value.GetLength()>0)
	{
		if(m_str_value[0]==_T('$'))//Значит необходимо сравнить со значением параметра
		{
			CString buf = m_str_value.Right(m_str_value.GetLength()-1);
			int ind = m_report_mgr->m_data_source.m_params.Find(buf);
			if(ind>-1)
				buf = m_report_mgr->m_data_source.m_params.GetAt(ind)->GetText();
			else
				return true;
			d_val = _atoi(buf);
		}
		else
			return false;
	}
	if(m_type==aplEQUAL)
		return val==d_val;
	else if(m_type == aplBELOW)
		return val<d_val;
	else if(m_type == aplMORE)
		return val>d_val;
	else if(m_type==aplNOEQUAL)
		return val!=d_val;
	return false;
}

bool CCondition::Compare(CaplReportValue* val)
{
	if(m_value_type!=val->type) return false;
	if(val->type==aplSTRING)
	{
		CString str;
		val->Get(str);
		return Compare(str);
	}
	if(val->type==aplINTEGER)
	{
		int ival;
		val->Get(ival);
		return Compare(ival);
	}
	if(val->type==aplREAL)
	{
		double dval;
		val->Get(dval);
		return Compare(dval);
	}
	return false;
}

void CCondition::Update(bool set)
{
	if(set)
	{
		if(m_inst==0)
			m_inst = m_report_mgr->m_data->CreateInstance(m_report_mgr->e_apl_condition);
		
		int type = m_type;
		type |= m_flag;
		
		m_report_mgr->m_data->PutAttr(m_inst,m_report_mgr->a_apl_condition_type,type);
		m_report_mgr->m_data->PutAttr(m_inst,m_report_mgr->a_apl_condition_value_type,m_value_type);
		CString str = GetText();
		m_report_mgr->m_data->PutAttr(m_inst,m_report_mgr->a_apl_condition_value,str);
		CaplInstance* inst = NULL;
		if(m_column)
			m_report_mgr->m_data->PutAttr(m_inst,m_report_mgr->a_apl_condition_ds_column,m_column->m_inst);
		else
			m_report_mgr->m_data->PutAttr(m_inst,m_report_mgr->a_apl_condition_ds_column,(CaplInstance*)NULL);
	}
	else
	{
		if(m_inst==0)
		{
			TRACE(APL_T("Не прочитал условие\n"));
			return;
		}
		int type;
		m_report_mgr->m_data->GetAttr(m_inst,m_report_mgr->a_apl_condition_type,type);
		
		if(type&aplCOMPARE_OR)
		{
			m_flag = aplCOMPARE_OR;
			m_type = type & ~m_flag;
		}
		else
		{
			m_flag = aplCOMPARE_AND;
			m_type = type & ~aplCOMPARE_AND;
		}

		m_report_mgr->m_data->GetAttr(m_inst,m_report_mgr->a_apl_condition_value_type,m_value_type);
		CString val;
		m_report_mgr->m_data->GetAttr(m_inst,m_report_mgr->a_apl_condition_value,val);
		if(m_value_type==aplINTEGER) Set(m_type,_atoi(val));
		else if(m_value_type==aplREAL) Set(m_type,__atof(val));
		else if(m_value_type==aplSTRING) Set(m_type,val);
		CaplInstance* inst;
		m_report_mgr->m_data->GetAttr(m_inst,m_report_mgr->a_apl_condition_ds_column, inst);
		int i = m_report_mgr->m_base_query->Find(inst);
		if(i<0)
		{
			i = m_report_mgr->m_header->Find(inst);
			m_column = m_report_mgr->m_header->GetColumn(i);
		}
		else
			m_column = m_report_mgr->m_base_query->GetColumn(i);
	}
}

void CCondition::Delete(CaplReportMgr *mgr)
{
	if(m_inst!=0)
		mgr->m_data->DeleteInstance(m_inst);
}

CString CCondition::GetText()
{
	if(m_value_type==aplSTRING)	return m_str_value;
	else if(m_value_type==aplREAL)
	{
		CString str;
		CDataSource::GetDoubleAsString(m_double_value, str);
		return str;
	}
	else if(m_value_type==aplINTEGER)
	{
		CString str;
		str.Format(_T("%d"),m_int_value);
		return str;
	}
	return _T("");
}
