/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * 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 __AUDIODATA_H
#define __AUDIODATA_H

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

namespace iwear{
namespace output{

    /**
     * Things that can happen in an AudioData
     */
    enum AudioDataChange{
	AUDIO_VOLUME_CHANGE,
	AUDIO_STATUS_CHANGE,
	AUDIO_FILE_CHANGE,
	AUDIO_FINISHED,
	num_AudioDataChange
    };

    inline const char* to_string (AudioDataChange enumtype){
	switch(enumtype){
	    case AUDIO_VOLUME_CHANGE:
		return "iwear::output::AudioDataChange::AUDIO_VOLUME_CHANGE";
		break;
	    case AUDIO_STATUS_CHANGE:
		return "iwear::output::AudioDataChange::AUDIO_STATUS_CHANGE";
		break;
	    case AUDIO_FILE_CHANGE:
		return "iwear::output::AudioDataChange::AUDIO_FILE_CHANGE";
		break;
	    case AUDIO_FINISHED:
		return "iwear::output::AudioDataChange::AUDIO_FINISHED";
		break;
	    case num_AudioDataChange:
		return "iwear::output::AudioDataChange::num_AudioDataChange";
		break;
	    default:
		return "iwear::output::AudioDataChange::<invalid value>";
	}
    }
    
    inline std::ostream& operator<<(std::ostream& os, AudioDataChange enumtype){
	os << to_string(enumtype);
	os << "(";
	os << (uint32_t)enumtype << ")";
	return os;
    }

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

    enum AudioDataType{
        MP3,
        OGG,
        num_AudioDataType
    };

    inline const char* to_string (AudioDataType enumtype){
        switch(enumtype){
            case MP3:
                return "iwear::output::AudioDataType::MP3";
                break;
            case OGG:
                return "iwear::output::AudioDataType::OGG";
                break;
            case num_AudioDataType:
                return "iwear::output::AudioDataType::num_AudioDataType";
                break;
            default:
                return "iwear::output::AudioDataType::<invalid value>";
        }
    }

    inline std::ostream& operator<<(std::ostream& os, AudioDataType enumtype){
        os << to_string(enumtype);
        os << "(";
        os << (uint32_t)enumtype << ")";
        return os;
    }

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

    enum AudioDataStatus{
	AUDIO_PLAYING,
	AUDIO_PAUSED,
	num_AudioDataStatus
    };

    inline const char* to_string (AudioDataStatus enumtype){
	switch(enumtype){
	    case AUDIO_PLAYING:
		return "iwear::output::AudioDataStatus::AUDIO_PLAYING";
		break;
	    case AUDIO_PAUSED:
		return "iwear::output::AudioDataStatus::AUDIO_PAUSED";
		break;
	    case num_AudioDataStatus:
		return "iwear::output::AudioDataStatus::num_AudioEvent_Type";
		break; 
	    default:
		return "iwear::output::AudioDataStatus::<invalid value>";
	}
    }

    inline std::ostream& operator<<(std::ostream& os, AudioDataStatus enumtype){
	os << to_string(enumtype);
	os << "(";
	os << (uint32_t)enumtype << ")";
	return os;
    }

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

class iwear::uid;

class AudioData : public OutputData{
    
 public:

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

    /**
     * The minimum possible volume.
     */
    static const int MIN_VOLUME;

    /**
     * The maximum possible volume.
     */
    static const int MAX_VOLUME;

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

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

    /**
     * Get the type of the AudioData - sth like MP3, OGG etc.
     * The type can only be set togehter with the file name.
     *
     * @return The type of the AudioData - sth like MP3, OGG etc.
     */
    inline AudioDataType get_audio_data_type(void){
        return this->audio_data_type;
    }

    /**
     * @return The absolute path to the audio file.
     */
    inline const string& get_audio_file_name(void){
        return this->audio_file_name;
    }

    /**
     * Set the content of this object - this will cause a
     * changed-event to be fired.
     * @param audio_file_name The new path to be set.
     * @param audio_data_type The type of the file.
     */
    void set_audio_file_name(const string& audio_file_name,
			     const AudioDataType& audio_data_type);

    bool pause(void);

    bool resume(void);

    inline bool get_only_in_focus(void) const{
	return only_in_focus;
    }

    inline bool get_is_music_sample(void) const{
	return is_music_sample;
    }

    void set_volume(int volume);

    inline uint32_t get_volume(void) const{
	return volume;
    }

    inline AudioDataStatus get_audio_data_status(void) const{
	return audio_data_status;
    }

    void audio_finished(void);

 protected:

    bool only_in_focus;

    bool is_music_sample;

    string audio_file_name;

    AudioDataType audio_data_type;

    AudioDataStatus audio_data_status;

    uint32_t volume;

};

    } // namespace output
} // namespace iwear

#endif

