
/**
 * outputmodule.h - is part of the iwear-framework
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 * In particular this file is part of the Framework Core Library
 *
 * 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
 */

#ifndef __OUTPUTMODULE_H
#define __OUTPUTMODULE_H

#include <stdint.h>
#include <vector>

#ifndef __MODULE_H
#include <iwear/module.h>
#endif

#ifndef __UID_H
#include <iwear/uid.h>
#endif

#include <iwear_output/outputenums.h>

#ifndef __OUTPUTDATA_H
#include <iwear_output/outputdata.h>
#endif

#ifndef __DEBUGSTREAM_H
#include <iwear/debugstream.h>
#endif

#ifndef __CONFIGURATION_H
#include <iwear/configuration.h>
#endif

using std::vector;
using std::map;
using std::pair;

namespace iwear { 
namespace output {


/**
 * Enum with return values for the display()-method
 * @todo Maybe further return values need to be integrated
 */
enum display_state
{
    display_succeeded,
    display_failed,
    num_display_state
};

/**
 * to_string method for the display states
 */
inline const char* to_string(display_state ds)
{
    switch(ds)
	{
	case display_succeeded :
	    return "display_state::display_succeeded";
	case display_failed :
	    return "display_state::display_failed";
	default :
	    return "display_state::<invalid_value>";
	}
}


// Needed for managing OutputData
class OutputManager;

/**
 * Base class for all modules
 */
class OutputModule : public Module {
	
    /**
     * So OutputManager can set the output_manager-member when an
     * OutputModule is registered externally
     */
    friend class OutputManager;
    
public:

    /** 
     * Creates a new OutputModule. 
     * @param output_manager a pointer to the output_manager to which the 
     *  OutputModule should be registered to.
     */
    OutputModule(OutputManager* output_manager, 
		 const string& name, 
		 Configuration& c);
	

    virtual ~OutputModule(void);
	

    /** Get all types that can be displayed by this outputmodule.
     * @return vector<output_module_type> with the types that can be 
     * displayed.
     */
    inline const vector<string>& get_displayable_types(void) const
    {
	return this->displayable_types;
    }

    /** Look if the given type is one we can diyplay.
     * @param type the type be checked.
     * @return if this OutputModule can display the given type.
     */
    bool can_display(const string& type) const;
        
    /** 
     * Display the DataObject.
     * @param data The OutputData to display.
     * @return uint32_t display status.
     */
    virtual display_state display(OutputData* data) = 0;
    
    /**
     * Stop displaying the data object. Just stop it - don't tell the
     * OutputManager that you're finished or something...
     *
     * @param data the OutputData that should not be displayed anymore.
     */
    virtual bool stop_display(OutputData* data)=0;

    /**
     * This function is called by the ApplicationFocusFunctor
     * Each module can define its own process of handling a switch
     * from one active application to another
     */
    void notify_application_focus_changed(const uid& app_id);

    /** Get the basic type of this module - can be output, sensor or input. 
     * Overrides the inherited pure virtual function from Module.
     * @return the basic type of all output modules: output.
     */
    inline virtual module_type get_module_type(void) const{
	return iwear::output_module;
    }

    /**
     * Get the name of this OutputModule.
     */
    inline const string& get_name(void) const{
	return this->my_name;
    }

protected:


    Configuration& conf;

    /**
     * Method which is called when the focus changes to another
     * application. Has to be implemented by the actual OutputModule.
     */
    virtual void apply_application_focus_change(const uid& app_id) = 0;
	
    /** Types that can be displayed. */
    vector<string> displayable_types;
    
    /** The global OutputManager. */
    OutputManager* output_manager;

    /**
     * Map of applications which have sent outputdatas to the output module.
     * First item is the uid of the application, second is the type of the
     * outputdata last is a pointer to the actual outputdata.
     *
     * @todo maybe every submodule should decide itself how to manage its apps
     * and outputdatas since in this class here there is only the map but no
     * functionality using it. DON'T COPY THE UID INTO THE MAP! (use pointer
     * and deref_less...)
     */
    map<uid, map<const string, vector<OutputData*> > > managed_applications;

    /**
     * The uid of the active application
     */
    uid* active_application_id;

};

} // namespace output
} //namespace iwear

#endif	// __OUTPUTMODULE_H
