/* $Revision Header *** Header built automatically - do not edit! ***********
 *
 *	(C) Copyright 1991 by Torsten Jürgeleit
 *
 *	Name .....: project.c
 *	Created ..: Sunday 22-Dec-91 21:22:52
 *	Revision .: 0
 *
 *	Date        Author                 Comment
 *	=========   ====================   ====================
 *	22-Dec-91   Torsten Jürgeleit      Created this file!
 *
 ****************************************************************************
 *
 *	Project part
 *
 * $Revision Header ********************************************************/

 /* Includes */

#include "includes.h"
#include "defines.h"
#include "imports.h"
#include "protos.h"

 /* Defines */

#define MOUSE_BUTTON_SELECT		(1 << 0)
#define MOUSE_BUTTON_MENU		(1 << 1)
#define MOUSE_BUTTON_RUBBER_BAND	(1 << 2)

#define PROJECT_TITLE_REFRESH_DELAY	500000		/* µs */

 /* Perform project action */

SHORT
perform_project_action(VOID)
{
	struct Box *box = &current_box;
	struct MsgPort *up = pwin->UserPort;
	struct IntuiMessage *msg;
	ULONG seconds = 0L, micros = 0L, last_seconds, last_micros;
	SHORT status = EDITOR_STATUS_NORMAL;

	while (msg = IGetMsg(up))
	{
		struct Template *tp;
		SHORT mouse_x, mouse_y, snap_x, snap_y;

		/* Get mouse position */
		mouse_x = msg->MouseX;
		mouse_y = msg->MouseY;
		snap_x = (mouse_x + (snap_offset >> 1)) / snap_offset * snap_offset;
		snap_y = (mouse_y + (snap_offset >> 1)) / snap_offset * snap_offset;
		switch (msg->Class)
		{
		case MOUSEBUTTONS:
			switch (msg->Code)
			{
			case SELECTDOWN:
				clear_template_info();
				switch (editor_mode)
				{
				case EDITOR_MODE_CREATE:
					box->bo_X1 = box->bo_X2 = snap_x;
					box->bo_Y1 = box->bo_Y2 = snap_y;
					mouse_button |= MOUSE_BUTTON_RUBBER_BAND;
					draw_box(pwin, box);
					break;

				case EDITOR_MODE_MODIFY:
					if (get_template_by_pos(mouse_x, mouse_y))
					{
						draw_box(pwin, box);
						last_snap_x = snap_x;
						last_snap_y = snap_y;
						modify_mode = get_modify_mode(mouse_x, mouse_y);
						mouse_button |= MOUSE_BUTTON_RUBBER_BAND;
						print_template_info();
					}
					break;

				case EDITOR_MODE_CLONE:
					if (get_template_by_pos(mouse_x, mouse_y))
					{
						draw_box(pwin, box);
						last_snap_x = snap_x;
						last_snap_y = snap_y;
						mouse_button |= MOUSE_BUTTON_RUBBER_BAND;
						print_template_info();
					}
					break;

				case EDITOR_MODE_DELETE:
				case EDITOR_MODE_EDIT:
					if (get_template_by_pos(mouse_x, mouse_y))
					{
						mouse_button |= MOUSE_BUTTON_RUBBER_BAND;
						print_template_info();
					}
					break;
				}
				mouse_button |= MOUSE_BUTTON_SELECT;
				if (editor_mode != EDITOR_MODE_USE)
				{
					print_project_window_title();
				}
				break;

			case SELECTUP:
				tp = selected_template;
				switch (editor_mode)
				{
				case EDITOR_MODE_CREATE:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						draw_box(pwin, box);
						box->bo_X2 = snap_x;
						box->bo_Y2 = snap_y;
						fix_template_bounds();
						end_rubber_banding();
					}
					break;

				case EDITOR_MODE_MODIFY:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						draw_box(pwin, box);
						clear_template_info();
						if (tp->tp_Flags & TEMPLATE_FLAG_MODIFIED)
						{
							tp->tp_Flags &= ~TEMPLATE_FLAG_MODIFIED;
							if (mouse_x < 0 || mouse_x > pwin->Width ||
								mouse_y < 0 || mouse_y > pwin->Height)
							{
								DisplayBeep((LONG) NULL);
							}
							else
							{
								if (modify_mode == MODIFY_MODE_MOVE)
								{
									box->bo_X1 += snap_x - last_snap_x;
									box->bo_Y1 += snap_y - last_snap_y;
									box->bo_X2 += snap_x - last_snap_x;
									box->bo_Y2 += snap_y - last_snap_y;
								}
								else
								{
									box->bo_X2 += snap_x - last_snap_x;
									box->bo_Y2 += snap_y - last_snap_y;
								}
								fix_template_bounds();
								end_rubber_banding();
							}
						}
					}
					break;

				case EDITOR_MODE_CLONE:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						draw_box(pwin, box);
						clear_template_info();
						if (mouse_x < 0 || mouse_x > pwin->Width ||
							mouse_y < 0 || mouse_y > pwin->Height)
						{
							DisplayBeep((LONG) NULL);
						}
						else
						{
							box->bo_X1 += snap_x - last_snap_x;
							box->bo_Y1 += snap_y - last_snap_y;
							box->bo_X2 += snap_x - last_snap_x;
							box->bo_Y2 += snap_y - last_snap_y;
							fix_template_bounds();
							end_rubber_banding();
						}
						tp->tp_Flags &= ~TEMPLATE_FLAG_MODIFIED;
					}
					break;

				case EDITOR_MODE_DELETE:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						clear_template_info();
						delete_template(selected_template);
					}
					break;

				case EDITOR_MODE_EDIT:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						info_template = NULL;
						info_displayed = FALSE;
						status = EDITOR_STATUS_EDIT;
					}
					break;
				}
				mouse_button &= ~(MOUSE_BUTTON_SELECT |
								  MOUSE_BUTTON_RUBBER_BAND);
				if (editor_mode != EDITOR_MODE_USE)
				{
					print_project_window_title();
					ActivateWindow(ewin);
				}
				break;

			case MENUDOWN:
				mouse_button |= MOUSE_BUTTON_MENU;
				break;

			case MENUUP:
				mouse_button &= ~MOUSE_BUTTON_MENU;
				ActivateWindow(ewin);
				break;
			}
			break;

		case MOUSEMOVE:
			if (mouse_button & MOUSE_BUTTON_SELECT)
			{

				/* Save time for project title refresh delay while rubberbanding */
				tp = selected_template;
				last_seconds = seconds;
				last_micros = micros;
				seconds = msg->Seconds;
				micros = msg->Micros;
				switch (editor_mode)
				{
				case EDITOR_MODE_CREATE:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						draw_box(pwin, box);
						box->bo_X2 = snap_x;
						box->bo_Y2 = snap_y;
						last_snap_x = snap_x;
						last_snap_y = snap_y;
						draw_box(pwin, box);
						if (seconds != last_seconds || (micros -
														last_micros) > PROJECT_TITLE_REFRESH_DELAY)
						{
							print_project_window_title();
						}
					}
					break;

				case EDITOR_MODE_MODIFY:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						draw_box(pwin, box);
						if (modify_mode == MODIFY_MODE_MOVE)
						{
							box->bo_X1 += snap_x - last_snap_x;
							box->bo_Y1 += snap_y - last_snap_y;
							box->bo_X2 += snap_x - last_snap_x;
							box->bo_Y2 += snap_y - last_snap_y;
						}
						else
						{
							box->bo_X2 += snap_x - last_snap_x;
							box->bo_Y2 += snap_y - last_snap_y;
						}
						last_snap_x = snap_x;
						last_snap_y = snap_y;
						draw_box(pwin, box);
						if (seconds != last_seconds || (micros -
														last_micros) > PROJECT_TITLE_REFRESH_DELAY)
						{
							print_project_window_title();
						}
						tp->tp_Flags |= TEMPLATE_FLAG_MODIFIED;
					}
					break;

				case EDITOR_MODE_CLONE:
					if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
					{
						draw_box(pwin, box);
						box->bo_X1 += snap_x - last_snap_x;
						box->bo_Y1 += snap_y - last_snap_y;
						box->bo_X2 += snap_x - last_snap_x;
						box->bo_Y2 += snap_y - last_snap_y;
						last_snap_x = snap_x;
						last_snap_y = snap_y;
						draw_box(pwin, box);
						if (seconds != last_seconds || (micros -
														last_micros) > PROJECT_TITLE_REFRESH_DELAY)
						{
							print_project_window_title();
						}
						tp->tp_Flags |= TEMPLATE_FLAG_MODIFIED;
					}
					break;

				case EDITOR_MODE_DELETE:
				case EDITOR_MODE_EDIT:
					if (selected_template)
					{

						/* Check if mouse points to selected template */
						if (find_template_by_pos(mouse_x, mouse_y) ==
							selected_template)
						{
							if (!(mouse_button & MOUSE_BUTTON_RUBBER_BAND))
							{
								mouse_button |= MOUSE_BUTTON_RUBBER_BAND;
								print_template_info();
								print_project_window_title();
							}
						}
						else
						{
							if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
							{
								mouse_button &= ~MOUSE_BUTTON_RUBBER_BAND;
								clear_template_info();
								print_project_window_title();
							}
						}
					}
					break;
				}
			}
			break;

		case NEWSIZE:
			refresh_all_templates();
			ActivateWindow(ewin);
			template_list.tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
			break;
		}
		IReplyMsg(msg);
	}
	return (status);
}

 /* End rubber banding */

