/*
  area.c - A quick approach to handling areas of a window.
*/

#include <stdlib.h>

#include "err.h"
#include "fc.h"

#include "area.h"
#include "ticker.h"

/* ---------- Macros ---------- */
/* dclick_time is the number of ticks allowed for a doubleclick */
/* a tick is defined as one-sixtieth of a second */
#define DCLICK_TIME	20

/* ------------------------------------------------------------------------ */
struct area *
area_create(struct aop *aop, size_t dsize)
{
    struct area *ret;

    ret = calloc(sizeof(struct area) + dsize, 1);
    if (!ret) {
	do_error(ERR_NOMEM, "Can't create area.");
    }
    
    ret->aops = aop->aops;
    ret->bounds.x = aop->x;
    ret->bounds.y = aop->y;
    ret->bounds.width = aop->width;
    ret->bounds.height = aop->height;
    ret->owner = aop->owner;
    ret->click_ticks = 0;
    ret->data = ret + 1;
    return(ret);
}

/* ------------------------------------------------------------------------ */
void 
area_destroy(struct area *area)
{
     area->aops->term(area);
     free(area);
}

/* ------------------------------------------------------------------------ */
int 
area_mouse(struct area *area, XButtonEvent *bev)
{
    return(area->aops->mouse(area, bev));
}

/* ------------------------------------------------------------------------ */
int
area_draw(struct area *area, Region rgn)
{
    return(area->aops->draw(area, rgn));
}

/* ------------------------------------------------------------------------ */
int
area_resize(struct area *area, XConfigureEvent *cev)
{
    return(area->aops->resize(area, cev));
}

/* ------------------------------------------------------------------------ */
int 
area_key(struct area *area, XKeyEvent *kev)
{
    return(area->aops->key(area, kev));
}

/* ------------------------------------------------------------------------ */
int
area_activate(struct area *area, XMapEvent *mev)
{
    return(area->aops->activate(area, mev));
}

/* ------------------------------------------------------------------------ */
int
area_deactivate(struct area *area, XUnmapEvent *uev)
{
    return(area->aops->deactivate(area, uev));
}

/* ------------------------------------------------------------------------ */
int
area_containspoint(struct area *area, int x, int y)
{
     if (x > area->bounds.x &&
	 x < area->bounds.x + area->bounds.width &&
	 y > area->bounds.y &&
	 y < area->bounds.y + area->bounds.height) {
	  return(TRUE);
     }
     return(FALSE);
}
   
/* ---------------------------------------------------------------------- */
int
area_inrgn(struct area *area, Region rgn)
{
     return(rect_in_rgn(&area->bounds, rgn));
}

/* ---------------------------------------------------------------------- */
int
area_clearrect(struct area *ap, XRectangle *rp, int exposure)
{
     clear_rect(dpy, ap->owner, rp, exposure);
     return(0);
}

/* ---------------------------------------------------------------------- */
int
area_clear(struct area *ap)
{
     clear_rect(dpy, ap->owner, &ap->bounds, TRUE);
     return(0);
}

/* ---------------------------------------------------------------------- */
int
area_isdoubleclick(struct area *ap)
{
     return((get_tick_count() - ap->click_ticks) < DCLICK_TIME);
}

