// {{{ iWear GPL header
/**
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 * 
 * This file is part of The iWear Framework.
 * In particular this file is part of the Test Framework 
 *
 * The iWear Framework 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 as in version 2 of the License.

 * 
 * The iWear Framework 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
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
// }}}

//--- Standard Includes -----------------
#include <unistd.h>
#include <list>
#include <map>

//--- iWear Includes --------------------
#include <iwear/basemodulemanager.h>
#include <iwear/utility.h>
#include <iwear/eventdispatcher.h>
#include <iwear/debugstream.h>

#include <iwear_output/outputmanager.h>
#include <iwear_output/imagedata.h>
#include <iwear_output/menudata.h>
#include <iwear_output/submenu.h>
#include <iwear_output/button.h>
#include <iwear_output/menuelement.h>
#include <iwear_output/rgb.h>

#include <iwsenscore/sensormanager.h>
#include <iwsenscore/sensorhandler.h>
#include <iwsenscore/sensorsurveillance.h>
#include <iwsenscore/timesensor.h>
#include <iwsenscore/loadsensor.h>

#include <iwpower/powermanager.h>

#include <iwear-context/contextmanager.h>
#include <iwear-context/testcontextlistener.h>

#include <iwear-context/contextxmlparser.h>

#include <iwear_griffin/griffin.h>
#include <iwear_griffin/griffinenums.h>

#include <iwear_test/testcontextlistener.h>
#include <iwear_test/audioplayer.h>

#include <iwear_output_audio/audiooutputmodule.h>

//--- Namespaces ------------------------
using namespace std;
using namespace iwear;
using namespace iwear::sensor;
using namespace iwear::sensor::power;
using namespace iwear::context;
using namespace iwear::output;
using namespace iwear::griffin;

namespace iwear{
namespace test{

    iwear::context::TestContextListener* tcl_after_dusk;
    iwear::context::TestContextListener* tcl_before_dawn;
    iwear::context::TestContextListener* tcl_day;
    iwear::test::TestContextListener* tcl_delayed_picture;
    SensorContext* sc;
    TimeSensor* ts;
    LoadSensor* ls;
    bool should_exit;

}
}

void context_activation(ContextManager* cm, SensorHandler* sh, OutputManager* om){
    /* Create sensors */
    iwear::test::ts = new TimeSensor(sh);
//     iwear::test::ls = new LoadSensor(sh);
    /* xml context test */
    ContextXMLParser context_xml_parser(cm);
    context_xml_parser.load_contexts_from_file("context.xml");
    string contextname_after_dusk("after dusk");
//     string contextname_before_dawn("before dawn");
//     string contextname_day("day");
    {
//  	iwear::test::tcl_after_dusk = 
//  	    new iwear::context::TestContextListener(cm, contextname_after_dusk);
// 	iwear::test::tcl_before_dawn = 
// 	    new iwear::context::TestContextListener(cm, contextname_before_dawn);
// 	iwear::test::tcl_day = 
// 	    new iwear::context::TestContextListener(cm, contextname_day);
	/* 5 sec delay test */
	string contextname_delayed_picture("delayed picture");
	iwear::test::sc = 
	    new SensorContext(contextname_delayed_picture, 
			      TIME, 
			      iwear::test::ts->get_value()+5, 
			      GREATER, 
			      unit_second, 
			      0.0);
	cm->register_context(iwear::test::sc);
	iwear::test::tcl_delayed_picture = 
	    new iwear::test::TestContextListener(cm, 
						 contextname_delayed_picture, 
						 om);
    }
    d_inf << ANSI_BLUE << "Context activation done" << ANSI_NORMAL << endl;
}

void context_cleanup(){
     delete iwear::test::tcl_after_dusk;
//     delete iwear::test::tcl_before_dawn;
//     delete iwear::test::tcl_day;
    delete iwear::test::tcl_delayed_picture;
    delete iwear::test::sc;
//     delete iwear::test::ts;
    delete iwear::test::ls;
}

/**
 * iWear test
 */
int main(void){
    //std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
    //enable_verbose_crash();
    iwear::test::should_exit = false;
    try{
	d_err.set_debuglevel(nonsens);
	d_inf << ANSI_BLUE << "Testing the iWear Framework" << ANSI_NORMAL << endl;
	
	/* The core base module manager */
	BaseModuleManager bmm;
	d_inf << ANSI_GREEN << "BasemoduleManager created!" << ANSI_NORMAL << endl;

	/*  Create Sensor Management */
	SensorManager sm(&bmm);  // The Sensor Manager, which is master to location and sensorhandler
	SensorHandler sh(&sm);   // The Sensor Handler which has direct sensors under its control
	PowerManager pm(&sm);    // The Power Manager

	EventDispatcher ed;
	ed.Init();
	ed.Start();

	SensorSurveillance ssu(sm,ed);
	ssu.Init();
	ssu.Start();
	
	/* Create Context Manager */
	ContextManager cm(&sm);

	// We create a new Output Manager. Note that for the
	// constructor we create a new Event Dispatcher.
	OutputManager* om = new OutputManager(&bmm, &ed);
	d_inf << ANSI_GREEN << "Outputmanager created!" << ANSI_NORMAL << endl;
	
	AudioOutputModule* audio_module = new AudioOutputModule(om, uid());

	// Create a Griffin instance and register
	// Griffin with the output manager
	Griffin::register_Griffin(om);

	Griffin::get_instance()
	  ->set_exit_point(new ExitFunctor(&iwear::test::should_exit));

	/* Initialising Framework is done. */
	/* =============================== */

	/* Running context test */
	context_activation(&cm, &sh, om);

	// Create audio player applications	
	iwear::test::AudioPlayer* audio_player = 
	    new iwear::test::AudioPlayer(*om,
					 "Audio Player",
					 "iWear Demonstrator Audio Player",
					 "sounds/wasfuereinenacht.wav",
					 "images/mplayer.png");
	/* Display audio_player and its  */
	audio_player->display_data();

	// Create audio player applications	
	iwear::test::AudioPlayer* audio_player2 = 
	    new iwear::test::AudioPlayer(*om,
					 "Audio Player 2",
					 "iWear Demonstrator Audio Player",
					 "sounds/jesus.wav",
					 "images/mplayer.png");
	/* Display audio_player and its  */
	audio_player2->display_data();

	/* Wait for exit to be selected */
	while (!iwear::test::should_exit){
	    usleep(1000000); // 1 sec
	}

    }catch(const exception& e){
	d_err << ANSI_RED << "Encountered Exception" << endl;
	d_err << e.what() << ANSI_NORMAL << endl;
    }
    context_cleanup();
    exit(0);
}
