/*******************************************************************************
*                         Goggles Music Manager                                *
********************************************************************************
*         Copyright (C) 2008-2010 by Sander Jansen. All Rights Reserved        *
*                               ---                                            *
* This program 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, either version 3 of the License, or            *
* (at your option) any later version.                                          *
*                                                                              *
* This program 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 this program.  If not, see http://www.gnu.org/licenses.           *
********************************************************************************/
#ifndef GMAUDIOSCROBBLER_H
#define GMAUDIOSCROBBLER_H

struct GMHost {
  FXString name;
  FXString path;
  FXuint port;
  GMHost() : port(0) {}
  GMHost(const FXString & n,FXuint p) : name(n), port(p) {}
  };

struct GMAudioScrobblerTrack {
  FXString artist;
  FXString album;
  FXString title;
  FXuint   duration;
  FXint    no;
  FXlong   timestamp;
  GMAudioScrobblerTrack(){}
  GMAudioScrobblerTrack(FXlong time,GMTrack & t) : artist(t.artist),album(t.album),title(t.title),duration(t.time),no(t.no),timestamp(time){}

  void load(FXStream & store);
  void save(FXStream & store) const;
  };

typedef FXArray<GMAudioScrobblerTrack> GMAudioScrobblerTrackList;


class GMAudioScrobbler : public FXThread {
private:
  FXMutex           mutex_task;
  FXMutex           mutex_data;
  FXCondition       condition_task;
  FXuchar           flags;
  GMMessageChannel  feedback;
  FXObject*         target;
  FXSelector        message;
private:
  GMHost            host_handshake;
  GMHost            host_nowplaying;
  GMHost            host_submit;
  FXString          username;
  FXString          password;
  FXString          session;
protected:
  FXlong            timeout;
protected:
  FXint             server;
  FXDict            dnscache;
private:
  enum {
    TASK_NONE       = 0x0,
    TASK_LOGIN 			= 0x1,
    TASK_NOWPLAYING = 0x2,
    TASK_SUBMIT 		= 0x4,
    TASK_SHUTDOWN   = 0x8
    };
private:
  enum {
    FLAG_NONE          = 0,
    FLAG_LOGIN_CHANGED = 0x1,
    FLAG_BANNED        = 0x2,
    FLAG_BADAUTH       = 0x4,
    FLAG_BADTIME			 = 0x8,
    FLAG_SHUTDOWN      = 0x10,
    FLAG_TIMEOUT       = 0x20,
    FLAG_NETWORK       = 0x40,
    FLAG_DISABLED      = 0x80,
    };
protected:
  FXint run();
protected:
  FXbool open_connection(GMHost &);
  void close_connection();
protected:
  FXuchar getNextTask();
  FXbool  waitForTask();
  void    runTask();
protected:
  GMAudioScrobblerTrack     nowplayingtrack;
  GMAudioScrobblerTrackList submitqueue;
  FXint nsubmitted;
  FXint nfailed;
protected:
  void handshake();
  void submit();
  void nowplaying();
  void create_handshake_request(FXString &);
  void process_handshake_response(const FXchar *,FXint);
  void create_nowplaying_request(GMHost &,FXString &);
  void process_nowplaying_response(const FXchar *,FXint);
  void create_submit_request(GMHost &,FXString &);
  void process_submit_response(const FXchar *,FXint);
  void set_handshake_timeout();
  void reset_handshake_timeout();
  void set_submit_failed();
  FXbool can_login();
  FXbool can_submit();
  void load_queue();
  void save_queue();
public:
  GMAudioScrobbler(FXObject* tgt,FXSelector msg);
  FXString getUsername();
  FXbool hasPassword();
  FXbool isBanned();
  FXbool isEnabled();
  void nowplaying(GMTrack & info);
  void submit(FXlong timestamp,GMTrack & info);
  void login(const FXString & user,const FXString & pass);
  void shutdown();
  void nudge();
  void disable();
  void enable();

  virtual ~GMAudioScrobbler();
  };

#endif


