/*
 * Copyright (c) 2002, 2003, 2004 Jean-Yves Lefort
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <gtk/gtk.h>
#include "st-handler-field.h"

/*** type definitions ********************************************************/

struct _STHandlerFieldPrivate
{
  GType			type;
  char			*label;
  STHandlerFieldFlags	flags;
  char			*description;

  gboolean		user_visible;
  int			width;
  int			position;
};

/*** API implementation ******************************************************/

/**
 * st_handler_field_new:
 * @id: the numeric ID of the field. Handler fields must be numbered
 * from 0 to n_fields - 1.
 * @label: the field label.
 * @type: the field type. Must be #G_TYPE_BOOLEAN, #G_TYPE_INT,
 * #G_TYPE_UINT, #G_TYPE_DOUBLE, #G_TYPE_STRING, or, if the
 * #ST_HANDLER_FIELD_EDITABLE flag is not set, #GDK_TYPE_PIXBUF or
 * #G_TYPE_VALUE_ARRAY.
 * @flags: the field flags.
 *
 * Creates a new #STHandlerField.
 *
 * Return value: the newly created #STHandlerField.
 **/
STHandlerField *
st_handler_field_new (int id,
		      const char *label,
		      GType type,
		      STHandlerFieldFlags flags)
{
  STHandlerField *field;

  g_return_val_if_fail(label != NULL, NULL);
  g_return_val_if_fail(type == G_TYPE_BOOLEAN
		       || type == G_TYPE_INT
		       || type == G_TYPE_UINT
		       || type == G_TYPE_DOUBLE
		       || type == G_TYPE_STRING
		       || ((flags & ST_HANDLER_FIELD_EDITABLE) == 0
			   && (type == GDK_TYPE_PIXBUF
			       || type == G_TYPE_VALUE_ARRAY)), NULL);
  
  field = g_new(STHandlerField, 1);
  field->id = id;

  field->priv = g_new(STHandlerFieldPrivate, 1);
  field->priv->type = type;
  field->priv->label = g_strdup(label);
  field->priv->flags = flags;
  field->priv->description = NULL;
  field->priv->user_visible = (field->priv->flags & ST_HANDLER_FIELD_START_HIDDEN) == 0;
  field->priv->width = ST_HANDLER_FIELD_DEFAULT_WIDTH;
  field->priv->position = -1;

  return field;
}

/**
 * st_handler_field_get_type:
 * @field: a field.
 *
 * Gets the value type of @field.
 *
 * Return value: the type of value held by @field.
 **/
GType
st_handler_field_get_type (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, -1);

  return field->priv->type;
}

/**
 * st_handler_field_get_label:
 * @field: a field.
 *
 * Gets the label of @field.
 *
 * Return value: the label of @field.
 **/
const char *
st_handler_field_get_label (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, NULL);
  
  return field->priv->label;
}

/**
 * st_handler_field_get_flags:
 * @field: a field.
 *
 * Gets the flags of @field.
 *
 * Return value: the flags of @field.
 **/
STHandlerFieldFlags
st_handler_field_get_flags (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, 0);

  return field->priv->flags;
}

/**
 * st_handler_field_set_description:
 * @field: a field.
 * @description: the field description, or %NULL to unset.
 *
 * Sets the description of @field.
 **/
void
st_handler_field_set_description (STHandlerField *field,
				  const char *description)
{
  g_return_if_fail(field != NULL);

  g_free(field->priv->description);
  field->priv->description = g_strdup(description);
}

/**
 * st_handler_field_get_description:
 * @field: a field.
 *
 * Gets the description of @field.
 *
 * Return value: the description of @field, or %NULL if not set.
 **/
const char *
st_handler_field_get_description (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, NULL);
  
  return field->priv->description;
}

/*** private implementation **************************************************/

STHandlerField *
st_handler_field_new_dummy (void)
{
  STHandlerField *field;

  field = g_new0(STHandlerField, 1);

  field->priv = g_new0(STHandlerFieldPrivate, 1);
  field->priv->flags = ST_HANDLER_FIELD_VISIBLE;
  field->priv->user_visible = TRUE;
  field->priv->width = ST_HANDLER_FIELD_DEFAULT_WIDTH;
  field->priv->position = -1;

  return field;
}

void
st_handler_field_set_user_visible (STHandlerField *field,
				   gboolean user_visible)
{
  g_return_if_fail(field != NULL);

  field->priv->user_visible = user_visible;
}

gboolean
st_handler_field_get_user_visible (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, FALSE);

  return field->priv->user_visible;
}

void
st_handler_field_set_width (STHandlerField *field, int width)
{
  g_return_if_fail(field != NULL);

  field->priv->width = width;
}

int
st_handler_field_get_width (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, -1);

  return field->priv->width;
}

void
st_handler_field_set_position (STHandlerField *field, int position)
{
  g_return_if_fail(field != NULL);

  field->priv->position = position;
}

int
st_handler_field_get_position (STHandlerField *field)
{
  g_return_val_if_fail(field != NULL, -1);

  return field->priv->position;
}
