/*
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "Be.h"


_IMPEXP_BE BApplication* be_app;
_IMPEXP_BE BClipboard* be_clipboard;
_IMPEXP_BE const BRoster* be_roster;


// constructor
BApplication::BApplication (const char *signature) :
BLooper (signature),
fAppName (signature),
fServerFrom (0),
fServerTo (0),
fCursorData (0),
fServerHeap (0),
fPulseRate (0),
fInitialWorkspace (0),
fDraggedMessage (0),
fPulseRunner (0),
fInitError (0),
fReadyToRunCalled (false)
{
	be_app = this;

	fReadyToRunCalled = true;
	PostMessage (B_READY_TO_RUN);
}


// destructor
BApplication::~BApplication ()
{
}


// ScriptReceived
bool BApplication::ScriptReceived (BMessage *msg, int32 index, BMessage *specifier, int32 form, const char *property)
{
	return false;
}


// AboutRequested
void BApplication::AboutRequested ()
{
}


void BApplication::RefsReceived (BMessage *a_message)
{
}


void BApplication::AppActivated (bool active)
{
}


void BApplication::ArgvReceived (int32 argc, char **argv)
{
}


void BApplication::ReadyToRun ()
{
	winBe::debugMessage ("BApplication::ReadyToRun");
}


void BApplication::Pulse ()
{
}


void BApplication::Quit ()
{
	winBe::debugMessage ("BApplication::Quit");

	if (!fTerminating) {
		fTerminating = true;

		// Request window threads quit
		std::list<BWindow*> windowList = winBe::getWindowList ();
		for (std::list<BWindow*>::iterator i = windowList.begin (); i != windowList.end (); ++i) {
			BWindow* window = static_cast<BWindow*>(*i);
			if (!window->QuitRequested ()) {
				fTerminating = false;
				break;
			} else
				window->Quit ();
		}

		// Terminate application message loop
		if (fTerminating) {
			//winBe::waitForLoopersToTerminate ();
			winBe::postQuitMessage (Thread ());
		}
	}	
}


bool BApplication::QuitRequested ()
{
	winBe::debugMessage ("BApplication::QuitRequested");

	return true;
}


thread_id BApplication::Run ()
{
	winBe::debugMessage ("BApplication::Run");
	return BLooper::Run ();
}


void BApplication::MessageReceived (BMessage *msg)
{
	Lock ();

	switch (msg->what) {

		case B_ABOUT_REQUESTED:
			AboutRequested ();
			break;

		case B_APP_ACTIVATED:
			AppActivated (msg->FindBool ("active"));
			break;

		case B_ARGV_RECEIVED:
			ArgvReceived (msg->FindInt32 ("argc"), /*msg->FindString ("argv")*/0); // incorrect params
			break;

		case B_PULSE:
			Pulse ();
			break;

		case B_QUIT_REQUESTED:
			if (!fTerminating)
				if (QuitRequested ())
					Quit ();
			break;

		case B_READY_TO_RUN:
			ReadyToRun ();
			break;

		case B_REFS_RECEIVED:
			RefsReceived (msg);
			break;

		default:
			MessageReceived (msg);
			break;

	}

	delete msg;
	Unlock ();
}


status_t BApplication::Perform (perform_code d, void *arg)
{
	return 0;
}


status_t BApplication::GetSupportedSuites (BMessage *data)
{
	return 0;
}


status_t BApplication::Archive (BMessage *data, bool deep) const
{
	return B_ERROR;
}


void BApplication::DispatchMessage (BMessage *an_event, BHandler *handler)
{
	MessageReceived (an_event);
}


BHandler* BApplication::ResolveSpecifier (BMessage *msg, int32 index, BMessage *specifier, int32 form, const char *property)
{
	return 0;
}


void BApplication::_ReservedApplication1 ()
{
}


void BApplication::_ReservedApplication2 ()
{
}


void BApplication::_ReservedApplication3 ()
{
}


void BApplication::_ReservedApplication4 ()
{
}


void BApplication::_ReservedApplication5 ()
{
}


void BApplication::_ReservedApplication6 ()
{
}


void BApplication::_ReservedApplication7 ()
{
}


void BApplication::_ReservedApplication8 ()
{
}


bool BApplication::IsLaunching() const
{
	return !fReadyToRunCalled;
}


void BApplication::SetPulseRate (bigtime_t microseconds)
{
	fPulseRate = microseconds;
	winBe::setTimer (microseconds / 1000);
}


namespace winBe {

void sendPulse ()
{
	be_app->PostMessage (B_PULSE);
}

};