/* 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_GRAPHURL_HPP
#define NMM_GRAPHURL_HPP NMM_GRAPHURL_HPP

#include "nmm/nmm_prefix.hpp"

#include <map>
#include <string>
#include <set>
#include <list>

#include "visibility.hpp"

using namespace std;

namespace NMM {
  class Format;
  class NodeDescription;
  class INode;
  class GraphURLObject;

  /**
   * Represents and parses a URL.
   */ 
  class DLLEXPORT GraphURL {
  public:
    //! enum of the different supported protocols
    enum URLProtocol { 
      //! if no protocol can be identified
      UNKNOWN = 0,
      //! Digitial Versatile Disc as special source
      DVD,
      //! AudioCD as special source
      AUDIOCD,
      //! Digital Video Broadcast Television as special source
      DVBTV,
      //! TVCard as special source
      TV,
      //! IVTV TVCard as special source
      IVTV,
      //! MPEG TVCard as special source
      MPEGTV,
      //! File source as protocol
      FILE,
      //! 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,    
      //! VNC, a remote Desktop access protocol
      VNC
    };
  private:

    typedef map<string, string> URLOptions;
    typedef URLOptions::const_iterator URLOptionsIt;

    typedef map<string, GraphURLObject*> GraphURLObjects;
    typedef GraphURLObjects::const_iterator GraphURLObjectsIt;

    string url;

    bool is_valid;

    URLProtocol protocol;
    string protocol_name;
    string user;
    string password;
    string host;
    unsigned int port;
    string uri;
    string uri_path;
    string uri_options;
    string uri_extension;

    URLOptions options;

    GraphURLObjects url_objects;

    void registerGraphURLObject(GraphURLObject* object);
    void registerGraphURLObjects();
    GraphURLObject* getGraphURLObject() const;

    bool parse();

    void addInterfacesFromProtocol(NodeDescription& n) const;

  public:

    GraphURL();

    GraphURL(const string);

    ~GraphURL();

    list<string> getRegisteredGraphURLs();

    Format* getFormat() const;

    NodeDescription getNodeDescription() const;

    void configureNodeDescription(NodeDescription &node);

    /**
     * Checks whether the URL is well formed.
     * E.g. a URL is invalid if it cannot be parsed.
     *
     * \return false if the URL is malformed.
     */
    inline const bool isValid() const { return is_valid; }

    inline const string getURL() const { return url; }

    /**
     * Returns the protocol of the URL.
     *
     * \return protocol of the URL
     */
    inline const URLProtocol getProtocol() const { return protocol; }

    /**
     * Returns the protocol name of the URL.
     * 
     * \return protocol name of the URL
     */
    inline const string getProtocolName() const { return protocol_name; }

    /**
     * Returns the decoded user name.
     *
     * \return the user name or "" if no user is specified
     */
    inline const string getUser() const { return user; }

    /**
     * Returns the decoded password.
     *
     * \return the password for a user or "" if no password is specified
     */
    inline const string getPassword() const { return password; }

    /**
     * Returns the decoded hostname.
     *
     * \return the name of the host or "" if no host is specified
     */
    inline const string getHost() const { return host; }

    /**
     * Returns the port of the URL.
     * \return the port number, ClientRegistry::default_port if no port number was specified
     */
    inline const unsigned int getPort() const { return port; }

    inline const string getURI() const { return uri; }

    inline const string getURIPath() const { return uri_path; }

    inline const string getURIOptions() const { return uri_options; }

    inline const string getURIExtension() const { return uri_extension; }

    const string getOption(const string) const;

    const set<string> getOptionList() const;
    
    void setOption(const string& key, const string& value);
    
    void clearOptions();
    
  };

  DLLEXPORT ostream& operator<<(ostream&, const NMM::GraphURL&);
}

#include "nmm/nmm_suffix.hpp"

#endif
