/* Copyright 1998-1999 The gtkmm Development Team
 * Copyright 2001      Free Software Foundation
 *
 * 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.1 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, see <https://www.gnu.org/licenses/>.
 */

namespace Pango
{

AttrIter::AttrIter()
:
  gobject_(0)
{}

AttrIter::AttrIter(const AttrIter& src)
:
  gobject_(src.gobject_ ? pango_attr_iterator_copy(src.gobject_) : 0)
{}

AttrIter::AttrIter(PangoAttrIterator* castitem, bool take_copy)
{
  if(take_copy)
  {
    if(castitem)
      gobject_ = pango_attr_iterator_copy(castitem);
    else
      gobject_ = 0;
  }
  else
  {
    gobject_ = castitem;
  }
}

AttrIter::~AttrIter()
{
  if(gobject_)
     pango_attr_iterator_destroy(gobject_);
}

AttrIter& AttrIter::operator=(const AttrIter& src)
{
  PangoAttrIterator *const new_gobject = (src.gobject_ ? pango_attr_iterator_copy(src.gobject_) : 0);

  if(gobject_)
     pango_attr_iterator_destroy(gobject_);
  gobject_ = new_gobject;

  return *this;
}

AttrIter& AttrIter::operator++()
{
  next();
  return *this;
}

const AttrIter AttrIter::operator++(int)
{
  AttrIter previous(*this);
  next();
  return previous;
}

/* operator bool() cannot be implemented to work properly if a Pango::AttrIter is created
 * from an already invalid PangoAttrIterator* because there is no way to validate it.
 * Otherwise the iterator can only become invalid after some call to Pango::AttrIter::next()
 * in which case gobject_ is destroyed thus marking the iterator as invalid.
 */
AttrIter::operator bool() const
{
  return (gobject_ != 0);
}

bool AttrIter::next()
{
  if(!pango_attr_iterator_next(gobj()))
  {
    pango_attr_iterator_destroy(gobject_);
    gobject_ = 0; // Mark as invalid. There is no other way to determine whether the iterator is valid later.
    return false;
  }
  else
    return true;
}

FontDescription AttrIter::get_font_desc() const
{
  FontDescription desc;
  pango_attr_iterator_get_font(const_cast<PangoAttrIterator*>(gobj()), desc.gobj(), 0, 0);

  // See pango ref docs for pango_attr_iterator_get_font.
  pango_font_description_set_family(desc.gobj(), pango_font_description_get_family(desc.gobj()));

  return desc;
}

Language AttrIter::get_language() const
{
  FontDescription desc;
  PangoLanguage* language = 0;

  pango_attr_iterator_get_font(const_cast<PangoAttrIterator*>(gobj()), desc.gobj(), &language, 0);

  return Language(language, true);
}

SListHandle_Attribute AttrIter::get_extra_attrs() const
{
  FontDescription desc;
  GSList* extra_attrs = 0;

  pango_attr_iterator_get_font(const_cast<PangoAttrIterator*>(gobj()), desc.gobj(), 0, &extra_attrs);

  return SListHandle_Attribute(extra_attrs, Glib::OWNERSHIP_DEEP);
}

SListHandle_Attribute AttrIter::get_attrs() const
{
  GSList* attrs = pango_attr_iterator_get_attrs( const_cast<PangoAttrIterator*>(gobj()) );
  return SListHandle_Attribute(attrs, Glib::OWNERSHIP_DEEP);
}

} /* namespace Pango */

namespace Glib
{

Pango::AttrIter wrap(PangoAttrIterator* object, bool take_copy)
{
  return Pango::AttrIter(object, take_copy);
}

} /* namespace Glib */
