/* :ts=8 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "general.h"
#include "globals.h"
#include "intui.h"
#include "normal.h"
#include "spl_math.h"
#include "spl_util.h"
#include "spl_gfx.h"
/************************************************************************/
/*                                                                      */
/* This file contains code to handle the GROUP command.			*/
/*                                                                      */
/************************************************************************/

static short		Group_View_Id;
static short		Group_X1;
static short		Group_Y1;
static short		Group_X2;
static short		Group_Y2;
static Boolean_T	Group_Active;

static 
void  Group_Select_Up()
/************************************************************************/
/*                                                                      */
/* This function is called when selection of a group is finished.	*/
/* The selection is given by the area (Group_X1, Group_Y1) ->		*/
/* (Group_X2, Group_Y2) in the view given by Group_View_Id.		*/
/*                                                                      */
/************************************************************************/
{
    short	i;
    Vector_T	Pos1, Pos2;

    if (!Group_Active) return;
    if (Group_X1 == Group_X2 || Group_Y1 == Group_Y2) return;

    /* Remove the selection box */
    if (Group_X2 < Group_X1) {
       i        = Group_X1;
       Group_X1 = Group_X2;
       Group_X2 = i;
    }
    if (Group_Y2 < Group_Y1) {
       i        = Group_Y1;
       Group_Y1 = Group_Y2;
       Group_Y2 = i;
    }
    Move(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y1);
    Draw(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y2);
    Draw(Windows[Id_Active_Window].RastPort, Group_X2, Group_Y2);
    Draw(Windows[Id_Active_Window].RastPort, Group_X2, Group_Y1);
    Draw(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y1);

    Screen_To_World(Group_X1, Group_Y1, Pos1);
    Screen_To_World(Group_X2, Group_Y2, Pos2);

    Select_Area(Group_View_Id, Pos1, Pos2);
    Set_Window_Title(NULL);

    Set_Mode_Normal();
    Redraw_Mask |= What_K;

} /* Group_Group_Select_Up */

static 
void  Group_Select_Down(short X, short Y)
/************************************************************************/
/*                                                                      */
/* Function called when mouse is moved to select a group.		*/
/* X, Y are the actual coordinates in the active window 'Win'.		*/
/*                                                                      */
/************************************************************************/
{
    Vector_T	  Pos;

    Group_View_Id = Screen_To_World(X, Y, Pos);
    if (Group_View_Id < 0) return;

    Group_Active = TRUE;

    Group_X2 = Group_X1 = X;
    Group_Y2 = Group_Y1 = Y;

    Windows[Id_Active_Window].RastPort->Mask    = 0x01;
    SetDrMd(Windows[Id_Active_Window].RastPort, COMPLEMENT);

} /* Group_Select_Down */

static 
void  Group_Move(short X, short Y)
/************************************************************************/
/*                                                                      */
/* Function called when mouse is moved to select a group.		*/
/* X, Y are the actual coordinates in the active window 'Win'.		*/
/*                                                                      */
/************************************************************************/
{
    Vector_T	  Pos;
    short	  View_Id;

    if (!Group_Active) return;

    View_Id = Screen_To_World(X, Y, Pos);
    if (View_Id != Group_View_Id) return;

    /* Remove old selection box */

    if (Group_X1 != Group_X2 && Group_Y1 != Group_Y2) {

        Move(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y1);
        Draw(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y2);
        Draw(Windows[Id_Active_Window].RastPort, Group_X2, Group_Y2);
        Draw(Windows[Id_Active_Window].RastPort, Group_X2, Group_Y1);
        Draw(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y1);

    } /* if */


    Group_X2 = X;
    Group_Y2 = Y;

    /* Draw new selection box */

    if (Group_X1 != Group_X2 && Group_Y1 != Group_Y2) {

        Move(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y1);
        Draw(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y2);
        Draw(Windows[Id_Active_Window].RastPort, Group_X2, Group_Y2);
        Draw(Windows[Id_Active_Window].RastPort, Group_X2, Group_Y1);
        Draw(Windows[Id_Active_Window].RastPort, Group_X1, Group_Y1);

    } /* if */

} /* Group_Move */


static
Boolean_T Group_Handle_Event(struct IntuiMessage *Msg)
/************************************************************************/
/*                                                                      */
/* Event handler routine for the 'ADD' mode.				*/
/* Events handled:							*/
/*	Select down: Start mark group.					*/
/*	Select up: End mark group.					*/
/*	Mousemove: Change group area.					*/
/*                                                                      */
/************************************************************************/
{

    switch (Msg->Class) {


    case IDCMP_MOUSEBUTTONS:
		/* Msg->Code contain id of button pressed 		*/
		/* Msg->MouseX and Msg->MouseY contain mouse position 			*/

	switch(Msg->Code) {

	case SELECTDOWN:
	    Group_Select_Down(Msg->MouseX, Msg->MouseY);
	    return(TRUE);

	case SELECTUP:
	    Group_Select_Up();
	    return(TRUE);

	} /* switch (Msg->Code) */
	break;

    case IDCMP_MOUSEMOVE:
        Group_Move(Msg->MouseX, Msg->MouseY);
	return(TRUE);

    } /* switch (Msg->Class) */

    return(FALSE);

} /* Group_Handle_Event */

void Set_Mode_Group()
/************************************************************************/
/*                                                                      */
/* Change to GROUP mode.						*/
/*                                                                      */
/************************************************************************/
{
    Group_Active		= FALSE;
    State.Handle_Event		= Group_Handle_Event;
    State.Redraw		= Normal_Redraw;

    Display_Status("Group");


} /* Set_Mode_Group */
