summaryrefslogtreecommitdiff
path: root/src/dae/daeMetaGroup.cpp
blob: 676141fc4dd75a5662f3e70783a56952ea3132e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* Copyright 2006 Sony Computer Entertainment Inc.
*
* Licensed under the MIT Open Source License, for details please see license.txt or the website
* http://www.opensource.org/licenses/mit-license.php
*
*/ 

#include <dae/daeMetaGroup.h>
#include <dae/daeMetaElementAttribute.h>
#include <dae/daeMetaElement.h>

daeMetaGroup::daeMetaGroup( daeMetaElementAttribute *econ, daeMetaElement *container, 
							daeMetaCMPolicy *parent, daeUInt ordinal, daeInt minO, daeInt maxO) : 
							daeMetaCMPolicy( container, parent, ordinal, minO, maxO ), _elementContainer( econ )
{}

daeMetaGroup::~daeMetaGroup()
{
	if ( _elementContainer != NULL ) {
		delete _elementContainer;
	}
}

daeElement *daeMetaGroup::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) {
	(void)offset;
	daeString nm = child->getElementName();
	if ( findChild( nm ) == NULL ) {
		return false;
	}
	daeElementRef el;

	//check if the element trying to be placed is a group element. If so Just add it don't create a new one.
	if ( strcmp( nm, _elementContainer->getName() ) == 0 ) {
		if ( _elementContainer->placeElement(parent, child, ordinal, offset ) != NULL ) {
			return child;
		}
	}

#if 1
	daeInt elCnt = _elementContainer->getCount(parent);
	//check existing groups
      //This doesn't work properly. Because the choice can't check if you make two decisions you cannot fail
	  //here when you are supposed to. Luckily the current schema just has groups with single choices so
	  //every element needs a new group container. Wasteful but thats how the schema is and its how it works.
	for ( daeInt x = 0; x < elCnt; x++ ) {
		daeMemoryRef mem = _elementContainer->get(parent, x );
		if ( mem != NULL ) {
			el = *(daeElementRef*)mem;
		}
		if ( el == NULL ) {
			continue;
		}
		if ( before != NULL ) {
			if ( _elementContainer->_elementType->placeBefore( before, el, child, &ordinal ) ) {
				ordinal = ordinal + _ordinalOffset;
				return el;
			}
		}
		else if ( after != NULL ) {
			if ( _elementContainer->_elementType->placeAfter( after, el, child, &ordinal ) ) {
				ordinal = ordinal + _ordinalOffset;
				return el;
			}
		}
		else {
			if ( _elementContainer->_elementType->place( el, child, &ordinal ) ) {
				ordinal = ordinal + _ordinalOffset;
				return el;
			}
		}
	}
#endif
	//if you couldn't place in existing groups make a new one if you can
	el = _elementContainer->placeElement(parent, _elementContainer->_elementType->create(), ordinal, offset );
	if ( el != NULL ) {
		//el = *(daeElementRef*)_elementContainer->get(parent, elCnt );
		if ( before != NULL ) {
			if ( _elementContainer->_elementType->placeBefore( before, el, child, &ordinal ) ) {
				ordinal = ordinal + _ordinalOffset;
				return el;
			}
		}
		else if ( after != NULL ) {
			if ( _elementContainer->_elementType->placeAfter( after, el, child, &ordinal ) ) {
				ordinal = ordinal + _ordinalOffset;
				return el;
			}
		}
		else {
			if ( _elementContainer->_elementType->place( el, child, &ordinal ) ) {
				ordinal = ordinal + _ordinalOffset;
				return el;
			}
		}
	}
	return NULL;
}

daeBool daeMetaGroup::removeElement( daeElement *parent, daeElement *child ) {
	daeElementRef el;
	daeInt elCnt = _elementContainer->getCount(parent);
	for ( daeInt x = 0; x < elCnt; x++ ) {
		daeMemoryRef mem = _elementContainer->get(parent, x );
		if ( mem != NULL ) {
			el = *(daeElementRef*)mem;
		}
		if ( el == NULL ) {
			continue;
		}
		if ( el->removeChildElement( child ) ) {
			//check if there are any more children in this group. If not remove the group container element too.
			daeElementRefArray array;
			getChildren( parent, array );
			if ( array.getCount() == 0 )
			{
				_elementContainer->removeElement( parent, el );
			}
			return true;
		}
	}
	return false;
}

daeMetaElement * daeMetaGroup::findChild( daeString elementName ) {
	if ( strcmp( _elementContainer->getName(), elementName ) == 0 ) {
		return _elementContainer->getElementType();
	}
	return _elementContainer->_elementType->getCMRoot()->findChild( elementName );
}

void daeMetaGroup::getChildren( daeElement *parent, daeElementRefArray &array ) {
	size_t cnt = _elementContainer->getCount( parent );
	for ( size_t x = 0; x < cnt; x++ ) {
		(*((daeElementRef*)_elementContainer->get(parent, (daeInt)x )))->getChildren( array );
		/*daeElementRef el = (*((daeElementRef*)_elementContainer->get(parent, (daeInt)x )));
		size_t cnt2 = _children.getCount();
		for ( size_t i = 0; i < cnt2; i++ ) {
			_children[i]->getChildren( el, array );
		}*/
	}
	//_elementContainer->_elementType->getChildren( parent, array );
}