STATIC VOID
end_rubber_banding(VOID)
{
	struct Box *box = &current_box;
	USHORT type, min_width, min_height, width = box->bo_X2 - box->bo_X1 + 1, height = box->bo_Y2 - box->bo_Y1 + 1;

	/* First get current template type */
	if (editor_mode == EDITOR_MODE_CREATE)
	{
		type = template_type;
	}
	else
	{
		type = selected_template->tp_Type;
	}

	/* Now calc minimal dimension required for template */
	switch (type)
	{
	case TEMPLATE_TYPE_SLIDER:
	case TEMPLATE_TYPE_SCROLLER:
	case TEMPLATE_TYPE_PALETTE:
		if (width / 2 > height)
		{
			min_width = min_dimension[type].dim_Width;
			min_height = min_dimension[type].dim_Height;
		}
		else
		{
			min_width = min_dimension[type].dim_Height * 2;
			min_height = min_dimension[type].dim_Width / 2;
		}
		break;

	default:
		min_width = min_dimension[type].dim_Width;
		min_height = min_dimension[type].dim_Height;
		break;
	}

	/* Check template dimension is greater than minimal */
	if (width < min_width || height < min_height)
	{
		DisplayBeep((LONG) NULL);
	}
	else
	{
		struct TemplateList *tl = &template_list;
		struct Template *tp;
		struct BorderData *bd;
		struct TextData *td;
		struct GadgetData *gd;

		switch (editor_mode)
		{
		case EDITOR_MODE_CREATE:
			tp = create_template(tl);
			display_template(tp);
			break;

		case EDITOR_MODE_MODIFY:
			tp = selected_template;
			CopyMem((BYTE *) box, (BYTE *)
					& tp->tp_Box, (LONG) sizeof(struct Box));
			/* Change template dimension */
			switch (type)
			{
			case TEMPLATE_TYPE_BORDER:
				bd = &tp->tp_Data.tp_BorderData;
				bd->bd_LeftEdge = box->bo_X1;
				bd->bd_TopEdge = box->bo_Y1;
				bd->bd_Width = width;
				bd->bd_Height = height;
				break;

			case TEMPLATE_TYPE_TEXT:
				td = &tp->tp_Data.tp_TextData;
				td->td_LeftEdge = box->bo_X1;
				td->td_TopEdge = box->bo_Y1;

				/* Calc size of text for template box */
				box = &tp->tp_Box;
				box->bo_X2 = box->bo_X1 + IPrintText(pri, pwin, td->td_Text,
													 td->td_LeftEdge, td->td_TopEdge, td->td_Type,
													 TEXT_DATA_FLAG_NO_PRINT, td->td_TextAttr) - 1;
				box->bo_Y2 = box->bo_Y1 + td->td_TextAttr->ta_YSize - 1;
				break;

			default:
				gd = &tp->tp_Data.tp_GadgetData;
				gd->gd_LeftEdge = box->bo_X1;
				gd->gd_TopEdge = box->bo_Y1;
				gd->gd_Width = width;
				gd->gd_Height = height;
				switch (gd->gd_Type)
				{
				case GADGET_DATA_TYPE_SLIDER:
					if (width / 2 < height)
					{
						gd->gd_Flags |= GADGET_DATA_FLAG_ORIENTATION_VERT;
					}
					else
					{
						gd->gd_Flags &= ~GADGET_DATA_FLAG_ORIENTATION_VERT;
					}
					break;

				case GADGET_DATA_TYPE_SCROLLER:
					if (width / 2 < height)
					{
						gd->gd_Flags |= GADGET_DATA_FLAG_ORIENTATION_VERT;
					}
					else
					{
						gd->gd_Flags &= ~GADGET_DATA_FLAG_ORIENTATION_VERT;
					}
					break;

				case GADGET_DATA_TYPE_PALETTE:
					if (width / 2 < height)
					{
						gd->gd_Flags |= GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP;
					}
					else
					{
						gd->gd_Flags &= ~GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP;
					}
					gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth = 2;
					gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset = 0;
					gd->gd_SpecialData.gd_PaletteData.gd_PaletteActiveColor = 2;
					break;
				}
				break;
			}
			refresh_all_templates();
			break;

		case EDITOR_MODE_CLONE:
			tp = clone_template(tl, selected_template, FALSE);
			display_template(tp);
			break;
		}
		template_list.tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
	}
}

 /* Print project window title */

