//-----------------------------------------------------------------------------
#include "DataConversion.h"
#include "PropTree.h"
#include "PropData.h"
#include "SpinEditorDouble.h"
#include <wxPropGrid/Include/propdev.h>
#include <wxPropGrid/Include/advprops.h>
#include <limits>
#include <vector>
#include <string>
#include <sstream>

//------------------------------------------------------------------------------
using namespace std;
using namespace mvIMPACT::acquire;

//=============================================================================
//========================= PropData ==========================================
//=============================================================================
//-----------------------------------------------------------------------------
PropData::PropData( HOBJ hObj ) : m_Component( hObj ), 
	m_lastChangedCounter(numeric_limits<unsigned int>::max()),
	m_lastChangedCounterAttr(numeric_limits<unsigned int>::max()), m_pParentGrid(0) {}
//-----------------------------------------------------------------------------

//------------------------------------------------------------------------------
void PropData::AppendComponentInfo( wxString &info, unsigned int actChangedCount, unsigned int actAttrChangedCount )
//------------------------------------------------------------------------------
{
	ostringstream oss;
	oss << ", hObj: ";
	oss.setf( std::ios::hex, std::ios::basefield );
	oss.setf( std::ios::uppercase );
	oss << m_Component.hObj();
	oss.unsetf( std::ios::hex | std::ios::uppercase );
	oss << ", cc: " << actChangedCount
		<< ", cca: " << actAttrChangedCount
		<< ", type: " << m_Component.typeAsString()
		<< ", flags: " << m_Component.flagsAsString();

	if( m_Component.isProp() )
	{
		Property prop(m_Component);
		if( prop.isConstDefined( plMinValue ) )
		{
			oss << ", min: " << prop.readS( plMinValue );
		}
		if( prop.isConstDefined( plMaxValue ) )
		{
			oss << ", max: " << prop.readS( plMaxValue );
		}
		if( prop.isConstDefined( plStepWidth ) )
		{
			oss << ", step width: " << prop.readS( plStepWidth );
		}
	}
	info.Append( oss.str().c_str() );
}

//------------------------------------------------------------------------------
void PropData::UpdateGridItem( PropTree *pPropTree, bool boDisplayDebugInfo, bool boDisplayInvisibleComponents, bool *boModified )
//------------------------------------------------------------------------------
{
	unsigned int actChangedCount = m_Component.changedCounter();
	unsigned int actAttrChangedCount = m_Component.changedCounterAttr();

	if( ( m_lastChangedCounter != actChangedCount ) || ( m_lastChangedCounterAttr != actAttrChangedCount ) )
	{
		Update( pPropTree, boDisplayDebugInfo, actChangedCount, actAttrChangedCount );
		m_lastChangedCounter = actChangedCount;
		m_lastChangedCounterAttr = actAttrChangedCount;
		if( boModified )
		{
			*boModified = true;
		}
	}
	else if( boModified )
	{
		*boModified = false;
	}

	if( !m_pParentGrid->IsPropertySelected( m_GridItemId ) )
	{
		if( boDisplayInvisibleComponents )
		{
			m_pParentGrid->SetPropertyPriority( m_GridItemId, wxPG_HIGH );
			m_pParentGrid->SetPropertyColour( m_GridItemId, m_Component.isVisible() ? ( m_Component.isList() ? ListObject::BACKGROUND_COLOR : wxColour(255,255,255) ): wxColour(0,255,0) );
		}
		else
		{
			m_pParentGrid->SetPropertyPriority( m_GridItemId, m_Component.isVisible() ? wxPG_HIGH : wxPG_LOW );
		}
	}
}

//=============================================================================
//========================= MethodObject ======================================
//=============================================================================
//-----------------------------------------------------------------------------
MethodObject::MethodObject( HOBJ hObj ) : PropData( hObj ), m_Params( "" )
//-----------------------------------------------------------------------------
{
	string::size_type end = 0;
	string name(m_Component.name());

	if( ( end = name.find_first_of( "@" ) ) != string::npos )
	{
		name = name.substr( 0, end );
	}

	Method meth(m_Component);
	string para_type_str = meth.paramList();
	string comma = " ";

	string::const_iterator  it = para_type_str.begin();
	m_FriendlyName = charToType( *it++ );
	m_FriendlyName += comma;
	m_FriendlyName += name + "(";

	for( ; it<para_type_str.end(); it++, comma = ", " )
	{	
		m_FriendlyName += comma;
		m_FriendlyName += charToType( *it );
	}
	m_FriendlyName += " )";
}

