#ifndef EPG_H
#define EPG_H

#include "tinyxml.h"

#include "module.hpp"
#include "options.hpp"

#include <cc++/thread.h>

class Programme
{
private:
  time_t str_to_time(const char *s);
public:
  Programme(TiXmlElement *element);
  time_t start;
  time_t stop;
  std::string title;
  std::string desc;

  // for sorting
  bool operator<(const Programme& rhs) const;
};

class Channel
{
public:
  Channel(TiXmlElement *element);
  std::string id;
  std::string display_name;
  std::string logo;
  std::vector<Programme> programme;
};

class EpgUpdate : public ost::Thread
{
private:
  virtual void run();
};

class Epg : public Module 
{
 private:

  // commands
  void print_description();
  void options();
  void exit();

  bool exit_loop;

  bool valid_program();
  void find_next_program();
  void find_valid_program();
  
  bool epg(std::list<Channel> *channel);

  Epg();
  ~Epg();
  
  void print_description(Programme p);

  class EpgOpts : public Options 
  {
  public:
    EpgOpts();
    ~EpgOpts();

    std::vector<Option*> values() 
    {
      return val;
    }

  private:
    void read_dirs() { Epg *epg = Epg::get_instance(); epg->read_db(); };
    Option *reload_p;
  };

  bool move_element_down();
  bool move_element_up();

  std::list<Channel> channels;

  // the position of the currently selected channel on the screen.
  // starts at 0 and goes up the number of channels on the screen minus 1.
  int sel_channel_num; 

  // an iterator to the currentlt selected channel
  std::list<Channel>::iterator sel_channel;

  // iterator pointing the currently selected program.
  std::vector<Programme>::iterator program_iter;
  std::vector<Programme>::iterator program_iter_end;

  // then screen spans cur_time to cur_time + some hours depending on the screen
  // size.
  time_t cur_time;
  // sel_time is the start time of the currently selected program
  time_t sel_time;

  int rows;
  int y_start;

  int timeslots;
  int x_start;

  double scale_factor;

  bool epg_script_found;

  EpgUpdate *e;

 public:
  static Epg* instance;

  // singleton
  static Epg* get_instance();

  // gcc 2.95 fix
  void print();

  void read_db();
  bool check_db();

  // an iterator to the first channel visible on the screen
  std::list<Channel>::iterator cur_channel;

  void update_time();

  std::string mainloop();

  EpgOpts opts;

  void epg_print();
  int check_epg_print();

  void update_epg_datafile();
  int check_epg_datafile();

  void startup_updater();
};

#endif
