#define MAIN
#include "interface.h"

char* concatStr(int num, ...) {
	va_list list;
	vector<char*> partList(10);
	int length = 0;
	char* out;
	int pos;

	va_start(list, num); 
	for(pos = 0; pos < num; pos++) { 
		char* part = va_arg(list,char*);
		length += strlen( part );
		partList[ pos ] = part;
	}
	va_end(list);

	out = new char[length+1];
	strcpy(out, "");
	for(pos = 0; pos < num; pos++) { 
		strcat( out, partList[ pos ] );
	}
	return out;
}

dllexport void test() { }

dllexport void setCartMemory( u8* rom, u32 romSize, u8* sram, u32 sramSize, u8* bios, u32 biosSize )
{
	mem::rom.map(rom, romSize);
	mem::sram.map(sram, sramSize);
	mem::bios.map(bios, biosSize);
	mem::rom.write_protect(true);
	mem::bios.write_protect(true);
}

dllexport void power()
{
	_system.bus.power();
	_system.cpu.power();
	_system.vdp.power();
	_system.sn76489.power();
	_system.init();
}

dllexport void reset()
{
	_system.cpu.reset(); //software controlled reset
}

dllexport void enter()
{
	_system.sync = _System::SyncNormal;
	_system.enter();
}

dllexport void setHwnd(HWND hwnd) {
	_system.setHwnd(hwnd);
}

dllexport void map(Bus::Type type, _System::Region region, _System::Unit unit)
{
	_system.bus.prepare(type);
	_system.setRegion(region);
	_system.setUnit(unit);
	
}

dllexport bool initVideo(HWND hwnd, int width, int height, bool vsync, bool fullscreen)
{
	try {
		_system.dvideo.init(hwnd, width, height, vsync, fullscreen);
	} catch (...) {
		return false;
	}
	return true;
}

dllexport bool initSound(bool _audio_active, unsigned _speed, unsigned _frequency, unsigned _volume)
{
	try {
		_system.dsound.set(_audio_active, _speed, _frequency, _volume);
	} catch (...) {
		return false;
	}
	return true;
}

dllexport void updateColor(int contrast, int gamma, int brightness, int filter_type, int ntsc_filter_cable)
{
	_system.color.update_parameter(
		contrast,
		gamma,
		brightness,
		filter_type,
		ntsc_filter_cable
	);
}

dllexport void setHWFilter(int filter) {
	_system.dvideo.set_filter(filter);
}

dllexport void setCounter(bool state) {
	_system.dvideo.set_counter(state);
}

dllexport void setScanlines(bool state, unsigned intensity) {
	_system.dvideo.set_scanlines(state, intensity);
}

dllexport void setDisplayMes(char* display_mes, int display_frames, bool critical) {
	_system.dvideo.set_display_mes(display_mes, display_frames, critical);
}

dllexport void pauseAudio() {
	_system.dsound.stop();
}

dllexport void playAudio() {
	_system.dsound.play();
}

dllexport void clearVideo() {
	_system.dvideo.clear();
}

dllexport void clearAudio() {
	_system.dsound.clear();
}

//input stuff
dllexport bool initInput() {
	try {
		_system.dinput.init();
	} catch (...) {
		return false;
	}
	return true;
}
dllexport unsigned getInputDeviceIdList(u8* deviceIdList) {
	return _system.inputmanager.getDeviceIdList(deviceIdList);
}
dllexport void getInputDeviceName(Inputmanager::DeviceID deviceId, char* name) {
	_system.inputmanager.getDeviceName(deviceId, name);
}
dllexport Inputmanager::Device::Port getInputDevicePort(Inputmanager::DeviceID deviceId) {
	return _system.inputmanager.getDevicePort(deviceId);
}
dllexport unsigned getInputDeviceObjectIdList(Inputmanager::DeviceID deviceId, u8* iobjectIdList) {
	return _system.inputmanager.getObjectIdList(deviceId, iobjectIdList);
}
dllexport void getInputDeviceObjectEntry(Inputmanager::DeviceID deviceId, Inputmanager::IObjectID iobjectId, char* entry) {
	_system.inputmanager.getDeviceObjectEntry(deviceId, iobjectId, entry);
}
dllexport void updateInputMap(Inputmanager::DeviceID deviceId, Inputmanager::IObjectID iobjectId, unsigned element) {
	_system.inputmanager.updateMap(deviceId, iobjectId, element);
}
dllexport unsigned readInputMap(Inputmanager::DeviceID deviceId, Inputmanager::IObjectID iobjectId) {
	return _system.inputmanager.readMap(deviceId, iobjectId);
}
dllexport void unmapInput(Inputmanager::DeviceID deviceid) {
	_system.inputmanager.unmap( deviceid );
}

dllexport void setInputPort(Inputmanager::Device::Port port, Inputmanager::DeviceID deviceId) {
	_system.inputmanager.setPort(port, deviceId);
}
dllexport void captureReady(Inputmanager::DeviceID deviceId,  Inputmanager::IObjectID iobjectId) {
	_system.inputmanager.captureReady(deviceId, iobjectId);
}
dllexport bool isInputCapturing() {
	return _system.inputmanager.isCapturing();
}
dllexport void endInputCapturing() {
	_system.inputmanager.endCapturing();
}
dllexport void pollInput() {
	_system.inputmanager.pollDevices();
}




