/*-
 * Copyright (c) 2003 Seth Kingsley.  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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgment:
 *    This product includes software developed by Seth Kingsley and
 *    contributors.
 * 4. Neither the author's name, nor any of the contributors names may be
 *    used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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    <sys/cdefs.h>

#include    <gdk/gdk.h>
#include    <gtk/gtkcellrenderertext.h>

#ifdef DEBUG
#include    <err.h>
#endif /* DEBUG */

#include    <xmk-gtk.h>

#include    "portsman.h"
#include    "portcell.h"

#define MARGIN_HGT	1
#define MARGIN_LEFT	5
#define MARGIN_RIGHT	3
#define ARROW_ASPECT	1.0

__RCSID("$Id: portcell.c,v 1.9 2004/05/13 21:00:16 sethk Exp $");

enum
{
    PROP_0,
    PROP_PORT_STATE,
    PROP_LAST
};

static void
_pm_cell_renderer_port_set_property(GObject *object,
	guint prop_id,
	const GValue *value,
	GParamSpec *pspec)
{
    PMCellRendererPort	*cell_port = (PMCellRendererPort *)object;

    switch (prop_id)
    {
	case PROP_PORT_STATE:
	    cell_port->state = g_value_get_enum(value);
	    break;

	default:
	    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}

static void
_pm_cell_renderer_port_get_property(GObject *object,
	guint prop_id,
	GValue *value,
	GParamSpec *pspec)
{
    PMCellRendererPort	*cell_port = (PMCellRendererPort *)object;

    switch (prop_id)
    {
	case PROP_PORT_STATE:
	    g_value_set_enum(value, cell_port->state);
	    break;

	default:
	    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}

static void
_pm_cell_renderer_port_get_size(GtkCellRenderer *renderer,
	GtkWidget *wid,
	GdkRectangle *cell_area,
	gint *x_offset,
	gint *y_offset,
	gint *width,
	gint *height)
{
    GtkCellRendererClass    *parent_class =
	g_type_class_peek_parent(PM_CELL_RENDERER_PORT_GET_CLASS(renderer));
    PMCellRendererPort	    *rend_port = PM_CELL_RENDERER_PORT(renderer);

    parent_class->get_size(renderer,
	    wid,
	    cell_area,
	    x_offset, y_offset,
	    width, height);

    rend_port->arrow_rect.x = MARGIN_LEFT;
    rend_port->arrow_rect.y = MARGIN_HGT;
    rend_port->arrow_rect.height = *height - MARGIN_HGT * 2;
    rend_port->arrow_rect.width =
	rend_port->arrow_rect.height * ARROW_ASPECT + 1;

    rend_port->text_xoffset = MARGIN_LEFT +
	rend_port->arrow_rect.width +
	MARGIN_RIGHT;
    *width+= rend_port->text_xoffset;
}

static void
_pm_cell_renderer_port_render(GtkCellRenderer *renderer,
	GdkWindow *win,
	GtkWidget *widget,
	GdkRectangle *bg_area,
	GdkRectangle *cell_area,
	GdkRectangle *exp_area,
	GtkCellRendererState state)
{
    GtkCellRendererClass    *parent_class =
	g_type_class_peek_parent(PM_CELL_RENDERER_PORT_GET_CLASS(renderer));
    PMCellRendererPort	    *rend_port = PM_CELL_RENDERER_PORT(renderer);
    GdkRectangle	    text_area;
    gboolean		    filled = TRUE;

    state &= ~GTK_CELL_RENDERER_PRELIT;

    switch (rend_port->state)
    {
	GdkPoint    pts[4];

	case PSTATE_STALE:
	    filled = FALSE;
	    /*FALLTHROUGH*/
	case PSTATE_INST:
	    pts[0].x = pts[2].x = pts[3].x = cell_area->x +
		rend_port->arrow_rect.x;
	    pts[0].y = pts[3].y = cell_area->y + rend_port->arrow_rect.y;
	    pts[1].x = cell_area->x + rend_port->arrow_rect.x +
		rend_port->arrow_rect.width;
	    pts[1].y = cell_area->y + rend_port->arrow_rect.y +
		(rend_port->arrow_rect.height + 1) / 2;
	    pts[2].y = cell_area->y + rend_port->arrow_rect.y +
		rend_port->arrow_rect.height;
	    gdk_draw_polygon(win,
		    widget->style->fg_gc[state],
		    filled,
		    pts,
		    sizeof(pts) / sizeof(pts[0]));
	    break;

	default:
	    break;
    }

    text_area.x = cell_area->x + rend_port->text_xoffset;
    text_area.y = cell_area->y;
    text_area.width = cell_area->width - rend_port->text_xoffset;
    text_area.height = cell_area->height;
    parent_class->render(renderer,
	    win,
	    widget,
	    bg_area,
	    &text_area,
	    exp_area,
	    state);
}

static void
_pm_cell_renderer_port_class_init(PMCellRendererPortClass *class)
{
    GtkCellRendererClass    *renderer_class = GTK_CELL_RENDERER_CLASS(class);
    GObjectClass	    *gobject_class = (GObjectClass *)class;

    gobject_class->get_property = _pm_cell_renderer_port_get_property;
    gobject_class->set_property = _pm_cell_renderer_port_set_property;
    renderer_class->get_size = _pm_cell_renderer_port_get_size;
    renderer_class->render = _pm_cell_renderer_port_render;

    g_object_class_install_property(gobject_class,
	    PROP_PORT_STATE,
	    g_param_spec_enum("port-state",
		"Port State",
		"The installed/uninstalled state of this port",
		PM_TYPE_PORT_STATE,
		PSTATE_UNINST,
		G_PARAM_READABLE | G_PARAM_WRITABLE));
}

GType
pm_cell_renderer_port_get_type(void)
{
    static GType    cell_port_type = 0;

    if (!cell_port_type)
    {
	static const GTypeInfo	cell_port_info =
	{
	    sizeof(PMCellRendererPortClass),
	    NULL,	    /* base_init */
	    NULL,	    /* base_finalize */
	    (GClassInitFunc)_pm_cell_renderer_port_class_init,
	    NULL,	    /* class_finalize */
	    NULL,	    /* class_data */
	    sizeof(PMCellRendererPort),
	    0,		    /* n_preallocs */
	    NULL
	};

	cell_port_type = g_type_register_static(GTK_TYPE_CELL_RENDERER_TEXT,
		"PMCellRendererPort",
		&cell_port_info,
		0);
    }
    return cell_port_type;
}

GtkCellRenderer *
pm_cell_renderer_port_new(void)
{
    return g_object_new(PM_TYPE_CELL_RENDERER_PORT, NULL);
}

