/* 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_URLNODE_HPP
#define NMM_URLNODE_HPP NMM_URLNODE_HPP

#include "nmm/multimedia/GenericSourceNode.hpp"

#include "nmm/plugins/net/url/IURLImpl.hpp"
#include "nmm/plugins/interfaces/IBufferSizeImpl.hpp"

namespace NMM {
  class ProtocolReader;

  /**
   * \brief This node reads multimedia data from a URL.

     After construction, the URLNode has to get an event for the URL,
     it has to read. After that, it could be initialized: It parses
     the URL for the used protocol and instantiates the corresponding
     ProtocolReader if one was found. After seting the URL of this
     Reader, it is ready to produce Buffers by simply calling the
     readData() method of its ProtocolReader. Certainly it has to
     generate first the corresponding events and check if the
     ProtocolReader read the end of the stream.
   */

  class URLNode
    : public GenericSourceNode,
      public IURLImpl,
      public IBufferSizeImpl {

  public:
    /**
     * The default constructor.
     * \param name: the name of the node (default is "URLNode").
     */
    URLNode(const char* name = "URLNode",
	    StreamQueue::Mode = StreamQueue::MODE_SUSPEND,
	    int = StreamQueue::DEFAULT_SIZE);

    /**
     * The default destructor.
     */
    ~URLNode();


  protected:
    // IURL interface
    void setURL(const string&);
    string getURL() const;

    // IBufferSize interface
    void setBufferSize(const nmm_int32&);
    nmm_int32 getBufferSize();

    Result doInit();

    /**
     * this method initialies the URLNode.
       It opens a socket to the host, encoded in the target url and
       tries to read some data. If it succeeds, it tries to analyse it
       to get the format of the media.
     */
    Result doInitOutput();
    Result doDeinitOutput();

    /**
     * this method produces the NMM data stream of the URLNode.
       It read a specified length of data from the socket, packs it in
       a buffer and sends it to the NMM environment.
       It also generates the appropriate events for the start and
       end of the data stream and after sending the end_track event,
       it generates a last finished event and stops ITSELF!
     */
    Message* processBuffer(Buffer*); // even source nodes are now called with a buffer pointer (which is obviously always NULL) to better match the generic node interface


  private:
    //! enum for saving the internal node state for emmiting events.
    enum EventState {START, DATA, END, FINISHED};
    //! enum of the different supported protocols
    enum URLProtocol { 
      //! if no protocol can be identified
      UNKNOWN,
      //! HyperText Transfer Protocol
      HTTP,    
      //! File Transfer Protocol
      FTP,     
      //! Server Message Block protocol, used for Windows(TM) file servers
      SMB,     
      //! File In SHell, ssh-encrypted remote file access, like kio_fish (http://ich.bin.kein.hoschi.de/fish/)
      FISH     
    };
    //! member to save the internal node state for emmiting events.
    EventState event;
    //! member to guaranty thread-save IO to the event menber.
    ThreadMutex event_mutex;

    //! member to save the target url
    string url;
    //! reading object
    ProtocolReader* reader;

    //! the size of the outgoing buffers
    int buffer_size;

    //! helper method to find the protocol of the URL
    URLProtocol getProtocol(const string);

  };

} /* namespace NMM */

#endif //NMM_URLNODE_HPP
