/* poppler-form-field.cc: glib interface to poppler
 *
 * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
 * Copyright (C) 2006 Julien Rebetez
 *
 * 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; either version 2, or (at your option)
 * any later version.
 *
 * 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.
 */

#include "poppler.h"
#include "poppler-private.h"

typedef struct _PopplerFormFieldClass PopplerFormFieldClass;
struct _PopplerFormFieldClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (PopplerFormField, poppler_form_field, G_TYPE_OBJECT);

static void
poppler_form_field_finalize (GObject *object)
{
  PopplerFormField *field = POPPLER_FORM_FIELD (object);

  if (field->document)
    {
      g_object_unref (field->document);
      field->document = NULL;
    }
  field->widget = NULL;

  G_OBJECT_CLASS (poppler_form_field_parent_class)->finalize (object);
}

static void
poppler_form_field_init (PopplerFormField *field)
{
}

static void
poppler_form_field_class_init (PopplerFormFieldClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = poppler_form_field_finalize;
}

PopplerFormField *
_poppler_form_field_new (PopplerDocument *document,
			 FormWidget      *field)
{
  PopplerFormField *poppler_field;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
  g_return_val_if_fail (field != NULL, NULL);

  poppler_field = POPPLER_FORM_FIELD (g_object_new (POPPLER_TYPE_FORM_FIELD, NULL));

  poppler_field->document = (PopplerDocument *)g_object_ref (document);
  poppler_field->widget = field;
  
  return poppler_field;
}

/* Public methods */
/**
 * poppler_form_field_get_field_type:
 * @field: a #PopplerFormField
 *
 * Gets the type of @field
 *
 * Return value: #PopplerFormFieldType of @field
 **/ 
PopplerFormFieldType
poppler_form_field_get_field_type (PopplerFormField *field)
{
  g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), POPPLER_FORM_FIELD_UNKNOWN);
  
  switch (field->widget->getType ())
  {
    case formButton:
      return POPPLER_FORM_FIELD_BUTTON;
    case formText:
      return POPPLER_FORM_FIELD_TEXT;
    case formChoice:
      return POPPLER_FORM_FIELD_CHOICE;
    case formSignature:
      return POPPLER_FORM_FIELD_SIGNATURE;
    default:
      g_warning ("Unsupported Form Field Type");
  }

  return POPPLER_FORM_FIELD_UNKNOWN;
}

/**
 * poppler_form_field_get_id:
 * @field: a #PopplerFormField
 *
 * Gets the id of @field
 *
 * Return value: the id of @field
 **/
gint
poppler_form_field_get_id (PopplerFormField *field)
{
  g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), -1);
  
  return field->widget->getID ();
}

/**
 * poppler_form_field_get_font_size
 * @field: a #PopplerFormField
 *
 * Gets the font size of @field
 *
 * Return value: the font size of @field
 **/
gdouble
poppler_form_field_get_font_size (PopplerFormField *field)
{
  g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), 0);
  
  return field->widget->getFontSize ();
}

/**
 * poppler_form_field_is_read_only
 * @field: a #PopplerFormField
 *
 * Checks whether @field is read only
 *
 * Return value: %TRUE if @field is read only
 **/
gboolean
poppler_form_field_is_read_only (PopplerFormField *field)
{
  g_return_val_if_fail (POPPLER_IS_FORM_FIELD (field), FALSE);

  return field->widget->isReadOnly ();
}

/* Button Field */
/**
 * poppler_form_field_button_get_button_type
 * @field: a #PopplerFormField
 *
 * Gets the button type of @field
 *
 * Return value: #PopplerFormButtonType of @field
 **/
PopplerFormButtonType
poppler_form_field_button_get_button_type (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formButton, POPPLER_FORM_BUTTON_PUSH);

  switch (static_cast<FormWidgetButton*>(field->widget)->getButtonType ())
    {
      case formButtonPush:
        return POPPLER_FORM_BUTTON_PUSH;
      case formButtonCheck:
        return POPPLER_FORM_BUTTON_CHECK;
      case formButtonRadio:
        return POPPLER_FORM_BUTTON_RADIO;
      default:
        g_assert_not_reached ();
    }
}

/**
 * poppler_form_field_button_get_state
 * @field: a #PopplerFormField
 *
 * Queries a #PopplerFormField and returns its current state. Returns %TRUE if
 * @field is pressed in and %FALSE if it is raised.
 *
 * Return value: current state of @field
 **/
gboolean
poppler_form_field_button_get_state (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formButton, FALSE);
  
  return static_cast<FormWidgetButton*>(field->widget)->getState ();
}

/**
 * poppler_form_field_button_set_state
 * @field: a #PopplerFormField
 * @state: %TRUE or %FALSE
 *
 * Sets the status of @field. Set to %TRUE if you want the #PopplerFormField
 * to be 'pressed in', and %FALSE to raise it. 
 **/
void
poppler_form_field_button_set_state (PopplerFormField *field,
				     gboolean          state)
{
  g_return_if_fail (field->widget->getType () == formButton);

  static_cast<FormWidgetButton*>(field->widget)->setState ((GBool)state);
}

