//  BMP
//  Copyright (C) 2005-2007 BMP development.
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License Version 2
//  as published by the Free Software Foundation.
//
//  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, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
//  --
//
//  The BMPx project hereby grants permission for non-GPL compatible GStreamer
//  plugins to be used and distributed together with GStreamer and BMPx. This
//  permission is above and beyond the permissions granted by the GPL license
//  BMPx is covered by.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

#include <glibmm.h>
#include <glibmm/markup.h>
#include <glibmm/i18n.h>
#include <glib.h>
#include <gtk/gtkliststore.h>
#include <gtkmm.h>
#include "util.hh"
using namespace Glib;
using namespace Gtk;

#include "radio-directory-types.hh"
#include "radio-directory-view-base.hh"

namespace Bmp
{
  namespace RadioDirectory
  {
      SignalStartStop&
      ViewBase::signal_start ()
      {
        return Signals.Start;
      }

      SignalStartStop&
      ViewBase::signal_stop ()
      {
        return Signals.Stop; 
      }

      void
      ViewBase::set_stream_list (StreamListT const& entries)
      {
        BaseData.Streams->clear ();
        for (StreamListT::const_iterator i = entries.begin() ;  i != entries.end() ; ++i) 
        {
          StreamInfo const& entry (*i);
          TreeModel::iterator m_iter = BaseData.Streams->append ();
          gtk_list_store_set (BaseData.Streams->gobj(), const_cast<GtkTreeIter*>(m_iter->gobj()),
                              0, entry.name.c_str(),
                              1, entry.bitrate,
                              2, entry.genre.c_str(),
                              3, entry.current.c_str(),
                              4, entry.uri.c_str(), -1);
          while (gtk_events_pending ()) gtk_main_iteration();
        }
      }

      bool
      ViewBase::visible_func (TreeModel::iterator const& m_iter)
      {
        if (!BaseData.Filter.length ())
          return true;

        ustring name    ((*m_iter)[columns.name]);
        ustring genre   ((*m_iter)[columns.genre]);
        ustring needle  (BaseData.Filter.casefold ());

        name.casefold();
        genre.casefold();

        return ((Util::match_keys (name, needle)) || (Util::match_keys (genre, needle)));
      }

      void
      ViewBase::set_filter (Glib::ustring const& text)
      {
        BaseData.Filter = text;
        BaseData.Filtered->refilter ();
      }

      void
      ViewBase::column_clicked (int column)
      {
        SortType sort_type, sort_type_new;
        int           sort_id;

        BaseData.Streams->get_sort_column_id (sort_id, sort_type);

        if ((sort_id >= 0) && (sort_id != column))
        {
          get_column (sort_id)->set_sort_indicator (false);
        }

        if (sort_id >= 0)
          sort_type_new = (sort_type == SORT_ASCENDING) ? SORT_DESCENDING : SORT_ASCENDING;
        else
          sort_type_new = SORT_ASCENDING;

        BaseData.Streams->set_sort_column_id (column, sort_type_new);
        get_column (column)->set_sort_indicator (true);
        get_column (column)->set_sort_order (sort_type_new);
      }

      void 
      ViewBase::get (Glib::ustring & title, Glib::ustring & uri)
      {
        TreeModel::iterator m_iter = get_selection()->get_selected ();
        uri   = (*m_iter)[columns.uri];
        title = (*m_iter)[columns.name];
      }

      ViewBase::ViewBase (BaseObjectType * obj,
                          Glib::RefPtr<Gnome::Glade::Xml> const& G_GNUC_UNUSED) 
      : TreeView (obj)
      {
        BaseData.Streams = ListStore::create (columns);
        BaseData.Filtered = TreeModelFilter::create (BaseData.Streams);
        BaseData.Filtered->set_visible_func (sigc::mem_fun (this, &Bmp::RadioDirectory::ViewBase::visible_func));

        const char* column_headers[] =
        {
          N_("Stream Name"),
          N_("Bitrate"),
          N_("Stream Genre"),
          N_("Current Song"),
        };

        for (unsigned int n = 0; n < G_N_ELEMENTS (column_headers); n++)
        {
          CellRendererText *cell;
          cell = manage (new CellRendererText());
          append_column (_(column_headers[n]), *cell);
          get_column (n)->add_attribute (*cell, "text", n);
          get_column (n)->set_resizable (true);
          get_column (n)->signal_clicked ().connect
                    (sigc::bind (sigc::mem_fun (this, &Bmp::RadioDirectory::ViewBase::column_clicked),n));
        }
        get_selection()->set_mode (SELECTION_SINGLE);
        set_headers_clickable (true);
        set_model (BaseData.Filtered);
      }
  }
};