//------------------------------------------------------------------------------
string MethodObject::Call()
//------------------------------------------------------------------------------
{
	if( m_GridItemId.GetPropertyPtr() && m_Component.isMeth() )
	{	
		wxString params = m_GridItemId.GetPropertyPtr()->GetValueAsString();
		Method meth(m_Component);
		int callResult;

		try
		{
			callResult = meth.call( params.c_str(), " " );		
		}
		catch( ImpactAcquireException& e )
		{
			callResult = e.getErrorCode();
			wxString errorString(wxString::Format( wxT("An error occurred while executing function %s: %s(numerical error representation: %d(%s))."), m_FriendlyName.c_str(), e.getErrorString().c_str(), e.getErrorCode(), e.getErrorCodeAsString().c_str() ));
			errorString.append( wxString::Format( wxT("Error origin: %s"), e.getErrorOrigin().c_str() ) );
			wxMessageDialog errorDlg( NULL, errorString, wxT("Error"), wxOK | wxICON_INFORMATION );
			errorDlg.ShowModal();
		}

		ostringstream resStream;
		resStream << "[ Last call info: " << m_FriendlyName
			<< "( " << string(params.c_str()) << " )";
		char retType = meth.paramList()[0];
		if( retType != 'v' )
		{
			resStream << " = " << ImpactAcquireException::getErrorCodeAsString( callResult );
		}
		resStream << " ]";
		return resStream.str();
	}
	return "Invalid method object";
}

//------------------------------------------------------------------------------
void MethodObject::UpdatePropData()
//------------------------------------------------------------------------------
{
	if( m_GridItemId.GetPropertyPtr() )
	{	
		m_Params = m_GridItemId.GetPropertyPtr()->GetValueAsString().c_str();
	}
}

//------------------------------------------------------------------------------
void MethodObject::Update( PropTree* /*pPropTree*/, bool boDisplayDebugInfo, unsigned int actChangedCount, unsigned int actAttrChangedCount )
//------------------------------------------------------------------------------
{
	wxString label( m_FriendlyName.c_str() );
	if( boDisplayDebugInfo )
	{
		AppendComponentInfo( label, actChangedCount, actAttrChangedCount );
	}
	if( m_GridItemId.GetPropertyPtr() )
	{
		m_GridItemId.GetPropertyPtr()->SetValueFromString( m_Params.c_str() );
		m_GridItemId.GetPropertyPtr()->SetLabel( label );
	}	
}

//------------------------------------------------------------------------------
void MethodObject::EnsureValidGridItem( PropTree *pPropTree, wxPGId parentItem, bool* boModified /* = 0 */ )
//------------------------------------------------------------------------------
{
	if( !m_GridItemId.GetPropertyPtr() )
	{	
		Method meth(m_Component);
		m_pParentGrid = pPropTree->GetPropGrid();
		m_GridItemId = m_pParentGrid->AppendIn( parentItem, wxStringProperty( wxT(m_FriendlyName.c_str()),wxPG_LABEL, wxT("") ) );

		m_Type = _ctrlEdit;
		if( m_GridItemId.GetPropertyPtr() )
		{
			m_GridItemId.GetPropertyPtr()->SetClientData( this );
		}
		
		if( boModified )
		{
			*boModified = true;
		}
	}
}

//=============================================================================
//========================= ListObject ========================================
//=============================================================================
const wxColour	ListObject::BACKGROUND_COLOR = wxColour(230, 230, 230);
string			ListObject::m_colourKey = string("<color>");

//-----------------------------------------------------------------------------
ListObject::ListObject( HOBJ hObj, const char *pTitle /* = 0 */ )
: PropData( hObj ), m_boExpanded(FALSE)
//-----------------------------------------------------------------------------
{
	if( pTitle )
	{
		m_Title = wxString(pTitle); 
	}
}

//-----------------------------------------------------------------------------
void ListObject::OnExpand()
//------------------------------------------------------------------------------
{
	if( m_GridItemId.GetPropertyPtr() && m_pParentGrid )
	{
		m_boExpanded = m_pParentGrid->IsPropertyExpanded( m_GridItemId );
	}

	//UpdateLabel();
}

