Revision 1 (by (no author), 2006/09/28 22:53:53) Initial import
/// \file widgetmanager.h
/// Widger manager class

#include "widgetmanager.h"

#ifdef _WIN32
#include <winalleg.h>
#else
#include <sys/time.h>

unsigned long long timeGetTime()
{
        timeval t;
        gettimeofday(&t, 0);
        return ((long long) t.tv_sec) * 1000 + t.tv_usec / 1000;
}
#endif

using namespace std;

WidgetManager* WidgetManager::currentlyRunning = NULL;

void WidgetManager::KeyboardHandler(int scancode)
{
	WidgetEvent* evt = new WidgetEvent();
	evt->type = (scancode & 0x80) ? ET_KeyUp : ET_KeyDown;
	evt->key.scancode = scancode & ~0x80;
	currentlyRunning->queue.push_back(evt);
}

void WidgetManager::MouseHandler(int flags)
{
	WidgetEvent* evt = new WidgetEvent();
	switch(flags)
	{
		case MOUSE_FLAG_MOVE:
			evt->type = ET_MouseMove;
			evt->mouseMove.x = mouse_x;
			evt->mouseMove.y = mouse_y;
			break;
		case MOUSE_FLAG_LEFT_DOWN:
		case MOUSE_FLAG_RIGHT_DOWN:
		case MOUSE_FLAG_MIDDLE_DOWN:
			evt->type = ET_MousePress;
			evt->mousePress.x = mouse_x;
			evt->mousePress.y = mouse_y;
			evt->mousePress.buttons = mouse_b;
			break;
		case MOUSE_FLAG_LEFT_UP:
		case MOUSE_FLAG_RIGHT_UP:
		case MOUSE_FLAG_MIDDLE_UP:
			evt->type = ET_MouseRelease;
			evt->mousePress.x = mouse_x;
			evt->mousePress.y = mouse_y;
			evt->mousePress.buttons = mouse_b;
			break;
		case MOUSE_FLAG_MOVE_Z:
			evt->type = ET_MouseScroll;
			evt->mouseScroll.amount = mouse_z;
			mouse_z = 0;
			break;
	}
	currentlyRunning->queue.push_back(evt);
}

WidgetManager::WidgetManager(): buffer(NULL), running(false)
{
}

WidgetManager::~WidgetManager()
{
	running = false;
	Stop();
}

void WidgetManager::Begin()
{
	buffer = create_bitmap(SCREEN_W, SCREEN_H);
	running = true;
	
	currentlyRunning = this;
	
	keyboard_lowlevel_callback = KeyboardHandler;
	mouse_callback = MouseHandler;
}

void WidgetManager::Pause()
{
	running = false;
}

void WidgetManager::Stop()
{
	keyboard_lowlevel_callback = NULL;
	mouse_callback = NULL;
	
	currentlyRunning = NULL;
	
	destroy_bitmap(buffer);
	buffer = NULL;
	
	for(list<WidgetEvent*>::iterator i = queue.begin(); i != queue.end(); i++)
		delete *i;
	queue.clear();
}

void WidgetManager::Continue()
{
	//oldTime = timeGetTime();
	running = true;
	
	while(running)
	{
		if(!queue.size())
			rest(1);
		if(queue.size())
		{
			WidgetEvent* evt = queue.front();
			queue.pop_front();
			
			switch(evt->type)
			{
				case ET_KeyDown:
				case ET_KeyUp:
				{
					KeyEventArgs e;
					e.handled = false;
					e.key = evt->key.scancode;
					e.down = evt->type == ET_KeyDown;
					if(evt->type == ET_KeyDown)
						KeyDown(&e);
					else
						KeyUp(&e);
					break;
				}
				case ET_MouseMove:
				{
					MouseEventArgs e;
					e.handled = false;
					e.x = evt->mouseMove.x;
					e.y = evt->mouseMove.y;
					MouseMove(&e);
					break;
				}
				case ET_MousePress:
				case ET_MouseRelease:
				{
					MouseEventArgs e;
					e.handled = false;
					e.x = evt->mousePress.x;
					e.y = evt->mousePress.y;
					e.b = evt->mousePress.buttons;
					if(evt->type == ET_MousePress)
						MousePress(&e);
					else
						MouseRelease(&e);
					break;
				}
				case ET_MouseScroll:
				{
					MouseEventArgs e;
					e.handled = false;
					e.z = evt->mouseScroll.amount;
					MouseScroll(&e);
					break;
				}
			}
			
			delete evt;
		}
		if(wantRedraw)
		{
			wantRedraw = false;
			RedrawEventArgs e;
			e.off_x = 0;
			e.off_y = 0;
			e.to = buffer;
			
			Redraw(&e);
			
			blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
		}
		
		/*long long newTime = timeGetTime();
		while(newTime - oldTime == 0)
		{
			rest(1);
			newTime = timeGetTime();
		}
		double dTime = (double) (newTime - oldTime) / 1000;
		oldTime = newTime;*/
	}
}

// The end