/* 
 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 * 
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "../lf_mforms.h"

#include "mforms/hypertext.h"

#include "../lf_view.h"
#include <glib/gprintf.h>
#include <glib-object.h>
#include <glib.h>
#include "base/string_utilities.h"
#include <stdio.h>

namespace mforms
{

namespace gtk
{

//==============================================================================
//
//==============================================================================
class HyperTextImpl : public ViewImpl
{
  public:
    HyperTextImpl(HyperText* self);

    static bool create(HyperText *ht);
    static void set_markup_text(HyperText *ht, const std::string &text);
    static void set_background_color(HyperText *ht, const std::string &color);

    static void init();

  protected:
    virtual void set_back_color(const std::string &color);

    virtual Gtk::Widget* get_outer() const
    {
      return &_win;
    }

  private:
    mutable Gtk::ScrolledWindow   _win;
    Gtk::TextView                 _text;
    gulong                        _conn;
};

//------------------------------------------------------------------------------
HyperTextImpl::HyperTextImpl(HyperText* self)
              : ViewImpl(self)
              , _conn(0)
{
  _win.add(_text);
  _win.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
  _text.show();
}

//------------------------------------------------------------------------------
bool HyperTextImpl::create(HyperText *ht)
{
  return new HyperTextImpl(ht);
}

static std::string strip_html(const std::string& input)
{
  std::string s(input);
  std::string ret;

  if (s.length())
  {
    const size_t slen = s.length();
    bool         copy = true;

    ret.reserve(slen);

    for (size_t i = 0; i < slen; ++i)
    {
      if (s[i] == '<')
      {
        copy = false;
        std::string::size_type p = s.find('>', i);
        if (p != std::string::npos)
        {
          std::string tag = s.substr(i, p-i+1);
          if (tag == "<br>" || tag == "<br/>" || tag == "</div>")
          {
            ret.push_back('\n');
            i += tag.size()+1;
          }
          else if (tag == "<tr>" || tag.find("<tr ") == 0)
          {
            ret.push_back('\n');
            i += tag.size()+1;
          }
          else if (tag == "<td>" || tag.find("<td ") == 0)
          {
            ret.push_back('\t');
            i += tag.size()+1;
          }
        }
      }
      else if (s[i] == '>')
        copy = true;
      else if (s[i] == '&')
      {
        copy = false;
        std::string::size_type p = s.find(';', i);
        if (p != std::string::npos)
        {
          std::string tag = s.substr(i, p-i+1);
          if (tag == "&lt;")
          {
            ret.push_back('<');
            i += tag.size()+1;
          }
          else if (tag == "&gt;")
          {
            ret.push_back('>');
            i += tag.size()+1;
          }
          else if (tag == "&amp;")
          {
            ret.push_back('&');
            i += tag.size()+1;
          }
        }
      }
      else if (copy)
        ret.push_back(s[i]);
    }
  }
  return ret;
}

//------------------------------------------------------------------------------
void HyperTextImpl::set_markup_text(HyperText *self, const std::string &text)
{
  HyperTextImpl *impl = self->get_data<HyperTextImpl>();
  if (impl)
    impl->_text.get_buffer()->set_text(strip_html(text));
}

//------------------------------------------------------------------------------
void HyperTextImpl::set_back_color(const std::string &color)
{
}

//------------------------------------------------------------------------------
void HyperText_init()
{
  ::mforms::ControlFactory *f = ::mforms::ControlFactory::get_instance();

  f->_hypertext_impl.create               = &HyperTextImpl::create;
  f->_hypertext_impl.set_markup_text      = &HyperTextImpl::set_markup_text;
}

} // gtk

} // mforms
