#ifndef PICTURES_HPP
#define PICTURES_HPP

#include <stack>

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

class Pictures : public Module 
{
 private:
  Pictures();

  void action_no_find_recursion();

  // commands
  void action();
  void go_back();
  void recurse_dirs();
  void options();
  void search_func();
  void exit();
  void exit_fullscreen();

  // fullscreen commands
  void zoom();
  void suspend();
  void rotate_left();
  void rotate_right();
  void options_fullscreen();

  void deactivate_updaters();
  void activate_updaters();

  bool enter_dir();

  bool exit_loop;

  bool in_fullscreen;

  bool search_compare(const Simplefile& s);
  std::string get_name_from_file(const Simplefile& e);

  void print(const std::vector<Simplefile>& pic_list);
  void prepare_and_show_fullscreen();
  void pictures_fullscreen();

  // helper functions, to minimize code copying, functions used in mainloops.
  void prev();
  void next();

  std::vector<std::string> images_in_dir(const std::list<std::string>& dirs);

  std::vector<Simplefile> parse_dirs_recursion();
  void find_recursion_file();
  bool find_recursion_pos();

  // helper
  bool already_tested(const std::vector<std::string>& tested_dirs, std::string dir);

  int pos_recursion;
  std::vector<Simplefile> recurse_files;

  void prev_no_skip_folders();
  void next_no_skip_folders();

  void prev_skip_folders();
  void next_skip_folders();

  bool testdir(const std::string& dir);

  Simplefile addfile(const std::string& name, const MyPair& filetype);
  std::vector<Simplefile> rdir(const std::string& argv);
  std::vector<Simplefile> parse_dir(const std::list<std::string>& dirs);

  int image_width;
  int image_height;
  int image_height_all_eks_text;

  // including text and space around image
  int image_width_all;
  int image_height_all;
  int image_height_all_search;

  int images_per_row;
  int rows;
  int rows_search;

  int y_start;

  int orientation;

  int zoom_level; // 1 or 2 currently
  int zoom_position; // 1 to X, where 1..max_pos_v is top, etc.
  int zoom_pos_h, zoom_pos_v;
  int max_pos_h, max_pos_v;

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

    std::string slideshow() 
    {
      return val[2]->values[val[2]->pos];
    }
    
    std::string zoom() 
    {
      return val[3]->values[val[3]->pos];
    }

    std::string show_preview() 
    {
      return val[4]->values[val[4]->pos];
    }

    std::string recurse_in_fullscreen()
    {
      return val[5]->values[val[5]->pos];
    }

    std::string thumbnail_extract() 
    {
      return val[6]->values[val[6]->pos];
    }

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

  private:
    void read_dirs();

    Option *reload_p, *slideshow_p, *zoom_p, *preview_p, *recurse_p, *thumbnail_extract_p;
  };

  struct file_sort
  {
    bool operator()(const Simplefile& lhs, const Simplefile& rhs);
  };

  // background thumbnail extraction
  void background_thumbnails();
  int check_thumbnail();

  bool thumbnailed_all_files;
  std::vector<std::string> all_image_files;

  // status of fullscreen
  bool pause;
  long int last_press;

 public:
  // singleton
  static Pictures& get_instance();

  // gcc 2.95 fix

  // for saving information about how you traverse a filesystem a stack is a
  // much better solution. The first element is the dirs and the next is the
  // position
  std::stack<std::pair<std::list<std::string>, int > > folders;

  void print_fullscreen(const Simplefile& e, const std::string& l, const std::string& r);

  std::vector<Simplefile> pic_list;

  void reset();

  void load_current_dirs();
  void read_dirs();

#ifdef use_media
  void play_pictures_cd();
#endif

  std::string mainloop();

  PicOpts opts;

  void pictures_check();
  int check_picture_time();

  void startup_updater();
};

#endif
