/*------------------------------------------------------------------------------
 src/lib/djWidget/djFileBrowser.h
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
------------------------------------------------------------------------------*/

#ifndef DJ_FILE_BROWSER_H
#define DJ_FILE_BROWSER_H
#include <djDir.h>
//#include <djImageIo.h>
#include <djWidget.h>
#include <djDialog.h>
#include <FL/Fl_Image.H>
#include <FL/Fl_Browser_.H>

namespace dj {

class Prefs;
class TextWidget;
class CheckButtonWidget;
class MenuItems;
class MenubarWidget;

// File browser options.
//
enum FILE_BROWSER_IMAGES {
  FILE_BROWSER_IMAGES_OFF,
  FILE_BROWSER_IMAGES_LOW,
  FILE_BROWSER_IMAGES_HIGH
};

// File browser item.
//
class FileBrowserItem {
public:

  FileBrowserItem();
  ~FileBrowserItem();
  
  void set(const FileInfo &);
  const FileInfo & get() const { return _value; }

  Fl_Image * image(bool proxyScale) const;
  const Vec2i & imageSize(bool proxyScale) const;
  bool imageIsValid() const { return _imageValid; }
  
  //const Str & imageIoPlugin() const { return _imageIoPlugin; }
  //const ImageIoInfo & imageIoInfo() const { return _imageIoInfo; }

private:

  FileInfo _value;
  Fl_Image * _imageFl;
  //Str _imageIoPlugin;
  //ImageIoInfo _imageIoInfo;
  Vec2i _imageSize;
  bool _imageValid, _imageSizeValid;
};

// File browser widget.
//
class FileBrowserWidget : public Fl_Browser_, public WidgetBase {
public:

  FileBrowserWidget();
  ~FileBrowserWidget();
  
  // Value.
  //
  void set(
    const List<FileInfo> &,
    bool info, FILE_BROWSER_IMAGES
  );
  const FileBrowserItem * get() const;
  
  // Signals.
  //
  Signal<const FileBrowserItem *> & sig() { return _sig; }
  Signal<const FileBrowserItem *> & actionSig() { return _actionSig; }
  
  // Layout.
  //
  void resize(int, int, int, int);
  int visible() const;

  // Widget.
  //
  int handle(int);

private:

  void * item_first() const;
  void * item_next(void *) const;
  void * item_prev(void *) const;
  int item_height(void *) const;
  int item_quick_height(void *) const;
  int item_width(void *) const;
  void item_draw(void *, int, int, int, int) const;
  
  DJ_FL_WIDGET_CALLBACK(FileBrowserWidget, widgetCallback)
  DJ_FL_CALLBACK(FileBrowserWidget, imageCallback)

  FileBrowserItem * _items;
  int _itemsSize;
  bool _info;
  int _textHeight;
  int _nameWidth, _typeWidth, _sizeWidth, _userWidth, _permWidth, _timeWidth;
  FILE_BROWSER_IMAGES _images;
  List<FileBrowserItem *> _imagesWorkList;
  
  Signal<const FileBrowserItem *> _sig, _actionSig;
};

// File browser dialog.
//
class FileBrowserDialog : public DialogBase {
public:

  FileBrowserDialog();
  ~FileBrowserDialog();
  void die();
  
  // Value.
  //
  void set(const Str &);
  const Str get() const;
  
  // Directory.
  //
  void dir(const Str &);
  const Str dir() const;
  
  // Options.
  //
  void info(bool);
  void seq(bool);
  void showHidden(bool);
  void sort(FILE_SORT);
  void sortReverse(bool);
  void sortDirsFirst(bool);
  void images(FILE_BROWSER_IMAGES);
  bool info() const { return _info; }
  bool seq() const { return _seq; }
  bool showHidden() const { return _showHidden; }
  FILE_SORT sort() const { return _sort; }
  bool sortReverse() const { return _sortReverse; }
  bool sortDirsFirst() const { return _sortDirsFirst; }
  FILE_BROWSER_IMAGES images() const { return _images; }
  
  // Bookmarks.
  //
  void bookmarkList(const StrList &);
  const StrList & bookmarkList() const { return _bookmarkList; }
  
  // Dialog.
  //
  void pin(bool);
  bool pin() const { return _pin; }
  
  // Signals.
  //
  Signal<const Str &> & sig() { return _sig; }
  
  // Widget.
  //
  int handle(int);
  
  // Preferences.
  //
  void prefs(const Str & name, const Prefs &);
  void prefs(const Str & name, Prefs *);

private:

  // Widget callbacks.
  //
  DJ_CALLBACK(FileBrowserDialog, widgetCallback, const Str &)
  DJ_CALLBACK(FileBrowserDialog, dirCallback, const Str &)
  DJ_CALLBACK(FileBrowserDialog, browserCallback, const FileBrowserItem *)
  DJ_CALLBACK(FileBrowserDialog, browserActionCallback, const FileBrowserItem *)
  
  // Directory callbacks.
  //
  DJ_CALLBACK(FileBrowserDialog, upCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, prevCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, homeCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, workCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, rootCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, reloadCallback, bool)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, upCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, prevCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, homeCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, workCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, rootCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, reloadCallback)
  
  // Options callbacks.
  //
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, infoCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, seqCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, showHiddenCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, sortCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, sortReverseCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, sortDirsFirstCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, imagesCallback)
  
  // Bookmark callbacks.
  //
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, bookmarkListAddCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, bookmarkListDelCallback)
  DJ_CALLBACK(FileBrowserDialog, bookmarkListDelAllCallback, bool)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, bookmarkListDelAllCallback)
  DJ_FL_WIDGET_CALLBACK(FileBrowserDialog, bookmarkListCallback)
  
  // Dialog callbacks.
  //
  DJ_CALLBACK(FileBrowserDialog, pinCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, okCallback, bool)
  DJ_CALLBACK(FileBrowserDialog, closeCallback, bool)
  
  // Update.
  //
  void dirUpdate();
  void menuUpdate();

  Dir _dir;
  Str _dirPrev;
  
  bool _info;
  bool _seq;
  bool _showHidden;
  FILE_SORT _sort;
  bool _sortReverse, _sortDirsFirst;
  FILE_BROWSER_IMAGES _images;
  StrList _bookmarkList;
  bool _pin;
  
  Signal<const Str &> _sig;
  
  MenuItems * _menuItems;
  MenubarWidget * _menubar;
  IntList _menuSortId, _menuImagesId, _menuBookmarkListId;
  TextWidget * _widget, * _dirWidget;
  FileBrowserWidget * _browserWidget;
  CheckButtonWidget * _pinWidget;
  bool _callbacks;
};

// Labels.
//
inline const StrList fileBrowserImagesStr()
  { return StrList() + Str("Off") + Str("Low Quality") + Str("High Quality"); }

}

#endif