//------------------------------------------------------------------------------
void ListObject::EnsureValidGridItem( PropTree *pPropTree, wxPGId parentItem, bool* boModified/* = 0 */ )
//------------------------------------------------------------------------------
{
	if( !m_GridItemId.GetPropertyPtr() )
	{	
		m_pParentGrid = pPropTree->GetPropGrid();
		m_GridItemId = m_pParentGrid->AppendIn( parentItem, wxParentProperty(wxT(m_Component.name().c_str()),wxPG_LABEL) );
		m_Type = _ctrlStatic;
		m_pParentGrid->SetPropertyClientData( m_GridItemId, this );
		ComponentList list(m_Component);
		string contDesc(list.contentDescriptor());
		if( !contDesc.empty() )
		{
			m_GridItemId.GetPropertyPtr()->SetValueFromString( list.contentDescriptor().c_str() );
			m_pParentGrid->SetPropertyTextColour( m_GridItemId, *wxBLUE );
		}
		m_pParentGrid->SetPropertyColour( m_GridItemId, BACKGROUND_COLOR );
		m_pParentGrid->DisableProperty( m_GridItemId );
		if( boModified )
		{
			*boModified = true;
		}
	}
}

//------------------------------------------------------------------------------
bool ListObject::GetColour( string& text, wxColour& colour )
//------------------------------------------------------------------------------
{
	string::size_type end = 0;
	if ( ( end = text.find( m_colourKey, 0 ) ) != string::npos )
	{
		string tempstring = text.substr( end + m_colourKey.size() );
		text = text.substr( end + m_colourKey.size() + 1 );

		switch( tempstring.at(0) )
		{
		case 'r':
			colour = wxColour( *wxRED );
			break;
		case 'g':
			colour = wxColour( *wxGREEN );
			break;
		case 'b':
			colour = wxColour( *wxBLUE );
			break;
		default:
			colour = wxColour( *wxBLACK );
			break;
		}
		return true;
	}
	return false;
}

//------------------------------------------------------------------------------
void ListObject::Update( PropTree* /*pPropTree*/, bool boDisplayDebugInfo, unsigned int actChangedCount, unsigned int actAttrChangedCount )
//------------------------------------------------------------------------------
{
	if( boDisplayDebugInfo )
	{
		wxString label = ( m_Title.empty() ) ? m_Component.name().c_str() : m_Title.c_str();
		label.Append( wxString::Format( "[%d]", ComponentList(m_Component).size() ) );
		AppendComponentInfo( label, actChangedCount, actAttrChangedCount );
		m_GridItemId.GetPropertyPtr()->SetLabel( label );
	}
	else if( actAttrChangedCount != m_lastChangedCounterAttr )
	{
		wxString label = ( m_Title.empty() ) ? m_Component.name().c_str() : m_Title.c_str();
		m_GridItemId.GetPropertyPtr()->SetLabel( label );
		ComponentList list(m_Component);
		string contDesc(list.contentDescriptor());
		if( !contDesc.empty() )
		{
			m_GridItemId.GetPropertyPtr()->SetValueFromString( list.contentDescriptor().c_str() );
			m_pParentGrid->SetPropertyTextColour( m_GridItemId, *wxBLUE );
		}
	}
}

//=============================================================================
//========================= PropertyObject ====================================
//=============================================================================
//-----------------------------------------------------------------------------
PropertyObject::PropertyObject( HOBJ hObj, int index /* = 0 */ )
: PropData( hObj ), m_boVectorAsList(false) 
//-----------------------------------------------------------------------------
{
	m_boVectorAsList = ( index >= 0 );
	m_Index = ( index < 0 ) ? 0 : index;
}

//-----------------------------------------------------------------------------
void PropertyObject::WritePropVal( const std::string& value )
//-----------------------------------------------------------------------------
{
	Property prop( m_Component );
	if( !m_boVectorAsList )
	{
		prop.writeS( value );
	}
	else
	{
		// only write one value to the property!
		string::size_type end = value.find_first_of( " " );
		prop.writeS( ( end != string::npos ) ? value.substr( 0, end ) : value, m_Index );
	}
	// instead of writing the same value twice we set the text color fixed to 
	// 'not default' here, as the property has been successfully modifed when we
	// reach this code and therefore can't be a derived property anymore.
	//m_pGridItemId->SetTextColor( GetSysColor(COLOR_WINDOWTEXT) );
}

