/*	Flip Tool

	(c) 1989 Blue Ribbon Bakery
*/

#include "/v.h"
#include <libraries/dos.h>
#include <exec/memory.h>
#include <string.h>
#include <intuition/intuition.h>

#define ID_FLIP	0x464C4950

static UWORD flip[] = { 
/*------ plane # 0: --------*/

  0x0,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x18,   0x0, 
  0x0,   0x0,
 /*------ plane # 1: --------*/

  0x0,   0x0, 
  0x0,   0x0, 
  0x0,   0x0, 
  0x200,   0x4000, 
  0xc700,   0x4300, 
  0xcf83,   0x5b00, 
  0xdac1,   0xf300, 
  0xc200,   0xe300, 
  0x200,   0x4000, 
  0x0,   0x0, 
  0x0,   0x0, 
  0x0,   0x0,
 /*------ plane # 2: --------*/

  0x0,   0x0, 
  0xfff,   0xf000, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0x3fff,   0xfc00, 
  0xfff,   0xf000, 
  0x0,   0x0};
 struct  Image flipimage =
 {
 0,0,
 24 , 12 , 3 ,
 &flip[0],
 0x1f,0x00,
 NULL,
 };
 
struct FlipTool {
    struct Tool tool;
    short axis;
};
 
extern struct Functions *functions;

static struct Event *processeventcode(event)

struct NoteEvent *event;

{
    struct FlipTool *tool = (struct FlipTool *) event->tool;
    short value;
    short center;
    char offset, offset2;
    if (!tool->tool.touched) {
	tool->axis = 60;
	tool->tool.touched = TOUCH_INIT;
    }
    event->tool = event->tool->next;
    if ((event->status == MIDI_NOTEON) || (event->status == MIDI_NOTEOFF) ||
	(event->status == MIDI_PTOUCH)) {
	value = (*functions->twelvetoscale)
	    (tool->tool.clip,event->time,event->value,&offset);
	center = (*functions->twelvetoscale)
	    (tool->tool.clip,event->time,tool->axis,&offset2);
	value = center - value;
	value = center + value;
	value = (*functions->scaletotwelve)(tool->tool.clip,event->time,value);
	value -= offset;
	while (value < 0) value += 12;
	while (value > 127) value -= 12;
	event->value = value;
    }
    event->next = 0;
    return(event);
}

extern struct NewWindow flipNewWindowStructure1;

void edittoolcode(tool)

struct FlipTool *tool;

{
    struct IntuiMessage *message;
    struct Window *window;
    long class, code;
    short octave, key;
    char string[10];
    static struct IntuiText itext = { 7,0,JAM2,0,0,NULL,0,0 };
    static char *convert[] = 
	{"C ","C#","D ","D#","E ","F ","F#","G ","G#","A ","A#","B "};
    struct Gadget *gadget;
    struct NewWindow *newwindow;
    flipNewWindowStructure1.Screen = functions->screen;
    if (tool->tool.touched & TOUCH_EDIT) {
	flipNewWindowStructure1.LeftEdge = tool->tool.left;
	flipNewWindowStructure1.TopEdge = tool->tool.top;
	flipNewWindowStructure1.Width = tool->tool.width;
	flipNewWindowStructure1.Height = tool->tool.height;
    }
    if (!tool->tool.touched) tool->axis = 60;
    newwindow = (struct NewWindow *) 
	(*functions->DupeNewWindow)(&flipNewWindowStructure1);
    if (!newwindow) return;
    window = (struct Window *) (*functions->FlashyOpenWindow)(newwindow);
    if (!window) return;
    tool->tool.window = window;
    for (;;) {
	itext.IText = convert[tool->axis % 12];
	PrintIText(window->RPort,&itext,82,21);
	(*functions->Itoa)(tool->axis / 12,string,10);
	itext.IText = string;
	PrintIText(window->RPort,&itext,120,21);
	message = (*functions->GetIntuiMessage)(window);
	class = message->Class;
	code = message->Code;
	gadget = (struct Gadget *) message->IAddress;
	ReplyMsg((struct Message *)message);
	if (class == CLOSEWINDOW) break;
	else if (class == GADGETDOWN) {
	    class = gadget->GadgetID;
	    switch (class) {
		case 1 :
		    key = (*functions->popupkey)(window,tool->axis % 12);
		    octave = tool->axis / 12;
		    code = (octave * 12) + key;
		    tool->axis = code;
		    break;
		case 2 :
		    octave = (*functions->popupoctave)(window,tool->axis / 12);
		    key = tool->axis % 12;
		    code = (octave * 12) + key;
		    tool->axis = code;
		    break;
	    }
	}
    }
    tool->tool.window = 0;
    tool->tool.left = window->LeftEdge;
    tool->tool.top = window->TopEdge;
    tool->tool.width = window->Width;
    tool->tool.height = window->Height;
    tool->tool.touched = TOUCH_INIT | TOUCH_EDIT;
    (*functions->FlashyCloseWindow)(window);
    (*functions->DeleteNewWindow)(newwindow);
}

static struct ToolMaster master;

extern long stdout;

struct ToolMaster *inittoolmaster()

{
    memset((char *)&master,0,sizeof(struct ToolMaster));
    master.toolid = ID_FLIP;
    master.image = &flipimage;
    strcpy(master.name,"Flip");
    master.edittool = edittoolcode;
    master.processevent = processeventcode;
    master.tooltype = TOOL_NORMAL;
    master.toolsize = sizeof(struct FlipTool);
    return(&master);
}
