/*
	CMameView.cc
	The BeMAME Team
	Created: 07/15/99 09:30:26
*/

#include "CMameView.h"

#include <AppDefs.h>
#include <Message.h>
#include <Window.h>
#include <WindowScreen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Up/Down status of mouse buttons
// These cannot be my_view members as beos_read_key()
//  is called before the my_view class is instantiated.
//  (inptport.c, update_input_ports() )
bool CMameView::sMB[3] = { false, false, false };
bool CMameView::s1stMouseRead;
bool CMameView::sQuit = false;
char CMameView::sKey[eKey_Max];

//
// Constructor
//
CMameView::CMameView(
	BRect			inFrame) : BView(inFrame, "MAMEView", B_FOLLOW_ALL, 0)
{
	s1stMouseRead = true;

	// Initialise all keys to released state
	memset(sKey, '\0', sizeof(sKey));
}

CMameView::~CMameView()
{
}

//
// Update key[] with any keypresses
//

void CMameView::KeyDown(
	const char		*inBytes,
	int32			inNumBytes)
{
	if (inNumBytes == 1) {
		if (inBytes[0] >= '0' && inBytes[0] <= '9')
			sKey[eKey_0 + inBytes[0] - '0'] = 1;
		else if (inBytes[0] >= 'A' && inBytes[0] <= 'Z')
			sKey[eKey_A + inBytes[0] - 'A'] = 1;
		else if (inBytes[0] >= 'a' && inBytes[0] <= 'z')
			sKey[eKey_A + inBytes[0] - 'a'] = 1;
		else {
			switch (inBytes[0]) {
				case B_ENTER:		sKey[eKey_Enter]		= 1;		break;
				case B_TAB:			sKey[eKey_Tab]			= 1;		break;
				case B_SPACE:		sKey[eKey_Space]		= 1;		break;
				case B_ESCAPE:		sKey[eKey_Escape]		= 1; sQuit= true; break;
				case B_LEFT_ARROW:	sKey[eKey_Left]			= 1;		break;
				case B_RIGHT_ARROW:	sKey[eKey_Right]		= 1;		break;
				case B_UP_ARROW:	sKey[eKey_Up]			= 1;		break;
				case B_DOWN_ARROW:	sKey[eKey_Down]			= 1;		break;
				case ',':			sKey[eKey_Comma]		= 1;		break;
				case '.':			sKey[eKey_Period]		= 1;		break;
				
//				case '-': osd_set_mastervolume(osd_get_mastervolume()-5);	break;
//				case '+': osd_set_mastervolume(osd_get_mastervolume()+5);	break;
				
				case B_FUNCTION_KEY: {
						BMessage *m = Window()->CurrentMessage();
						if (m) {
							int32 k;
							m->FindInt32("key", &k);
							switch (k) {
								case B_F1_KEY:	sKey[eKey_F1] = 1;		break;
								case B_F2_KEY:	sKey[eKey_F2] = 1;		break;
								case B_F3_KEY:	sKey[eKey_F3] = 1;		break;
								case B_F4_KEY:	sKey[eKey_F4] = 1;		break;
								case B_F5_KEY:	sKey[eKey_F5] = 1;		break;
								case B_F6_KEY:	sKey[eKey_F6] = 1;		break;
								case B_F7_KEY:	sKey[eKey_F7] = 1;		break;
								case B_F8_KEY:	sKey[eKey_F8] = 1;		break;
								case B_F9_KEY:	sKey[eKey_F9] = 1;		break;
								case B_F10_KEY:	sKey[eKey_F10]= 1;		break;
								case B_F11_KEY:	sKey[eKey_F11]= 1;	 	break;
								case B_F12_KEY:	sKey[eKey_F12]= 1;		break;
								default:
									// Beats me
									printf("Unknown function key\n");
							}
						}
					}
					break;
					
				default:
					printf("Unknown key pressed\n");
					break;
			}
		}
	}
}



