#include <stdlib.h>
#include <gtk/gtk.h>

static double bx=200.0, by=350.0, cx=400.0, cy=50.0;
static GdkRectangle gdr = {0,0,600, 400};
static GtkWidget* darea=NULL;

double eval(double  a, double b, double c, double d, double frac)
{
    double frac2, onemf, onemf2, retval;

    frac = CLAMP(frac ,0.0, 1.0);
    frac2 = frac*frac;
    onemf = 1.0 -frac;
    onemf2 = onemf * onemf;

    retval = a * onemf2 *onemf;
    retval += 3.0  * onemf2 * frac * b;
    retval += 3.0  * onemf  * frac2 * c;
    retval += d * frac2 *frac;

    return retval;
}

void cb_change_val(GtkAdjustment *adj, double *dp )
{
    *dp = adj->value;
    gdr.height = darea->allocation.height;
    gdr.width =darea->allocation.width;
    gdk_window_invalidate_rect(darea->window, &gdr, TRUE);




}

gboolean
expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
    int ii, x1=0,y1=0, x2,y2;
    gdk_draw_point( widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], cx,cy);
    gdk_draw_point( widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], bx,by);

    for (ii=1 ;ii <=24; ii++)
    {
        x2 = eval ( 0.0, (double)bx, (double) cx, (double) widget->allocation.width-1, ii/24.0);
        y2 = eval ( 0.0, (double)by, (double) cy, (double) widget->allocation.height-1, ii/24.0);
        gdk_draw_line( widget->window,
                       widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                       x1, y1, x2, y2);
        x1=x2, y1=y2;
    }
    return TRUE;
}

int main (int argc, char *argv[])
{
    GtkWidget *win = NULL;
    GtkObject *adj;
    GtkWidget *table;
    GtkWidget *scale;



    /* Initialize GTK+ */
    gtk_init (&argc, &argv);

    /* Create the main window */
    win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width (GTK_CONTAINER (win), 8);
    gtk_window_set_title (GTK_WINDOW (win), "Tutorial in drawing");
    gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
    g_signal_connect (win, "destroy", gtk_main_quit, NULL);
    table = gtk_table_new(3,3,FALSE);
    gtk_container_add(GTK_CONTAINER(win), table);
    darea = gtk_drawing_area_new();
    gtk_widget_set_size_request (darea, 600, 400);
    gtk_table_attach_defaults (GTK_TABLE(table), darea, 0, 1, 0, 1);
    g_signal_connect (G_OBJECT (darea), "expose_event",
                      G_CALLBACK (expose_event_callback), NULL);
    adj = gtk_adjustment_new( bx, 0.0, 600.0, 0.1, 10.0, 0.0);
    scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
    gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_LEFT);
    gtk_table_attach(GTK_TABLE(table), scale, 0, 1, 1, 2,GTK_EXPAND|GTK_FILL, GTK_FILL, 0,0 );
    g_signal_connect(G_OBJECT (adj), "value-changed", G_CALLBACK(cb_change_val), (gpointer) &bx);

    adj = gtk_adjustment_new( by, 0.0, 400.0, 0.1, 10.0, 0.0);
    scale = gtk_vscale_new(GTK_ADJUSTMENT(adj));
    gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
    gtk_table_attach (GTK_TABLE(table), scale, 1, 2, 0, 1, GTK_FILL, GTK_FILL|GTK_EXPAND, 0,0);
    g_signal_connect(G_OBJECT (adj), "value-changed", G_CALLBACK(cb_change_val), (gpointer) &by);

    adj = gtk_adjustment_new( cx, 0.0, 600.0, 0.1, 10.0, 0.0);
    scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
    gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_LEFT);
    gtk_table_attach (GTK_TABLE(table), scale, 0, 1, 2, 3, GTK_FILL| GTK_EXPAND, GTK_FILL,0,0);
    g_signal_connect(G_OBJECT (adj), "value-changed", G_CALLBACK(cb_change_val), (gpointer) &cx);

    adj = gtk_adjustment_new( cy, 0.0, 400.0, 0.1, 10.0, 0.0);
    scale = gtk_vscale_new(GTK_ADJUSTMENT(adj));
    gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_LEFT);
    gtk_table_attach (GTK_TABLE(table), scale, 2, 3, 0, 1, GTK_FILL, GTK_FILL|GTK_EXPAND, 0,0);
    g_signal_connect(G_OBJECT (adj), "value-changed", G_CALLBACK(cb_change_val), (gpointer) &cy);


    gtk_widget_show_all(win);
    gtk_main ();
    return 0;
}
