#ifndef _APP_UPDATER_H_
#define _APP_UPDATER_H_


#include "file_downloader.h"
#include <vector>
#include <list>
#include "util.h"


class App_updater;
#ifdef _WIN32
#pragma make_public(App_updater)
#endif

class App_updater
{
public:
  class Release_info
  {
  public:
    class Mirror_info
    {
    public:
      std::string description;
      std::string url;

      std::string full_name() const;
      static std::string get_full_name(const Mirror_info &this_) { return this_.full_name(); }
    };

    typedef std::vector<Mirror_info> Mirrors_info;
    Mirrors_info mirrors;

    Release_info() : _updater(NULL) {}
    Release_info(App_updater *updater) : _updater(updater) {}

    std::string name;
    std::string description;
    std::string version;
    std::string date;
    std::string next_release_date;
    std::string release_notes;
    std::string type;
    int authorization;

    bool available() { return !mirrors.empty(); }
    bool is_new();
    std::string full_name() const;
    static std::string get_full_name(const Release_info &this_) { return this_.full_name(); }

  private:
    App_updater *_updater;
  };

  App_updater();
  virtual ~App_updater();

  PROPERTY(File_dir, working_dir)
  PROPERTY(std::string, url)
  PROPERTY(std::string, active_version)
  PROPERTY(std::string, result_filepath)
  PROPERTY_RE(std::string, user_agent, _fd.user_agent)
  PROPERTY_RE(std::string, proxy_type, _fd.proxy_type)
  PROPERTY_RE(std::string, proxy_server, _fd.proxy_server)
  PROPERTY_RE(std::string, proxy_userpwd, _fd.proxy_userpwd)
  PROPERTY_RE(std::string, server_userpwd, _fd.server_userpwd)
  PROPERTY_RE(File_downloader::Progress_cb, progress_cb, _fd.progress_cb)
  void get_rel_names(std::list<std::string> &rel_names);
  void get_mirrors(int rel_index, std::list<std::string> &mirrors);
  bool fetch_release_info();
  int rel_authorization(int rel_index);
  bool download(int rel_index, int mirror_index);
  void cancel_download();
  bool cancelled() { return _fd.cancelled(); }
  bool install();

protected:
  bool do_download(int rel_index, int mirror_index);

  File_downloader _fd;
  File_dir _working_dir;
  std::string _url; // versions.xml
  std::string _active_version;
  std::string _result_filepath;

  typedef std::vector<Release_info> Releases_info;
  Releases_info _releases_info;
};


#endif // _APP_UPDATER_H_