VOID
print_project_window_title(VOID)
{
	struct Box *box = &current_box;
	BYTE *title = &project_window_title[0];
	USHORT width, height;

	if (box->bo_X2 > box->bo_X1)
	{
		width = box->bo_X2 - box->bo_X1 + 1;
	}
	else
	{
		width = box->bo_X1 - box->bo_X2 + 1;
	}
	if (box->bo_Y2 > box->bo_Y1)
	{
		height = box->bo_Y2 - box->bo_Y1 + 1;
	}
	else
	{
		height = box->bo_Y1 - box->bo_Y2 + 1;
	}
	switch (editor_mode)
	{
	case EDITOR_MODE_CREATE:
		if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
		{
			sprintf(title, " Left=%d Top=%d Width=%d Height=%d ",
					box->bo_X1, box->bo_Y1, width, height);
		}
		else
		{
			sprintf(title, " Create %s Template ",
					template_type_text_array[template_type]);
		}
		break;

	case EDITOR_MODE_MODIFY:
		if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
		{
			sprintf(title, " Left=%d Top=%d Width=%d Height=%d ",
					box->bo_X1, box->bo_Y1, width, height);
		}
		else
		{
			strcpy(title, " Modify Template ");
		}
		break;

	case EDITOR_MODE_DELETE:
		if (mouse_button & MOUSE_BUTTON_RUBBER_BAND)
		{
			sprintf(title, " Left=%d Top=%d Width=%d Height=%d ",
					box->bo_X1, box->bo_Y1, width, height);
		}
		else
		{
			strcpy(title, " Delete Template ");
		}
		break;

	case EDITOR_MODE_EDIT:
		strcpy(title, " Edit Template ");
		break;

	case EDITOR_MODE_USE:
		strcpy(title, " Use Templates ");
		break;
	}
	SetWindowTitles(pwin, title, (LONG) NULL);
}

 /* Start a new project */