void CMameView::KeyUp(
	const char		*inBytes,
	int32			inNumBytes)
{
	if (inNumBytes == 1) {
		if (inBytes[0] >= '0' && inBytes[0] <= '9')
			sKey[eKey_0 + inBytes[0] - '0'] = 0;
		else if (inBytes[0] >= 'A' && inBytes[0] <= 'Z')
			sKey[eKey_A + inBytes[0] - 'A'] = 0;
		else if (inBytes[0] >= 'a' && inBytes[0] <= 'z')
			sKey[eKey_A + inBytes[0] - 'a'] = 0;
		else {
			switch (inBytes[0]) {
				case B_ENTER:		sKey[eKey_Enter]		= 0;		break;
				case B_TAB:			sKey[eKey_Tab]			= 0;		break;
				case B_SPACE:		sKey[eKey_Space]		= 0;		break;
				case B_ESCAPE:		sKey[eKey_Escape]		= 0; sQuit= true; break;
				case B_LEFT_ARROW:	sKey[eKey_Left]			= 0;		break;
				case B_RIGHT_ARROW:	sKey[eKey_Right]		= 0;		break;
				case B_UP_ARROW:	sKey[eKey_Up]			= 0;		break;
				case B_DOWN_ARROW:	sKey[eKey_Down]			= 0;		break;
				case ',':			sKey[eKey_Comma]		= 0;		break;
				case '.':			sKey[eKey_Period]		= 0;		break;

				case B_FUNCTION_KEY: {
						BMessage *m = Window()->CurrentMessage();
						if (m) {
							int32 k;
							m->FindInt32("key", &k);
							switch (k) {
								case B_F1_KEY:	sKey[eKey_F1] = 0;		break;
								case B_F2_KEY:	sKey[eKey_F2] = 0;		break;
								case B_F3_KEY:	sKey[eKey_F3] = 0;		break;
								case B_F4_KEY:	sKey[eKey_F4] = 0;		break;
								case B_F5_KEY:	sKey[eKey_F5] = 0;		break;
								case B_F6_KEY:	sKey[eKey_F6] = 0;		break;
								case B_F7_KEY:	sKey[eKey_F7] = 0;		break;
								case B_F8_KEY:	sKey[eKey_F8] = 0;		break;
								case B_F9_KEY:	sKey[eKey_F9] = 0;		break;
								case B_F10_KEY:	sKey[eKey_F10]= 0;		break;
								case B_F11_KEY:	sKey[eKey_F11]= 0;	 	break;
								case B_F12_KEY:	sKey[eKey_F12]= 0;		break;
								default:
									// Beats me
									printf("Unknown function key\n");
							}
						}
					}
					break;
					
				default:
					printf("Unknown key pressed\n");
					break;
			}
		}
	}
}

void
CMameView::MessageReceived(
	BMessage		*inMessage)
{
	if (inMessage->what == B_MODIFIERS_CHANGED) {
		int32	modifierKeys;
		
		if (inMessage->FindInt32("modifiers", &modifierKeys) == B_OK) {
			sKey[eKey_LeftShift]	= (modifierKeys & B_SHIFT_KEY)   ? 1 : 0;
			sKey[eKey_LeftControl]	= (modifierKeys & B_CONTROL_KEY) ? 1 : 0;
			sKey[eKey_Alt]			= (modifierKeys & B_COMMAND_KEY) ? 1 : 0;
		}
	}
	else
		BView::MessageReceived(inMessage);
}

void
CMameView::SetQuit()
{
	sKey[eKey_Escape] = true;
	sQuit = true;
}

void
CMameView::ClearQuit()
{
	sKey[eKey_Escape] = false;
	sQuit = false;
}

