/**
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * Author: cob
 *
 * This file is part of The iWear Framework.
 * In particular this file is part of the Framework Output
 *
 * 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 __SIGNALDATA_H
#define __SIGNALDATA_H

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

namespace iwear{
namespace output{

    /**
     * Things that can happen to a SignalData.
     */
    enum SignalDataChange{
	SIGNAL_STATUS_CHANGE,
	SIGNAL_ERROR_OCCURED,
	num_SignalDataChange
    };

    inline const char* to_string (SignalDataChange enumtype){
	switch(enumtype){
	    case SIGNAL_STATUS_CHANGE:
		return "iwear::output::SignalDataChange::SIGNAL_STATUS_CHANGE";
		break;
	    case SIGNAL_ERROR_OCCURED:
		return "iwear::output::SignalDataChange::SIGNAL_ERROR_OCCURED";
		break;
	    case num_SignalDataChange:
		return "iwear::output::SignalDataChange::num_SignalDataChange";
		break;
	    default:
		return "iwear::output::SignalDataChange::<invalid value>";
	}
    }
    
    inline std::ostream& operator<<(std::ostream& os, SignalDataChange enumtype){
	os << to_string(enumtype);
	os << "(";
	os << (uint32_t)enumtype << ")";
	return os;
    }

////////////////////////////////////////////////////////////////////////////////

    /**
     * Types of signals contained in a SignalData.
     */
    enum SignalState{
	SIGNAL_STATE_OFF,
	SIGNAL_STATE_STANDBY,
	SIGNAL_STATE_ON,
	SIGNAL_STATE_ON_BUSY,
	num_SignalState
    };

    inline const char* to_string (SignalState enumtype){
	switch(enumtype){
	    case SIGNAL_STATE_OFF:
		return "iwear::output::SignalState::SIGNAL_STATE_OFF";
		break;
	    case SIGNAL_STATE_STANDBY:
		return "iwear::output::SignalState::SIGNAL_STATE_STANDBY";
		break;
	    case SIGNAL_STATE_ON:
		return "iwear::output::SignalState::SIGNAL_STATE_ON";
		break;
	    case SIGNAL_STATE_ON_BUSY:
		return "iwear::output::SignalState::SIGNAL_STATE_ON_BUSY";
		break;
	    case num_SignalState:
		return "iwear::output::SignalState::num_SignalState";
		break;
	    default:
		return "iwear::output::SignalState::<invalid value>";
	}
    }
    
    inline std::ostream& operator<<(std::ostream& os, SignalState enumtype){
	os << to_string(enumtype);
	os << "(";
	os << (uint32_t)enumtype << ")";
	return os;
    }

////////////////////////////////////////////////////////////////////////////////

    /**
     * Types of signal errors contained in a SignalData.
     */
    enum SignalErrorState{
	SIGNAL_STATE_WARNING,
	SIGNAL_STATE_ERROR,
	SIGNAL_STATE_PANIC,
	num_SignalErrorState
    };

    inline const char* to_string (SignalErrorState enumtype){
	switch(enumtype){
	    case SIGNAL_STATE_WARNING:
		return "iwear::output::SignalErrorState::SIGNAL_STATE_WARNING";
		break;
	    case SIGNAL_STATE_ERROR:
		return "iwear::output::SignalErrorState::SIGNAL_STATE_ERROR";
		break;
	    case SIGNAL_STATE_PANIC:
		return "iwear::output::SignalErrorState::SIGNAL_STATE_PANIC";
		break;
	    case num_SignalErrorState:
		return "iwear::output::SignalErrorState::num_SignalErrorState";
		break;
	    default:
		return "iwear::output::SignalErrorState::<invalid value>";
	}
    }
    
    inline std::ostream& operator<<(std::ostream& os, SignalErrorState enumtype){
	os << to_string(enumtype);
	os << "(";
	os << (uint32_t)enumtype << ")";
	return os;
    }

////////////////////////////////////////////////////////////////////////////////

    /**
     * How the signal should be displayed - constantly, flashing or fast_flashing.
     */
    enum SignalStateInterval{
	SIGNAL_CONSTANT,
	SIGNAL_FLASHING,
	SIGNAL_FLASHING_FAST,
	num_SignalStateInterval
    };

    inline const char* to_string (SignalStateInterval enumtype){
	switch(enumtype){
	    case SIGNAL_CONSTANT:
		return "iwear::output::SignalStateInterval::SIGNAL_CONSTANT";
		break;
	    case SIGNAL_FLASHING:
		return "iwear::output::SignalStateInterval::SIGNAL_STATUS_FLASHING";
		break;
	    case SIGNAL_FLASHING_FAST:
		return "iwear::output::SignalStateInterval::SIGNAL_STATUS_FLASHING_FAST";
		break;
	    case num_SignalStateInterval:
		return "iwear::output::SignalStateInterval::num_SignalStateInterval";
		break;
	    default:
		return "iwear::output::SignalStateInterval::<invalid value>";
	}
    }
    
    inline std::ostream& operator<<(std::ostream& os, SignalStateInterval enumtype){
	os << to_string(enumtype);
	os << "(";
	os << (uint32_t)enumtype << ")";
	return os;
    }

////////////////////////////////////////////////////////////////////////////////

class iwear::uid;

class SignalData : public OutputData{
    
 public:

    /**
     * Constains the OutputData type of this object.
     */
    static const string TYPE;

    /**
     * Constructor
     * @param name The name of the output data
     * @param description A description of the output data
     * @todo Hand over the actual content
     */
    SignalData(const uid& application_id,
	       const string& name,
	       const string& description,
	       bool only_in_focus = true);

    /**
     * Destructor
     */
    virtual ~SignalData(void);

    /**
     * If the signals of this signaldata should be displayed only when the
     * application is in focus.
     *
     * @return true if the application of this data is in focus.
     */
    inline bool get_only_in_focus(void) const{
	return only_in_focus;
    }

    /**
     * Set the signal state of this SignalData.
     *
     * @param signal_state the signal state to be set.
     *
     * @param interval in which interval the signal should be
     * displayed. Default is SIGNAL_CONSTANT.
     */
    void set_signal_state(SignalState signal_state, 
			  SignalStateInterval interval = SIGNAL_CONSTANT);

    /**
     * Get the signal state.
     *
     * @return the actual signal state.
     */
    inline SignalState get_signal_state(void){
	return signal_state;
    }

    /**
     * Set the signal state of this SignalData.
     *
     * @param signal_state the signal state to be set.
     */
    void set_signal_error_state(SignalErrorState error_state);

    /**
     * Get the signal error state.
     *
     * @return the actual signal error state.
     */
    inline SignalErrorState get_signal_error_state(void){
	return error_state;
    }

    /**
     * Get the signal state interval.
     *
     * @return the actual signal state interval.
     */
    inline SignalStateInterval get_signal_state_interval(void){
	return interval;
    }

 protected:

    bool only_in_focus;

    SignalState signal_state;

    SignalErrorState error_state;

    SignalStateInterval interval;
};

} // namespace output
} // namespace iwear

#endif