SHORT
new_project(struct TemplateList *tl, USHORT new_flags)
{
	SHORT status;

	/* Free all templates */
	free_template_list(tl);
	ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
						 USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
	clear_template_info();

	/* Use default project name? */
	if (new_flags & TEMPLATE_LIST_FLAG_DEFAULT_WINDOW)
	{
		change_project_name(tl, DEFAULT_PROJECT_NAME, -1);
/*      strcpy(project_file_requester->fr_File, DEFAULT_PROJECT_FILE_NAME); */
	}

	/* Close old project window and open new one */
	if ((status = new_project_window(tl, new_flags)) == EDITOR_STATUS_NORMAL)
	{
		print_project_window_title();
	}
	show_error(status);
	return (status);
}

 /* Close old project window and open new one */

SHORT
new_project_window(struct TemplateList * tl, USHORT new_flags)
{
	struct NewWindow *nwin = &project_new_window;
	USHORT flags;
	SHORT status;

	/* Use default template list data? */
	if (new_flags & TEMPLATE_LIST_FLAG_DEFAULT_WINDOW)
	{
		nwin->LeftEdge = 0;
		nwin->TopEdge = ewin->Height + 1;
		nwin->Width = wb_screen.Width;
		nwin->Height = wb_screen.Height - nwin->TopEdge;
		new_flags = tl->tl_Flags = DEFAULT_TEMPLATE_LIST_FLAGS;
	}

	/* Change render info */
	if (pri)
	{
		IFreeRenderInfo(pri);
	}

	flags = PROJECT_RENDER_INFO_FLAGS |
		(new_flags & TEMPLATE_LIST_FLAG_BACK_FILL ? RENDER_INFO_FLAG_BACK_FILL : 0) |
		(new_flags & TEMPLATE_LIST_FLAG_AVAIL_FONTS ? RENDER_INFO_FLAG_AVAIL_FONTS : 0);

	if (!(pri = IGetRenderInfo((struct Screen *) NULL, flags)))
		status = EDITOR_ERROR_OUT_OF_MEM;
	else
	{
		/* Change new window structure */

		if (new_flags & TEMPLATE_LIST_FLAG_RENDER_COLORS)
			flags = PROJECT_OPEN_WINDOW_FLAGS | OPEN_WINDOW_FLAG_RENDER_PENS;
		else
			flags = PROJECT_OPEN_WINDOW_FLAGS;

		/* Open new project window */
		if (pwin)
			ICloseWindow(pwin, FALSE);

		if (!(pwin = IOpenWindow(pri, nwin, flags)))
			status = EDITOR_ERROR_NO_WINDOW;
		else
		{
			print_project_window_title();
			status = EDITOR_STATUS_NORMAL;
		}
	}

	show_error(status);
	return (status);
}

 /* Clear project window */

VOID
clear_project_window(USHORT flags)
{
	SetRast(pwin->RPort, 0L);
	RefreshWindowFrame(pwin);
	if (flags & TEMPLATE_LIST_FLAG_BACK_FILL)
	{
		IClearWindow(pri, pwin, 0, 0, (USHORT) - 1, (USHORT) - 1, 0);
	}
}

 /* Change project name and display it as window title */

VOID
change_project_name(struct TemplateList *tl, BYTE * new_name, SHORT len)
{
	BYTE *name = &tl->tl_ProjectName[0], *title = &editor_window_title[0];

	if (len < 0)
	{
		len = strlen(new_name);
	}
	if (len > MAX_PROJECT_NAME_LEN)
	{
		len = MAX_PROJECT_NAME_LEN;
	}

#ifdef LATTICE_50
	strncpy(name, new_name, (int) len);
#else
	strncpy(name, new_name, (size_t) len);
#endif

	*(name + len) = '\0';
	sprintf(title, " %s ", name);
	SetWindowTitles(ewin, title, (BYTE *) - 1L);
}