/* Text Field */
/**
 * poppler_form_field_text_get_text_type:
 * @field: a #PopplerFormField
 *
 * Gets the text type of @field.
 *
 * Return value: #PopplerFormTextType of @field
 **/
PopplerFormTextType
poppler_form_field_text_get_text_type (PopplerFormField *field)
{
  FormWidgetText *text_field;
  
  g_return_val_if_fail (field->widget->getType () == formText, POPPLER_FORM_TEXT_NORMAL);

  text_field = static_cast<FormWidgetText*>(field->widget);
  
  if (text_field->isMultiline ())
    return POPPLER_FORM_TEXT_MULTILINE;
  else if (text_field->isFileSelect ())
    return POPPLER_FORM_TEXT_FILE_SELECT;

  return POPPLER_FORM_TEXT_NORMAL;
}

/**
 * poppler_form_field_text_get_text:
 * @field: a #PopplerFormField
 *
 * Retrieves the contents of @field.
 *
 * Return value: a new allocated string. It must be freed with g_free() when done.
 **/
gchar *
poppler_form_field_text_get_text (PopplerFormField *field)
{
  FormWidgetText *text_field;
  GooString      *tmp;

  g_return_val_if_fail (field->widget->getType () == formText, NULL);

  text_field = static_cast<FormWidgetText*>(field->widget);
  tmp = text_field->getContent ();

  return tmp ? _poppler_goo_string_to_utf8 (tmp) : NULL;
}

/**
 * poppler_form_field_text_set_text:
 * @field: a #PopplerFormField
 * @text: the new text
 *
 * Sets the text in @field to the given value, replacing the current contents.
 **/
void
poppler_form_field_text_set_text (PopplerFormField *field,
				  const gchar      *text)
{
  GooString *goo_tmp;
  gchar *tmp;
  gsize length = 0;
	
  g_return_if_fail (field->widget->getType () == formText);

  tmp = text ? g_convert (text, -1, "UTF16BE", "UTF8", NULL, &length, NULL) : NULL;
  goo_tmp = new GooString (tmp, length);
  g_free (tmp);
  static_cast<FormWidgetText*>(field->widget)->setContent (goo_tmp);
  delete goo_tmp;
}

/**
 * poppler_form_field_text_get_max_len:
 * @field: a #PopplerFormField
 *
 * Retrieves the maximum allowed length of the text in @field
 *
 * Return value: the maximum allowed number of characters in @field, or -1 if there is no maximum.
 **/
gint
poppler_form_field_text_get_max_len (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formText, 0);

  return static_cast<FormWidgetText*>(field->widget)->getMaxLen ();
}

/**
 * poppler_form_field_text_do_spell_check:
 * @field: a #PopplerFormField
 *
 * Checks whether spell checking should be done for the contents of @field
 *
 * Return value: %TRUE if spell checking should be done for @field
 **/
gboolean
poppler_form_field_text_do_spell_check (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formText, FALSE);

  return !static_cast<FormWidgetText*>(field->widget)->noSpellCheck ();
}

gboolean
poppler_form_field_text_do_scroll (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formText, FALSE);

  return !static_cast<FormWidgetText*>(field->widget)->noScroll ();
}

/**
 * poppler_form_field_text_is_rich_text:
 * @field: a #PopplerFormField
 *
 * Checks whether the contents of @field are rich text
 *
 * Return value: %TRUE if the contents of @field are rich text
 **/
gboolean
poppler_form_field_text_is_rich_text (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formText, FALSE);

  return static_cast<FormWidgetText*>(field->widget)->isRichText ();
}

/**
 * poppler_form_field_text_is_password:
 * @field: a #PopplerFormField
 *
 * Checks whether content of @field is a password and it must be hidden
 *
 * Return value: %TRUE if the content of @field is a password
 **/
gboolean
poppler_form_field_text_is_password (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formText, FALSE);

  return static_cast<FormWidgetText*>(field->widget)->isPassword ();
}

/* Choice Field */
/**
 * poppler_form_field_choice_get_choice_type:
 * @field: a #PopplerFormField
 *
 * Gets the choice type of @field
 *
 * Return value: #PopplerFormChoiceType of @field
 **/
PopplerFormChoiceType
poppler_form_field_choice_get_choice_type (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, POPPLER_FORM_CHOICE_COMBO);

  if (static_cast<FormWidgetChoice*>(field->widget)->isCombo ())
    return POPPLER_FORM_CHOICE_COMBO;
  else
    return POPPLER_FORM_CHOICE_LIST;
}

/**
 * poppler_form_field_choice_is_editable:
 * @field: a #PopplerFormField
 *
 * Checks whether @field is editable
 *
 * Return value: %TRUE if @field is editable
 **/ 
gboolean
poppler_form_field_choice_is_editable (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, FALSE);

  return static_cast<FormWidgetChoice*>(field->widget)->hasEdit ();
}

