/* 
 * © 2008-2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef _LF_FILECHOOSER_H_
#define _LF_FILECHOOSER_H_

#include <mforms/mforms.h>

#include "lf_mforms.h"
#include "lf_view.h"

#define RESPONSE_OK 1
#define RESPONSE_CANCEL 0



namespace mforms {
namespace gtk {

class FileChooserImpl : public ViewImpl
{
  Gtk::FileChooserDialog *_dlg;
  Gtk::Widget *get_outer() const { return _dlg; }

  static std::vector<std::string> split_string(const std::string &s, const std::string &sep)
  {
    std::vector<std::string> parts;
    std::string ss= s;

    std::string::size_type p;

    if (s.empty())
      return parts;

    p= ss.find(sep);
    while (!ss.empty() && p != std::string::npos)
    {
      parts.push_back(ss.substr(0, p));
      ss= ss.substr(p+sep.size());

      p= ss.find(sep);
    }
    parts.push_back(ss);

    return parts;
  
  }
  
  static bool create(::mforms::FileChooser *self, ::mforms::FileChooserType type)
  {
    return new FileChooserImpl(self, type) != 0;
  }

  static void set_title(::mforms::FileChooser *self, const std::string &title)
  {
    FileChooserImpl *dlg = self->get_data<FileChooserImpl>();
    if ( dlg )
      dlg->_dlg->set_title(title);
  }

  static bool show_modal(::mforms::FileChooser *self)
  {
    FileChooserImpl *dlg = self->get_data<FileChooserImpl>();
    bool res;
    res= dlg->_dlg->run() == RESPONSE_OK;
    dlg->_dlg->hide();
    return res;
  }

  static void set_directory(FileChooser *self, const std::string &path)
  {
    FileChooserImpl *dlg = self->get_data<FileChooserImpl>();
    if ( dlg )
    {
      dlg->_dlg->set_current_folder(path);
    }
  }

  static std::string get_directory(FileChooser *self)
  {
    FileChooserImpl *dlg = self->get_data<FileChooserImpl>();
    if ( dlg )
    {
      return dlg->_dlg->get_current_folder();
    }
    return "";
  }


  static std::string get_path(FileChooser *self)
  {
    FileChooserImpl *dlg = self->get_data<FileChooserImpl>();
    return dlg ? dlg->_dlg->get_filename().raw() : "";
  }

  static void set_extensions(FileChooser *self, const std::string &extensions, const std::string &default_extension)
  {
    FileChooserImpl *dlg = self->get_data<FileChooserImpl>();
    if ( dlg )
    {      
      // extensions format:
      // AAA Files (*.aaa)|*.aaa,BBB Files (*.bbb)
      std::vector<std::pair<std::string, std::string> > exts(self->split_extensions(extensions));
      
      for (std::vector<std::pair<std::string, std::string> >::const_iterator iter= exts.begin();
           iter != exts.end(); ++iter)
      {
        Gtk::FileFilter filter;
        
        filter.add_pattern(iter->second);
        filter.set_name(iter->first);
        
        dlg->_dlg->add_filter(filter);
      }
      
      Gtk::FileFilter filter;
      filter.add_pattern("*");
      filter.set_name("All Files");

      dlg->_dlg->add_filter(filter);
    }
  }

  FileChooserImpl(::mforms::FileChooser *form, ::mforms::FileChooserType type)
    : ViewImpl(form)
  {
    //FileChooserDialog *dialog = 0;
    switch (type)
    {
    case ::mforms::OpenFile:
      _dlg = new Gtk::FileChooserDialog("Open File...", Gtk::FILE_CHOOSER_ACTION_OPEN);
      _dlg->add_button(Gtk::Stock::CANCEL, RESPONSE_CANCEL);
      _dlg->add_button(Gtk::Stock::OPEN, RESPONSE_OK);
      break;
    case ::mforms::SaveFile:
      _dlg = new Gtk::FileChooserDialog("Save File...", Gtk::FILE_CHOOSER_ACTION_SAVE);
      _dlg->add_button(Gtk::Stock::CANCEL, RESPONSE_CANCEL);
      _dlg->add_button(Gtk::Stock::SAVE, RESPONSE_OK);
      _dlg->set_do_overwrite_confirmation(true);
      break;
    case ::mforms::OpenDirectory:
      _dlg = new Gtk::FileChooserDialog("Open Directory...", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
      _dlg->add_button(Gtk::Stock::CANCEL, RESPONSE_CANCEL);
      _dlg->add_button(Gtk::Stock::OPEN, RESPONSE_OK);
      break;      
    }
  }

  virtual ~FileChooserImpl()
  {
    delete _dlg;
  }

 public:
  static void init()
  {
    ::mforms::ControlFactory *f = ::mforms::ControlFactory::get_instance();

    f->_filechooser_impl.create = &FileChooserImpl::create;
    f->_filechooser_impl.set_title = &FileChooserImpl::set_title;
    f->_filechooser_impl.run_modal = &FileChooserImpl::show_modal;
    f->_filechooser_impl.set_extensions = &FileChooserImpl::set_extensions;
    f->_filechooser_impl.set_directory = &FileChooserImpl::set_directory;
    f->_filechooser_impl.get_directory = &FileChooserImpl::get_directory;
    f->_filechooser_impl.get_path = &FileChooserImpl::get_path;
  }
};

};
};

#endif
