/*
    PIP - Platform Independent Primitives
    Object, base class of some PIP classes, provide EVENT -> EVENT_HANDLER mechanism
    Copyright (C) 2014  Ivan Pelipenko peri4ko@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "piobject.h"

PIVector<PIObject * > PIObject::objects;


/** \class PIObject
 * \brief This is base class for any classes which use events -> handlers mechanism.
 * \details
 * \section PIObject_sec0 Events and Event handlers
 * %PIObject provide notification mechanism similar Qt but implemented
 * on language capabilities without any special preprocessors or compilers.
 * Any class inherits PIObject should use macro \a PIOBJECT() immediate
 * after declaration to proper compile.
 * 
 * Event is a some abstract event that can be raised at any time.
 * Event is a function but declared with special macro \a EVENT().
 * To raise event simply execute event function.
 * 
 * Event handler is a function but declared with special macro
 * \a EVENT_HANDLER(). You can use event handlers as ordinary functions.
 * 
 * Main goal of this mechanism is perform abstract connections between
 * various objects. This functionality provide macro \a CONNECT() which
 * connect some event of first object to some event handler or event of
 * second object. Each event can be connected any times to any event handlers.
 * 
 * \image html events_handlers.png
 * 
 * Example: \snippet piobject.cpp main
 * Result:
\code{.cpp}
handler B: 2 , 0.5
handler A: event to handler
handler A: event to event
\endcode
 */


PIObject::PIObject(const PIString & name): emitter_(0), thread_safe_(false) {
	piMonitor.objects++;
	setName(name);
	setDebug(true);
	objects << this;
}


void PIObject::piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h) {
	PIObject * o = findByName(src);
	if (o == 0) {
		piCout << "[PIObject] Can`t find object with name \"" << src << "\"!";
		return;
	}
	o->connections << Connection(ev_h, 0, sig, dest);
}


void PIObject::piConnect(PIObject * src, const PIString & sig, const PIString & dest, void * ev_h) {
	PIObject * o = findByName(dest);
	if (o == 0) {
		piCout << "[PIObject] Can`t find object with name \"" << dest << "\"!";
		return;
	}
	src->connections << Connection(ev_h, 0, sig, o);
}


void PIObject::piConnect(const PIString & src, const PIString & sig, const PIString & dest, void * ev_h) {
	PIObject * s = findByName(src);
	if (s == 0) {
		piCout << "[PIObject] Can`t find object with name \"" << src << "\"!";
		return;
	}
	PIObject * d = findByName(dest);
	if (d == 0) {
		piCout << "[PIObject] Can`t find object with name \"" << dest << "\"!";
		return;
	}
	s->connections << Connection(ev_h, 0, sig, d);
}

/*
PIStringList PIObject::events() {
	PIStringList l;
	for (PIMap<NamedFunction, PIString>::const_iterator i = signals_.begin(); i != signals_.end(); i++)
		l << (*i).first;
	return l;
}


PIStringList PIObject::eventHandlers() {
	PIStringList l;
	for (PIMap<NamedFunction, PIString>::const_iterator i = slots_.begin(); i != slots_.end(); i++)
		l << (*i).first;
	return l;
}
*/
