#ifndef n_URL_H
#define n_URL_H

/*
 *
 * nucleo/core/URL.H --
 *
 * Copyright (C) Nicolas Roussel
 *
 * See the file LICENSE for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

/*
  See also :

    http://www.ics.uci.edu/pub/ietf/uri/rfc2396.txt
    http://www.ics.uci.edu/~fielding/
    http://www.ics.uci.edu/~fielding/url/
  */

#include <string>

namespace nucleo {

  // ----------------------------------------------------------------------------

  class URL {

  private:

    bool _isAbsolute ;
    bool _isOpaque ;

    std::string _scheme ;
    std::string _user, _password ;
    std::string _host, _port ;
    std::string _path ;
    std::string _query ;
    std::string _fragment ;

    std::string _opaque ;
  
  public:

    typedef enum {
	 NONE = 0,
	 NORMAL = 1,
	 UNSAFE = 2,
	 RESERVED = 4
    } URLENCODING ;

    static std::string encodeForQuery(const std::string &src, int flags = NORMAL) ;

    static std::string decodeFromQuery(const std::string &src) ;

    static bool getQueryArg(const std::string &q, const std::string &key, std::string *value=0) ;
    static bool getQueryArg(const std::string &q, const std::string &key, int *value) ;
    static bool getQueryArg(const std::string &q, const std::string &key, unsigned int *value) ;
    static bool getQueryArg(const std::string &q, const std::string &key, unsigned long *value) ;

    // --------------------------------------------------------------------------

    URL(void) {}
    URL(const std::string& s) { load(s) ; }

    void load(const std::string &url) ;

    bool isOpaque(void) const { return _isOpaque ; }

    std::string const getScheme(void) const { return _scheme ; }
    std::string const getUser(void) const { return _user ; }
    std::string const getPassword(void) const { return _password ; }
    std::string const getHost(void) const { return _host ; }
    std::string const getPort(void) const { return _port ; }
    std::string const getPath(void) const { return _path ; }
    std::string const getQuery(void) const { return _query ; }
    std::string const getFragment(void) const { return _fragment ; }
    std::string const getOpaque(void) const { return _opaque ; }

    void debug(std::ostream& out) const ;

  } ;

  // ----------------------------------------------------------------------------

}

#endif