/**
 * poppler_form_field_choice_can_select_multiple:
 * @field: a #PopplerFormField
 *
 * Checks whether @field allows multiple choices to be selected
 *
 * Return value: %TRUE if @field allows multiple choices to be selected
 **/
gboolean
poppler_form_field_choice_can_select_multiple (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, FALSE);

  return static_cast<FormWidgetChoice*>(field->widget)->isMultiSelect ();
}

/**
 * poppler_form_field_choice_do_spell_check:
 * @field: a #PopplerFormField
 *
 * Checks whether spell checking should be done for the contents of @field
 *
 * Return value: %TRUE if spell checking should be done for @field
 **/
gboolean
poppler_form_field_choice_do_spell_check (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, FALSE);

  return !static_cast<FormWidgetChoice*>(field->widget)->noSpellCheck ();
}

gboolean
poppler_form_field_choice_commit_on_change (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, FALSE);

  return static_cast<FormWidgetChoice*>(field->widget)->commitOnSelChange ();
}

/**
 * poppler_form_field_choice_get_n_items:
 * @field: a #PopplerFormField
 *
 * Returns the number of items on @field
 *
 * Return value: the number of items on @field
 **/
gint
poppler_form_field_choice_get_n_items (PopplerFormField *field)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, -1);

  return static_cast<FormWidgetChoice*>(field->widget)->getNumChoices ();
}

/**
 * poppler_form_field_choice_get_item:
 * @field: a #PopplerFormField
 * @index: the index of the item
 *
 * Returns the contents of the item on @field at the given index
 *
 * Return value: a new allocated string. It must be freed with g_free() when done.
 **/
gchar *
poppler_form_field_choice_get_item (PopplerFormField *field,
				    gint              index)
{
  GooString *tmp;
  
  g_return_val_if_fail (field->widget->getType () == formChoice, NULL);

  tmp = static_cast<FormWidgetChoice*>(field->widget)->getChoice (index);
  return tmp ? _poppler_goo_string_to_utf8 (tmp) : NULL;
}

/**
 * poppler_form_field_choice_is_item_selected:
 * @field: a #PopplerFormField
 * @index: the index of the item
 *
 * Checks whether the item at the given index on @field is currently selected 
 *
 * Return value: %TRUE if item at @index is currently selected
 **/
gboolean
poppler_form_field_choice_is_item_selected (PopplerFormField *field,
					    gint              index)
{
  g_return_val_if_fail (field->widget->getType () == formChoice, FALSE);

  return static_cast<FormWidgetChoice*>(field->widget)->isSelected (index);
}

/**
 * poppler_form_field_choice_select_item:
 * @field: a #PopplerFormField
 * @index: the index of the item
 *
 * Selects the item at the given index on @field
 **/
void
poppler_form_field_choice_select_item (PopplerFormField *field,
				       gint              index)
{
  g_return_if_fail (field->widget->getType () == formChoice);

  static_cast<FormWidgetChoice*>(field->widget)->select (index);
}

/**
 * poppler_form_field_choice_unselect_all:
 * @field: a #PopplerFormField
 *
 * Unselects all the items on @field
 **/
void
poppler_form_field_choice_unselect_all (PopplerFormField *field)
{
  g_return_if_fail (field->widget->getType () == formChoice);

  static_cast<FormWidgetChoice*>(field->widget)->deselectAll ();
}

/**
 * poppler_form_field_choice_toggle_item:
 * @field: a #PopplerFormField
 * @index: the index of the item
 *
 * Changes the state of the item at the given index
 **/
void
poppler_form_field_choice_toggle_item (PopplerFormField *field,
				       gint              index)
{
  g_return_if_fail (field->widget->getType () == formChoice);

  static_cast<FormWidgetChoice*>(field->widget)->toggle (index);
}

/**
 * poppler_form_field_choice_toggle_item:
 * @field: a #PopplerFormField
 * @text: the new text
 *
 * Sets the text in @field to the given value, replacing the current contents
 **/
void
poppler_form_field_choice_set_text (PopplerFormField *field,
				    const gchar      *text)
{
  GooString *goo_tmp;
  gchar *tmp;
  gsize length = 0;

  g_return_if_fail (field->widget->getType () == formChoice);

  tmp = text ? g_convert (text, -1, "UTF16BE", "UTF8", NULL, &length, NULL) : NULL;
  goo_tmp = new GooString (tmp, length);
  g_free (tmp);
  static_cast<FormWidgetChoice*>(field->widget)->setEditChoice (goo_tmp);
  delete goo_tmp;
}

/**
 * poppler_form_field_choice_get_text:
 * @field: a #PopplerFormField
 *
 * Retrieves the contents of @field.
 *
 * Return value: a new allocated string. It must be freed with g_free() when done.
 **/
gchar *
poppler_form_field_choice_get_text (PopplerFormField *field)
{
  GooString *tmp;
  
  g_return_val_if_fail (field->widget->getType () == formChoice, NULL);

  tmp = static_cast<FormWidgetChoice*>(field->widget)->getEditChoice ();
  return tmp ? _poppler_goo_string_to_utf8 (tmp) : NULL;
}
