1/*
2 * Copyright 2006, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan Aßmus <superstippi@gmx.de>
7 */
8
9#include "ShapeContainer.h"
10
11#include <stdio.h>
12#include <string.h>
13
14#include <OS.h>
15
16#include "Shape.h"
17
18#ifdef ICON_O_MATIC
19// constructor
20ShapeContainerListener::ShapeContainerListener()
21{
22}
23
24// destructor
25ShapeContainerListener::~ShapeContainerListener()
26{
27}
28#endif // ICON_O_MATIC
29
30
31
32// constructor
33ShapeContainer::ShapeContainer()
34	: fShapes(16)
35#ifdef ICON_O_MATIC
36	, fListeners(2)
37#endif
38{
39}
40
41// destructor
42ShapeContainer::~ShapeContainer()
43{
44#ifdef ICON_O_MATIC
45	int32 count = fListeners.CountItems();
46	if (count > 0) {
47		debugger("~ShapeContainer() - there are still"
48				 "listeners attached\n");
49	}
50#endif // ICON_O_MATIC
51	_MakeEmpty();
52}
53
54// #pragma mark -
55
56// AddShape
57bool
58ShapeContainer::AddShape(Shape* shape)
59{
60	return AddShape(shape, CountShapes());
61}
62
63// AddShape
64bool
65ShapeContainer::AddShape(Shape* shape, int32 index)
66{
67	if (!shape)
68		return false;
69
70	// prevent adding the same shape twice
71	if (HasShape(shape))
72		return false;
73
74	if (fShapes.AddItem((void*)shape, index)) {
75#ifdef ICON_O_MATIC
76		_NotifyShapeAdded(shape, index);
77#endif
78		return true;
79	}
80
81	fprintf(stderr, "ShapeContainer::AddShape() - out of memory!\n");
82	return false;
83}
84
85// RemoveShape
86bool
87ShapeContainer::RemoveShape(Shape* shape)
88{
89	if (fShapes.RemoveItem((void*)shape)) {
90#ifdef ICON_O_MATIC
91		_NotifyShapeRemoved(shape);
92#endif
93		return true;
94	}
95
96	return false;
97}
98
99// RemoveShape
100Shape*
101ShapeContainer::RemoveShape(int32 index)
102{
103	Shape* shape = (Shape*)fShapes.RemoveItem(index);
104#ifdef ICON_O_MATIC
105	if (shape) {
106		_NotifyShapeRemoved(shape);
107	}
108#endif
109
110	return shape;
111}
112
113// MakeEmpty
114void
115ShapeContainer::MakeEmpty()
116{
117	_MakeEmpty();
118}
119
120// #pragma mark -
121
122// CountShapes
123int32
124ShapeContainer::CountShapes() const
125{
126	return fShapes.CountItems();
127}
128
129// HasShape
130bool
131ShapeContainer::HasShape(Shape* shape) const
132{
133	return fShapes.HasItem((void*)shape);
134}
135
136// IndexOf
137int32
138ShapeContainer::IndexOf(Shape* shape) const
139{
140	return fShapes.IndexOf((void*)shape);
141}
142
143// ShapeAt
144Shape*
145ShapeContainer::ShapeAt(int32 index) const
146{
147	return (Shape*)fShapes.ItemAt(index);
148}
149
150// ShapeAtFast
151Shape*
152ShapeContainer::ShapeAtFast(int32 index) const
153{
154	return (Shape*)fShapes.ItemAtFast(index);
155}
156
157// #pragma mark -
158
159#ifdef ICON_O_MATIC
160
161// AddListener
162bool
163ShapeContainer::AddListener(ShapeContainerListener* listener)
164{
165	if (listener && !fListeners.HasItem((void*)listener))
166		return fListeners.AddItem((void*)listener);
167	return false;
168}
169
170// RemoveListener
171bool
172ShapeContainer::RemoveListener(ShapeContainerListener* listener)
173{
174	return fListeners.RemoveItem((void*)listener);
175}
176
177#endif // ICON_O_MATIC
178
179// #pragma mark -
180
181// _MakeEmpty
182void
183ShapeContainer::_MakeEmpty()
184{
185	int32 count = CountShapes();
186	for (int32 i = 0; i < count; i++) {
187		Shape* shape = ShapeAtFast(i);
188#ifdef ICON_O_MATIC
189		_NotifyShapeRemoved(shape);
190		shape->ReleaseReference();
191#else
192		delete shape;
193#endif
194	}
195	fShapes.MakeEmpty();
196}
197
198// #pragma mark -
199
200#ifdef ICON_O_MATIC
201
202// _NotifyShapeAdded
203void
204ShapeContainer::_NotifyShapeAdded(Shape* shape, int32 index) const
205{
206	BList listeners(fListeners);
207	int32 count = listeners.CountItems();
208	for (int32 i = 0; i < count; i++) {
209		ShapeContainerListener* listener
210			= (ShapeContainerListener*)listeners.ItemAtFast(i);
211		listener->ShapeAdded(shape, index);
212	}
213}
214
215// _NotifyShapeRemoved
216void
217ShapeContainer::_NotifyShapeRemoved(Shape* shape) const
218{
219	BList listeners(fListeners);
220	int32 count = listeners.CountItems();
221	for (int32 i = 0; i < count; i++) {
222		ShapeContainerListener* listener
223			= (ShapeContainerListener*)listeners.ItemAtFast(i);
224		listener->ShapeRemoved(shape);
225	}
226}
227
228#endif // ICON_O_MATIC
229