//------------------------------------------------------------------------------
void PropertyObject::UpdatePropData()
//------------------------------------------------------------------------------
{
	if( m_GridItemId.GetPropertyPtr() )
	{	
		wxString errorString;
		Property prop( m_Component );
		try
		{
			WritePropVal( m_GridItemId.GetPropertyPtr()->GetValueAsString().c_str() );
		}
		catch( const EValTooSmall& )
		{
			errorString = wxT("Value too small! Clipping to minimum!");
			WritePropVal( prop.readS( plMinValue ) );
		}
		catch( const EValTooLarge& )
		{
			errorString = wxT("Value too large! Clipping to maximum!");
			WritePropVal( prop.readS( plMaxValue ) );
		}
		catch( const ENoModifySizeRights& )
		{
			errorString = wxString::Format( wxT("This property can store %d value(s) only!"), prop.valCount() );
		}
		catch( ImpactAcquireException& e )
		{
			errorString = wxString::Format( wxT("Can't set value( Error: %s(%s))!"), e.getErrorString().c_str(), e.getErrorCodeAsString().c_str() );
		}

		if( !errorString.IsEmpty() )
		{
			wxMessageDialog errorDlg( NULL, errorString, wxT("Error"), wxOK | wxICON_INFORMATION );
			errorDlg.ShowModal();
		}
	}
}

//------------------------------------------------------------------------------
void PropertyObject::EnsureValidGridItem( PropTree *pPropTree, wxPGId parentItem, bool* boModified /* = 0 */ )
//------------------------------------------------------------------------------
{
	m_pParentGrid = pPropTree->GetPropGrid();
	if( !m_GridItemId.GetPropertyPtr() )
	{	
		TComponentType type = m_Component.type();
		switch( type )
		{
		case ctPropInt:
			{
				PropertyI intProp( m_Component );
				if( ( intProp.isConstDefined( PROP_MIN_VAL ) || intProp.isConstDefined( PROP_MAX_VAL ) )  
					&& ( intProp.dictSize() == 0 ) && intProp.isWriteable() )
				{
					m_Type = _ctrlSpinner;
				}
				else if( ( intProp.dictSize() != 0 ) && intProp.isWriteable() )
				{
					m_Type = _ctrlCombo;
				}
				else
				{
					m_Type = _ctrlEdit;
				}
			}
			break;
		case ctPropFloat:
			{
				PropertyF floatProp( m_Component );
				if( ( floatProp.isConstDefined( PROP_MIN_VAL ) || floatProp.isConstDefined( PROP_MAX_VAL ) )  
					&& ( floatProp.dictSize() == 0 ) && floatProp.isWriteable() )
				{
					m_Type = _ctrlSpinner;
				}
				else if( ( floatProp.dictSize() != 0 ) && floatProp.isWriteable() )
				{
					m_Type = _ctrlCombo;
				}
				else
				{
					m_Type = _ctrlEdit;
				}
			}
			break;
		case ctPropString:
			m_Type = _ctrlEdit;
			break;
		case ctPropPtr:
			m_Type = _ctrlEdit;
			break;
		default:
			break;
		}

		switch( m_Type )
		{
		case _ctrlSpinner:
			if( ( type == ctPropInt ) || ( type == ctPropFloat ) )
			{
				m_GridItemId = m_pParentGrid->AppendIn( parentItem, wxStringProperty(wxT(m_Component.name().c_str()),wxPG_LABEL) );
			}
			else
			{
				// invalid type for spinner
				wxASSERT(0); 
			}
			pPropTree->GetPropGrid()->SetPropertyEditor( m_GridItemId, wxPGSpinCtrlEditor::Instance() );
			break;
		case _ctrlEdit:
			m_GridItemId = m_pParentGrid->AppendIn( parentItem, wxStringProperty(wxT(m_Component.name().c_str()),wxPG_LABEL) );
			break;
		case _ctrlCombo:
			{
				PropertyI prop(m_Component);
				if( prop.hasDict() )
				{
					vector<pair<string, int> > dict;
					prop.getTranslationDict( dict );
					wxPGChoices soc;

					vector<pair<string, int> >::iterator it = dict.begin(), itEnd = dict.end();
					while( it != itEnd )
					{
						soc.Add( wxT(it->first.c_str()), it->second );
						++it;
					}
					m_GridItemId = m_pParentGrid->AppendIn( parentItem, wxEnumProperty(wxT(prop.name().c_str()), wxPG_LABEL, soc, 240 ) );
				}
			}
			break;
		default:
			break;
		}

		m_pParentGrid->SetPropertyClientData( m_GridItemId, this );
		if( boModified )
		{
			*boModified = true;
		}
	}
}

