/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM 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; only version 2 of the License.      
 * 
 * NMM 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 NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */


#ifndef NMM_GENERICWRITENODE_HPP
#define NMM_GENERICWRITENODE_HPP

#include "nmm/multimedia/GenericSinkNode.hpp"
#include "nmm/plugins/file/interfaces/ISinkFileHandlerImpl.hpp"
#include "nmm/multimedia/interfaces/ITrackImpl.hpp"

#include "nmm/utils/thread/Thread.hpp"

#include <fstream>
#include <string>

namespace NMM {

  class GenericWriteNode :
    public GenericSinkNode,
    public ISinkFileHandlerImpl,
    public ITrackImpl
  {
  public: 
    GenericWriteNode(const char *name = "GenericWriteNode", 
                     const StreamQueue::Mode queue_mode = StreamQueue::MODE_SUSPEND, 
                     const int queue_size = 1);
    ~GenericWriteNode();

    // GenericNode methods
    virtual Result doInit();
    virtual Result doInitOutput();
    virtual Result doActivate();
    virtual Result doDeactivate();
    virtual Message* processBuffer(Buffer *in_buffer);

    // ISinkFileHandler interface
    virtual void setWorkingDirectory(const string& directory);
    virtual string getWorkingDirectory();
    virtual void setFileExtension(const string& extension);
    virtual string getFileExtension();

    // IFileHandler interface
    virtual void setFilename(const string& filename);

    // ITrack interface
    virtual Result startTrack(const string& filename);
    virtual Result endTrack();
    virtual Result finished();

  private:
    /** This method tries to open the file if a filename has been set.
     */
    Result openFile();

    /** This method tries to close the file
     */
    Result closeFile();

    void makeDefaultFilename(const string& filename);

  private:
    enum SubState {
      CLOSED   = 1, ///< File is not opened. This is the initial state.
      STARTED  = 2, ///< File is not opened and a startTrack event has already been received.
      OPENED   = 4, ///< File is opened and data can be written to it.
    };

    string   __file_extension;               ///< Default output file extension
    string   __working_directory;            ///< Default output file directory
    bool     __override_default_filename;    ///< Override default filename
    SubState __sub_state;                    ///< Current sub state of node
    string   __filename;                     ///< Filename
    ofstream __out_fstream;                  ///< Stream to write to

    long int __bytes_written;                ///< Bytes written to stream
    int      __buffnum;                      ///< Buffers written to stream

    ThreadMutex __substate_mutex;            ///< Sub state mutex
  };

}

#endif
