/* :ts=8 */
/************************************************************************/
/*                                                                      */
/* This file contains code to handle the NORMAL mode.			*/
/*                                                                      */
/************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "general.h"
#include "globals.h"
#include "intui.h"
#include "spl_math.h"
#include "spl_util.h"
#include "spl_gfx.h"
#include "commands.h"
#include "render.h"
#include "move.h"
#include "group.h"
#include "pan.h"
#include "normal.h"

void Normal_Redraw(long What)
/************************************************************************/
/*                                                                      */
/* Function normally called to redraw the screen:			*/
/* Clear all windows and draw everything again.				*/
/*                                                                      */
/************************************************************************/
{
    if (What & What_S) Clear_All(What_All);
    Draw_All(What);

} /* Normal_Redraw */

static 
void  Normal_Select_Down(short X, short Y)
/************************************************************************/
/*                                                                      */
/* This function is called when the user activates the select button	*/
/* in normal mode, ie. to select/move a knot.				*/
/*                                                                      */
/************************************************************************/
{
    short	Point_Id;

    Select_View_Id = Screen_To_World(X, Y, Current_Pos);
    if (Select_View_Id < 0) return;

    Point_Id = Point_Find(Current_Pos,  Select_View_Id);
    if (Point_Id < 0) {

	/* We don't need a selected point to move in group mode: */
	if (Group_Mode) Set_Mode_Move(X, Y);
	return;

    } /* if */

    Vec2Op(Current_Pos, =, Points[Point_Id].Pos);

    if (Select_Point_Id != Point_Id) { /* Select another point 	*/

	if (Select_Point_Id != -1) {   /* Deselect previous	*/

	    if (!Group_Mode) Deselect_All();

    	    Draw_Marked_Segments(DM_Normal, What_S);

	} /* if */

	Select_Point(Point_Id);

	Set_Move_Group_Position(Points[Select_Point_Id].Pos);
	KnotInfo_Show_Info(Select_Spline, Select_Knot);
        Set_Window_Title(NULL);

    }

    Set_Mode_Move(X, Y);
    return;

} /* Normal_Select_Down */

static
void Normal_Timeout()
/************************************************************************/
/*                                                                      */
/* Handle timeout in normal mode.					*/
/*                                                                      */
/************************************************************************/
{
	/* The default timeout action: Don't do anything */
} /* Normal_Timeout */

static
Boolean_T Normal_Handle_Event(struct IntuiMessage *Msg)
/************************************************************************/
/*                                                                      */
/* Event handler routine for the 'NORMAL' mode.				*/
/*                                                                      */
/* Events handled:							*/
/*	Select down: Select or move a knot.				*/
/* 	Up arrow:							*/
/* 	And lots of other keys... ########				*/
/*                                                                      */
/************************************************************************/
{

    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:
	    Normal_Select_Down(Msg->MouseX, Msg->MouseY);
	    return(TRUE);

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

    case IDCMP_RAWKEY:
	switch (Msg->Code) { /* Msg->Code contain RAW keycode	*/

	case 0x4c:					/* Up arrow	*/
	    Command_Pan_Up();
	    return(TRUE);

	case 0x4d:					/* Down arrow	*/
	    Command_Pan_Down();
	    return(TRUE);

	case 0x4e:					/* Right arrow	*/
	    Command_Pan_Right();
	    return(TRUE);

	case 0x4f:					/* Left arrow	*/
	    Command_Pan_Left();
	    return(TRUE);

	case 0x50:					/* F1        	*/
	case 0x51:					/* F2        	*/
	case 0x52:					/* F3        	*/
	case 0x53:					/* F4        	*/
	case 0x54:					/* F5        	*/
	case 0x55:					/* F6        	*/
	case 0x56:					/* F7        	*/
	case 0x57:					/* F8        	*/
	case 0x58:					/* F9        	*/
	case 0x59:					/* F10       	*/
	case 0x5f:					/* Help      	*/
	    return(TRUE);

	} /* switch */
        return(FALSE);

    case IDCMP_VANILLAKEY:
	switch (Msg->Code) { /* Msg->Code contain ASCII code	*/

	case 'L':					/* L	*/
	    Command_Load_JMan_Object();
	    return(TRUE);

	case 'a':					/* a	*/
	    Command_Add();
	    return(TRUE);

	case 'c':					/* c	*/
	    Command_Cut();
	    return(TRUE);

	case 'C':					/* C	*/
	    Command_Combine();
	    return(TRUE);

	case 'd':					/* d	*/
	    Command_Delete();
	    return(TRUE);

	case 'D':					/* D	*/
	    Command_Disconnect();
	    return(TRUE);

	case 'h':					/* h	*/
	    Command_Hide();
	    return(TRUE);

	case 'H':					/* H	*/
	    Command_Show();
	    return(TRUE);

	case 'l':					/* l	*/
	    Command_Loop();
	    return(TRUE);

	case 'n':					/* n	*/
	    Command_Select_Next();
	    return(TRUE);

	case 'g':					/* g	*/
	    Set_Mode_Group();
	    return(TRUE);

	case 'p':					/* p	*/
	    Set_Mode_Pan();
	    return(TRUE);

	case '-':					/* -	*/
	    Command_Resolution_Down();
	    return(TRUE);

	case '+':					/* +	*/
	    Command_Resolution_Up();
	    return(TRUE);
	
	case '.':
	    Command_Toggle_Select_All();
	    break;

	case ',':
	    Command_Toggle_Select_Spline();
	    break;

	case ';':
	    if (Select_Point_Id >= 0) {
		Group_Mode = TRUE;
		Set_Window_Title(NULL);
	    }	
	    break;

	case 'r': 					/* r: Render */
    	    Render_Tesselate_Object();
    	    return(TRUE);

	case 'R': 					/* R: ReRender */
    	    Render_Object();
    	    return(TRUE);

	case '\r':
	case '\n':
	    Command_Deselect_All();
	    return(TRUE);
	
	case 12:					/* Ctrl+L	*/
	    Compute_Splines();
            Redraw_Mask |= What_All;
	    break;

	case ' ':					/* Space	*/
	    Command_Redraw();
	    return(TRUE);

	default:
	    return(FALSE);

        } /* switch */
        break;

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

    return(FALSE);

} /* Normal_Handle_Event */

void Set_Mode_Normal()
/************************************************************************/
/*                                                                      */
/* Change to NORMAL mode.						*/
/*                                                                      */
/************************************************************************/
{
    State.Handle_Event		= Normal_Handle_Event;
    State.Timeout		= Normal_Timeout;
    State.Redraw		= Normal_Redraw;

    Mark_Selected_Segments();
    Display_Status(NULL);

} /* Set_Mode_Normal */