//------------------------------------------------------------------------------
void PropertyObject::UpdateLabel( bool boDisplayDebugInfo, unsigned int actChangedCount, unsigned int actAttrChangedCount )
//------------------------------------------------------------------------------
{
	wxString label( m_Component.name().c_str() );
	if( m_boVectorAsList )		
	{
		label.Append( wxString::Format( "[%d]", m_Index ) );
	}
	else
	{
		int valCount = Property( m_Component ).valCount();
		if( valCount > 1 )
		{
			label.Append( wxString::Format( "[%d]", valCount ) );
		}
	}
	if( boDisplayDebugInfo )
	{
		AppendComponentInfo( label, actChangedCount, actAttrChangedCount );
	}
	m_pParentGrid->SetPropertyLabel( m_GridItemId, label );
	m_pParentGrid->SetPropertyTextColour( m_GridItemId, m_Component.isWriteable() ? ( m_Component.isDefault() ? wxColour( 15, 113, 18 ) : wxSystemSettings::GetColour ( wxSYS_COLOUR_WINDOWTEXT ) ) : wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );	
}

//------------------------------------------------------------------------------
void PropertyObject::Update( PropTree* /*pPropTree*/, bool boDisplayDebugInfo, unsigned int actChangedCount, unsigned int actAttrChangedCount )
//------------------------------------------------------------------------------
{
	Property prop( m_Component );

	switch( Type() )
	{
	case _ctrlEdit:
		{
			string str;
			if( ( prop.valCount() > 1 ) && !m_boVectorAsList )
			{
				unsigned int valCnt = prop.valCount();
				for( unsigned int i=0; i<valCnt; i++ )
				{
					str.append( prop.readS( i ) );
					str.append( " " );
				}
			}
			else
			{
				str.append( prop.readS( m_Index ) );
			}
			m_pParentGrid->SetPropertyValue( m_GridItemId, str.c_str() );
		}
		break;
	case _ctrlCombo:
		{
			if( actAttrChangedCount != m_lastChangedCounterAttr )
			{
				PropertyI prop(m_Component);
				vector<pair<string, int> > dict;
				prop.getTranslationDict( dict );
				wxPGChoices soc;

				vector<pair<string, int> >::iterator it = dict.begin(), itEnd = dict.end();
				while( it != itEnd )
				{
					soc.Add( wxT(it->first.c_str()), it->second );
					++it;
				}
				m_pParentGrid->SetPropertyChoices( m_GridItemId, soc );
				m_GridItemId.GetPropertyPtr()->SetClientData( this );
			}
		}
	case _ctrlSpinner:
		m_pParentGrid->SetPropertyValue( m_GridItemId, prop.readS( m_Index ).c_str() );
		break;
	default:
		break;
	}

	// read-only / read-write state
	if( !m_Component.isWriteable() )
	{
		m_pParentGrid->DisableProperty( m_GridItemId );
	}
	else if( !m_pParentGrid->IsPropertyEnabled( m_GridItemId ) )
	{
		m_pParentGrid->EnableProperty( m_GridItemId );
	}
	UpdateLabel( boDisplayDebugInfo, actChangedCount, actAttrChangedCount );
}

//=============================================================================
//========================= VectorPropertyObject ==============================
//=============================================================================
//-----------------------------------------------------------------------------
VectorPropertyObject::VectorPropertyObject( HOBJ hObj )
	: PropData( hObj ), m_boExpanded(false), m_Property( hObj ) {}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
VectorPropertyObject::~VectorPropertyObject()
//-----------------------------------------------------------------------------
{
	for( size_t i=0; i<m_VectorItems.size(); i++ )
	{
		delete m_VectorItems[i];
	}
}