//
// Read current key state from the keypress array maintained by the View
//
int
CMameView::ReadKey(
	int		inKeycode)
{
//	// If user has closed the window, 'press' ESCAPE key
//	if (sQuit && inKeycode==OSD_KEY_FAST_EXIT) {
//		return (rand()&1);
//	}
//
	// LCTRL, ALT and Space map to mouse buttons 1, 2 and 3
	if (inKeycode == eKey_LeftControl) {
		return (sMB[0] || sKey[eKey_LeftControl]);
	}
	if (inKeycode == eKey_Alt) {
		return (sMB[1] || sKey[eKey_Alt]);
	}
	if (inKeycode == eKey_Space) {
		return (sMB[2] || sKey[eKey_Space]);
	}

//	if (inKeycode > OSD_MAX_KEY) {
//		switch (inKeycode) {
//            case OSD_KEY_FAST_EXIT:
//				return sKey[OSD_KEY_ESC];
//
//            case OSD_KEY_SHOW_GFX:
//				return sKey[OSD_KEY_F4];
//
//			case OSD_KEY_RESET_MACHINE:
//                return sKey[OSD_KEY_F3];
//
//            /*case OSD_KEY_JOY_CALIBRATE:
//				return sKey[OSD_KEY_F7];*/
//
//            /*case OSD_KEY_FRAMESKIP:
//                return sKey[OSD_KEY_F8];*/
//
//            case OSD_KEY_THROTTLE:
//                return sKey[OSD_KEY_F10];
//
//            case OSD_KEY_SHOW_FPS:
//                return sKey[OSD_KEY_F11] /* && !sKey[OSD_KEY_LSHIFT]*/;
//
//            case OSD_KEY_SHOW_PROFILE:
//                return sKey[OSD_KEY_F11] && sKey[OSD_KEY_LSHIFT];
//
//            case OSD_KEY_CONFIGURE:
//				return sKey[OSD_KEY_TAB];
//#if 0
//            case OSD_KEY_VOLUME_DOWN:
//				return (sKey[OSD_KEY_MINUS_PAD] && !sKey[OSD_KEY_LSHIFT]);
//
//			case OSD_KEY_VOLUME_UP:
//				return (sKey[OSD_KEY_PLUS_PAD] && !sKey[OSD_KEY_LSHIFT]);
//
//			case OSD_KEY_GAMMA_DOWN:
//				return (sKey[OSD_KEY_MINUS_PAD] && sKey[OSD_KEY_LSHIFT]);
//
//            case OSD_KEY_GAMMA_UP:
//                return (sKey[OSD_KEY_PLUS_PAD] && sKey[OSD_KEY_LSHIFT]);
//#endif
//            case OSD_KEY_PAUSE:
//				return sKey[OSD_KEY_P];
//
//            /*case OSD_KEY_UNPAUSE:
//				return sKey[OSD_KEY_P];*/
//
//			case OSD_KEY_SNAPSHOT:
//				return sKey[OSD_KEY_F12];
//        }
//
//	}
//
//	//if (inKeycode == OSD_KEY_RCONTROL) inKeycode = KEY_RCONTROL;
//	//if (inKeycode == OSD_KEY_ALTGR) inKeycode = KEY_ALTGR;

	// If the user clicks the close gadget, then simulate pressing
	//  and releasing the escape key.  This avoids problems with
	//  the startup screens where pressing escape won't quit the
	//  program.
	if (inKeycode==eKey_Escape && sQuit) {
		sKey[eKey_Escape] = rand()%2;
	}

	return sKey[inKeycode];
}



void
CMameView::GetMouseDelta(
	int		*outDeltaX,
	int		*outDeltaY)
{
	BPoint	p;
	uint32	b;

	if (s1stMouseRead) {
		s1stMouseRead = false;
		*outDeltaX = 0;
		*outDeltaY = 0;
	} else {
		if (LockLooper()) {
			GetMouse(&p, &b, 0);
			UnlockLooper();

			sMB[0] = (b == B_PRIMARY_MOUSE_BUTTON);
			sMB[1] = (b == B_SECONDARY_MOUSE_BUTTON);
			sMB[2] = (b == B_TERTIARY_MOUSE_BUTTON);
		}

		*outDeltaX = int (p.x) - 100;
		*outDeltaY = int (p.y) - 100;
	}

	// Move mouse back to centre of screen...
	set_mouse_position(100, 100);
}

void
CMameView::SetPenAtIdx(
	int32			inIdx,
	uint8			inRed,
	uint8			inGreen,
	uint8			inBlue)
{
}

void
CMameView::Refresh()
{
}

