/*
 *                 GRAPH, Version 1.00 - 4 August 1989
 *
 *            Copyright 1989, David Gay. All Rights Reserved.
 *            This software is freely redistrubatable.
 */

#include <exec/types.h>
#include <graphics/text.h>
#include <math.h>

#include "object.h"
#include "object/default.h"
#include "uio.h"
#include "grph.h"
#include "coords.h"
#include "tracker.h"

#include <proto/exec.h>
#include <proto/graphics.h>

/*-------------------------------------------------------------------------*/
/*                        pos class implementation                         */
/*-------------------------------------------------------------------------*/

/* Size of cross */
#define XCROSS 3
#define YCROSS 3

/* Redraw cross/rect */
static void draw_pos(struct pos *this, int allow_mes)
{
    struct graph *g = this->o.g;
    struct RastPort *rp = g->io.rw->rp;

    SetDrMd(rp, COMPLEMENT);
    if (this->cross) /* Draw cross */
    {
        RMove(g->io.rw, this->x0, this->y0);
        Move(rp, rp->cp_x - XCROSS, rp->cp_y);
        Draw(rp, rp->cp_x + 2 * XCROSS, rp->cp_y);
        Move(rp, rp->cp_x - XCROSS, rp->cp_y - YCROSS);
        Draw(rp, rp->cp_x, rp->cp_y + 2 * YCROSS);
    }
    if (this->rect) /* Draw rectangle */
    {
        long const sx0 = ftol(g->io.rw->sx(g->io.rw, this->x0));
        long const sx1 = ftol(g->io.rw->sx(g->io.rw, this->x1));
        long const sy0 = ftol(g->io.rw->sy(g->io.rw, this->y0));
        long const sy1 = ftol(g->io.rw->sy(g->io.rw, this->y1));
        long c1 = ReadPixel(rp, sx0, sy0);
        long c2 = ReadPixel(rp, sx0, sy1);
        long c3 = ReadPixel(rp, sx1, sy0);
        long c4 = ReadPixel(rp, sx1, sy1);

        Move(rp, sx0, sy0);
        Draw(rp, sx1, sy0);
        Draw(rp, sx1, sy1);
        Draw(rp, sx0, sy1);
        Draw(rp, sx0, sy0);
        /* Had problems with the corners ... */
        if (c1 == ReadPixel(rp, sx0, sy0)) WritePixel(rp, sx0, sy0);
        if (c2 == ReadPixel(rp, sx0, sy1)) WritePixel(rp, sx0, sy1);
        if (c3 == ReadPixel(rp, sx1, sy0)) WritePixel(rp, sx1, sy0);
        if (c4 == ReadPixel(rp, sx1, sy1)) WritePixel(rp, sx1, sy1);
    }
}

/* The object exists only to be "selected" --> */
/* This actually deletes the object !!! */
static struct Region *deselect_pos(struct pos *this)
{
    if (this->o.g->ok && this->o.g->io.rw) draw_pos(this, TRUE); /* erase */
    FreeMem(this, sizeof(struct pos));
    return NULL;
}

static int down_pos(struct pos *this)
{
    return FALSE; /* You can never select a 'pos' */
}

/* Move, ie define rectangle */
static void move_pos(struct pos *this)
{
    draw_pos(this, TRUE);   /* erase old */
    this->x1 = this->o.g->s.x;
    this->y1 = this->o.g->s.y;
    this->cross = FALSE; this->rect = TRUE; /* Not a cross any more */
    draw_pos(this, TRUE);   /* draw new */
}

/* Rectangle is now defined */
static struct Region *up_pos(struct pos *this)
{
    draw_pos(this, TRUE);
    this->x1 = this->o.g->s.x;
    this->y1 = this->o.g->s.y;
    draw_pos(this, TRUE);

    return NULL;
}

/* Create a rectangle/cross (starts off as a cross) */
struct pos *new_pos(struct graph *g)
{
    struct pos *this;
    const static struct pos def_p = {
        {
            { NULL },
            NULL, "", TRUE, 0, 0,
            (void *)uncalled, (void *)uncalled, (void *)deselect_pos, (void *)d
own_pos, (void *)move_pos, (void *)up_pos, (void *)uncalled, (void *)draw_pos, (
void *)uncalled, (void *)uncalled, (void *)uncalled, (void *)uncalled, (void *)u
ncalled,
            (void *)uncalled
        },
        TRUE, FALSE
    };

    if (g->ok && g->io.rw)
        if (this = AllocMem(sizeof(struct pos), 0L))
        {
            *this = def_p;
            this->o.g = g;
            this->x0 = this->x1 = g->s.x;
            this->y0 = this->y1 = g->s.y;
            draw_pos(this, TRUE); /* draw it */

            return this;
        }
        else message(g, "No memory !", (char *)NULL);
    else message(g, "No scale set", (char *)NULL);
    return NULL;
}