//-----------------------------------------------------------------------------
void VectorPropertyObject::OnExpand()
//------------------------------------------------------------------------------
{
	if( m_GridItemId.GetPropertyPtr() && m_pParentGrid )
	{
		m_boExpanded = m_pParentGrid->IsPropertyExpanded( m_GridItemId );
	}
}

//------------------------------------------------------------------------------
PropData* VectorPropertyObject::GetVectorItem( int index )
//------------------------------------------------------------------------------
{
	int vSize = m_VectorItems.size();
	for( int i=vSize; i<=index; i++ )
	{
		m_VectorItems.push_back( new PropertyObject( m_Component, i ) );
	}
	return m_VectorItems.at(index);
}

//------------------------------------------------------------------------------
void VectorPropertyObject::EnsureValidGridItem( PropTree* pPropTree, wxPGId parentItem, bool* boModified /* = 0 */ )
//------------------------------------------------------------------------------
{
	if( !m_GridItemId.GetPropertyPtr() )
	{	
		m_pParentGrid = pPropTree->GetPropGrid();
		m_GridItemId = m_pParentGrid->AppendIn( parentItem, wxParentProperty(wxT(m_Component.name().c_str()),wxPG_LABEL) );
		m_Type = _ctrlStatic;
		m_pParentGrid->SetPropertyClientData( m_GridItemId, this );
		m_pParentGrid->DisableProperty( m_GridItemId );
		if( boModified )
		{
			*boModified = true;
		}
	}
	for( unsigned int i=0; i<m_Property.valCount(); i++ )
	{
		pPropTree->CreateGridProperty( m_Component, m_GridItemId, i );
	}
}

//-----------------------------------------------------------------------------
void VectorPropertyObject::RemoveValue( unsigned int index )
//-----------------------------------------------------------------------------
{
	Property prop(m_Component);
	unsigned int propValCount = prop.valCount();
	unsigned int vSize = m_VectorItems.size();
	if( ( propValCount > index ) && ( vSize > index ) && ( vSize > 1 ) )
	{
		prop.removeValue( index );
		wxPGId item = m_VectorItems[index]->GetGridItem();
		if( item.IsOk() )
		{
			m_pParentGrid->Delete( item );
		}
		delete m_VectorItems[index];
		m_VectorItems.erase( m_VectorItems.begin() + index );
	}
}

//------------------------------------------------------------------------------
void VectorPropertyObject::Resize( void )
//------------------------------------------------------------------------------
{
	Property prop(m_Component);
	unsigned int propValCount = prop.valCount();
	unsigned int vSize = m_VectorItems.size();
	if( propValCount < vSize )
	{
		for( unsigned int i=propValCount; i<vSize; i++ )
		{
			wxPGId item = m_VectorItems[i]->GetGridItem();
			if( item.IsOk() )
			{
				m_pParentGrid->Delete( item );
			}
			delete m_VectorItems[i];
		}
		m_VectorItems.resize( propValCount );
	}
	else if( propValCount > vSize )
	{
		for( unsigned int i=vSize; i<propValCount; i++ )
		{
			m_VectorItems.push_back( new PropertyObject( m_Component, static_cast<int>(i) ) );
		}
	}
}

//-----------------------------------------------------------------------------
void VectorPropertyObject::Update( PropTree* pPropTree, bool boDisplayDebugInfo, unsigned int actChangedCount, unsigned int actAttrChangedCount )
//-----------------------------------------------------------------------------
{
	Property prop(m_Component);
	unsigned int valCnt = prop.valCount(), vSize = m_VectorItems.size();
	wxString label( wxString::Format( "%s[%d]", prop.name().c_str(), valCnt ) );
	if( boDisplayDebugInfo )
	{
		AppendComponentInfo( label, actChangedCount, actAttrChangedCount );
	}
	m_pParentGrid->SetPropertyLabel( m_GridItemId, label );
	wxString val( wxString::Format( "[%s]", prop.readSArray( "", ", " ).c_str() ) );
	m_GridItemId.GetPropertyPtr()->SetValueFromString( val );
	while( valCnt > vSize )
	{
		pPropTree->CreateGridProperty( m_Component, m_GridItemId, vSize++ );
	}
	m_pParentGrid->SetPropertyTextColour( m_GridItemId, prop.isDefault() ? wxColour( 15, 113, 18 ) : wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
}
