#include <iostream>
#include <ubit/ubit.hpp>
using namespace std;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// should be in header file

class Demo : public UFrame {            // UFrame = main window
public:
	Demo();

private:
	UButton* button;		                     // NB: 'button' is a POINTER

	static  void foo1(const char*);                 // non-member and member
	virtual void foo2(UEvent&, const char*, int);   // callback functions
};

// end of header - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

int main(int argc, char* argv[]) {
	UAppli* appli = new UAppli(&argc, argv); // creates the Application Context

	Demo* frame = new Demo();          // creates the Main Frame
	appli->add(frame);                 // adds the Main Frame to the Appli
	frame->show(true);                 // packs and shows the main window
	
	return appli->mainLoop();          // starts the event loop
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

Demo::Demo() {
	// creates a label and adds it to the main frame
	ULabel* label = new ULabel("Simple demo");
	this->add(label);
	
	// creates a push button and adds it to the main frame
	button = new UButton("Please Click Me !");
	this->add(button);

	// adds a NON-member callback function to the button
	// - condition 'UOn::mpress' means: when one of the mouse buttons is pressed
	// - the first argument(s) of ucall() are passed to the callback function:
	//   NON-member functions can have 1 or 2 args (and 1 optional UEvent& arg, see below)

	button->add( UOn::mpress / ucall("test1", &Demo::foo1) );
	
	// adds a MEMBER callback function to the button
	// - 'UOn::action' condition means: when the object is activated (eg. clicked...)
	// - the 1st arg. of ucall() is the object of the callback function
	// - the following argument(s) are passed to the callback function:
	//   MEMBER functions can have 0, 1 or 2 args (and 1 optional UEvent& arg, see below)
	
	button->add( UOn::action / ucall(this, "test2", 666, &Demo::foo2) );

	// NB: as UOn::action is the default it can be omitted:
	button->add( ucall(this, "test3", 777, &Demo::foo2) );
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// non-member callback function (can have 1 or 2 arguments and and optional
// UEvent& arg)

void Demo::foo1(const char* s) {
	cout << "pressed: " << s << endl;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// member callback function (can have 1 or 2 arguments and and optional
// UEvent& arg [which must be the first arg])

void Demo::foo2(UEvent& e, const char* s, int i) {
	cout << "action: " << s << " " << i << endl;
}

