//-----------------------------------------------------------------------------
//-------- Copyright (c)2003-2011 XYLIO INFO SRL. All Rights Reserved. --------
//-----------------------------------------------------------------------------
// file implementing MIDI controller 'Akai LPD8'
//----------------------------------------------------------------------------- 
function getLanguageVersion()
{
	return 1;// do not modify this, this should be 1 for all scripts
}
//----------------------------------------------------------------------------- 
function getFileVersion()
{
	return 1;// update this as needed
}
//----------------------------------------------------------------------------- 
// return a user friendly name for the controller supported
function getControllerUserFriendlyName()
{
	return "Akai LPD8";
}
//----------------------------------------------------------------------------- 
// return the communication type that the controller supports 
// this can be either 'midi' or 'hid' (please return only one of them in case the controller supports both)
function getControllerType()
{
	return 'midi';
}
//----------------------------------------------------------------------------- 
// preferred way to identify the controller (if it supports MIDI SysEx)
// return false if the controller does not support this kind of identification
function getSupportedMidiSysExIdString(osId)
{
	// sysex response to 'F0 7E 7F 06 01 F7' (identification request sysex)
	// please note that the response contains 5 bytes in hex format containing
	// the Manufacturer ID (3 bytes) and Model Number (2 bytes)
	// ATTN: the returned value should omit the standard 'F0 7E 00 06 02' message start
	//if(osId==3) return false;
	return "4775001900";
}
//----------------------------------------------------------------------------- 
// this is NOT the preferred way to identify the controller but you should use
// it if the controller does not support standard MIDI SysEx identification
// return false if the controller does not support this kind of identification
// osId -- 0 Windows; 1 MacOSX; 2 Linux; 3 iOS; 4 Android; -1 unknown
function getSupportedMidiDeviceNameForInput(osId)
{
	//if(osId==3) return "Network Session 1";
	//if(osId==1) return "LPD8";
	return false;
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	//if(osId==3) return "Network Session 1";
	//if(osId==1) return "LPD8";
	return false;
}
//----------------------------------------------------------------------------- 
// preferred way to identify the controller (using the USB device VID and PID -- vendor and product id)
// return false if the controller does not support this kind of identification
// osId -- 0 Windows; 1 MacOSX; 2 Linux; -1 unknown
function getSupportedHidDeviceVID(osId)
{
	return false;
}
//----------------------------------------------------------------------------- 
function getSupportedHidDevicePID(osId)
{
	return false;
}
//----------------------------------------------------------------------------- 
// this is NOT the preferred way to identify the controller but you should use
// it if the controller does not support standard USB VID and PID identification
// return false if the controller does not support this kind of identification
// osId -- 0 Windows; 1 MacOSX; 2 Linux; -1 unknown
function getSupportedHidDeviceName(osId)
{
	return false;
}
//----------------------------------------------------------------------------- 
// this is called when the controller is initialized and the control is passed to this script
// use this to initialize any variables you might need, the controller' leds, etc
// uniqueId is a unique integer between 0..15 that is guaranteed not to change for 
// a certain opened controller -- please note that there can be many controllers
// of the same type in use at the same time ! Use uniqueId to identify between them
function controllerInit(uniqueId)
{
	debug('controllerInit LPD8 ['+uniqueId+']');// this outputs a string to DebugView app on Win
	//sendMidi(uniqueId, status, channel, data1, data2);
}
//----------------------------------------------------------------------------- 
// called just before the controller will be deinitialized and the control will go away from the script
// use to power off any powered leds, etc
function controllerDeinit(uniqueId)
{
	debug('controllerDeinit LPD8 ['+uniqueId+']');
}	
//----------------------------------------------------------------------------- 
// this is your main target function to implement the controller -- this is called 
// for each and every MIDI message that comes from the controller itself
// return true if the message was processed by the script and false to let it 
// pass thru the software (eg. so it can be assigned by the user using the LEARN function)
function messageReceived(uniqueId,status,channel,data1,data2)
{
	var messageNotProcessed=false;
	switch(status)
	{
	//-----------------------------------------------
	// controllers: sliders, knobs, jog-wheels, encoders ('moving' things)
	case 0xB0:
		switch(channel)
		{
			// program 1
			case 0:
			switch(data1)
			{
			// deck A
			case 0x01: call('setDeckEqLow', 0, data2); break;
			case 0x02: call('setDeckEqMid', 0, data2); break;
			case 0x03: call('setDeckEqHigh', 0, data2); break;
			case 0x04: call('setDeckGain', 0, data2); break;
			
			// deck B
			case 0x05: call('setDeckEqLow', 1, data2); break;
			case 0x06: call('setDeckEqMid', 1, data2); break;
			case 0x07: call('setDeckEqHigh', 1, data2); break;
			case 0x08: call('setDeckGain', 1, data2); break;
			case 0x00: break;
			
			default: messageNotProcessed = true;
			}
			break;
			
			// program 2
			case 1:
			switch(data1)
			{
			// deck A
			case 0x01: call('setDeckPitch', 0, data2); break;
			case 0x02: call('setDeckPitchKey', 0, data2); break;
			case 0x03: call('setDeckCutoff', 0, data2); break;
			case 0x04: call('setDeckVolume', 0, data2); break;
			
			// deck B
			case 0x05: call('setDeckPitch', 1, data2); break;
			case 0x06: call('setDeckPitchKey', 1, data2); break;
			case 0x07: call('setDeckCutoff', 1, data2); break;
			case 0x08: call('setDeckVolume', 1, data2); break;
			case 0x00: break;
			
			default: messageNotProcessed = true;
			}
			break;
			
			// program 3
			case 2:
			switch(data1)
			{
			// deck C
			case 0x01: call('setDeckEqLow', 2, data2); break;
			case 0x02: call('setDeckEqMid', 2, data2); break;
			case 0x03: call('setDeckEqHigh', 2, data2); break;
			case 0x04: call('setDeckGain', 2, data2); break;
			
			// deck D
			case 0x05: call('setDeckEqLow', 3, data2); break;
			case 0x06: call('setDeckEqMid', 3, data2); break;
			case 0x07: call('setDeckEqHigh', 3, data2); break;
			case 0x08: call('setDeckGain', 3, data2); break;
			case 0x00: break;
			
			default: messageNotProcessed = true;
			}
			break;
			
			// program 2
			case 3:
			switch(data1)
			{
			// deck C
			case 0x01: call('setDeckPitch', 2, data2); break;
			case 0x02: call('setDeckPitchKey', 2, data2); break;
			case 0x03: call('setDeckCutoff', 2, data2); break;
			case 0x04: call('setDeckVolume', 2, data2); break;
			
			// deck D
			case 0x05: call('setDeckPitch', 3, data2); break;
			case 0x06: call('setDeckPitchKey', 3, data2); break;
			case 0x07: call('setDeckCutoff', 3, data2); break;
			case 0x08: call('setDeckVolume', 3, data2); break;
			case 0x00: break;
			
			default: messageNotProcessed = true;
			}
			break;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)
	case 0x80:
	case 0x90:
		if(status==0x90) data2 = 0x7F;
		if(status==0x80) data2 = 0;
		switch(channel)
		{
			// program 1
			case 0:
			switch(data1)
			{
			// deck A
			case 0x28: call('deckCue', 0, data2); break;
			case 0x29: call('deckPlayPause', 0, data2); break;
			case 0x2A: call('deckCuePlay', 0, data2); break;
			case 0x2B: call('deckSync', 0, data2); break;
			
			
			// deck B
			case 0x24: call('deckCue', 1, data2); break;
			case 0x25: call('deckPlayPause', 1, data2); break;
			case 0x26: call('deckCuePlay', 1, data2); break;
			case 0x27: call('deckSync', 1, data2); break;
								
			default: messageNotProcessed = true;
			}
			break;
			
			// program 2
			case 1:
			switch(data1)
			{
			// deck A
			case 0x25: call('deckLoopInEnd', 0, data2); break;
			case 0x26: call('deckLoopExit', 0, data2); break;
			case 0x2E: call('deckLoopPrev', 0, data2); break;
			case 0x2C: call('deckLoopNext', 0, data2); break;
			
			
			// deck B
			case 0x23: call('deckLoopInEnd', 1, data2); break;
			case 0x24: call('deckLoopExit', 1, data2); break;
			case 0x2A: call('deckLoopPrev', 1, data2); break;
			case 0x27: call('deckLoopNext', 1, data2); break;
								
			default: messageNotProcessed = true;
			}
			break;
			
			//program 3
			case 2:
			switch(data1)
			{
			// deck C
			case 0x43: call('deckCue', 2, data2); break;
			case 0x45: call('deckPlayPause', 2, data2); break;
			case 0x47: call('deckCuePlay', 2, data2); break;
			case 0x48: call('deckSync', 2, data2); break;
			
			
			// deck D
			case 0x3C: call('deckCue', 3, data2); break;
			case 0x3E: call('deckPlayPause', 3, data2); break;
			case 0x40: call('deckCuePlay', 3, data2); break;
			case 0x41: call('deckSync', 3, data2); break;
								
			default: messageNotProcessed = true;
			}
			break;
			
			//program 4
			case 3:
			switch(data1)
			{
			// deck C
			case 0x2B: call('deckLoopInEnd', 2, data2); break;
			case 0x2D: call('deckLoopExit', 2, data2); break;
			case 0x2F: call('deckLoopPrev', 2, data2); break;
			case 0x30: call('deckLoopNext', 2, data2); break;
			
			
			// deck D
			case 0x24: call('deckLoopInEnd', 3, data2); break;
			case 0x26: call('deckLoopExit', 3, data2); break;
			case 0x28: call('deckLoopPrev', 3, data2); break;
			case 0x29: call('deckLoopNext', 3, data2); break;
			
			default: messageNotProcessed = true;
			}
			break;
		}
	//-----------------------------------------------
	default: messageNotProcessed = true;
	}
	if(messageNotProcessed) debug('messageReceived ['+uniqueId+'] - status:'+status+' channel:'+channel+' data1:'+data1+' data2:'+data2);
	return !messageNotProcessed;
}
//----------------------------------------------------------------------------- 
// this is called by the software whenever something important changes (eg. play status, song changed, etc)
// depending on the notification type it may refer to a global event (deck is -1) or a specific deck (deck >= 0)
// and can contain any/all of the parameters: param 1 is an integer, param 2 is a float, param 3 is a string
function notificationReceived(uniqueId,name,deck,param1,param2,param3)
{
	//debug('notif ['+uniqueId+'] name='+name + ' deck='+deck + ' p1(int)='+param1 + ' p2(float)='+param2 + ' p3(str)='+param3);
}
//----------------------------------------------------------------------------- 
// this is called from time to time by the software (several times per second)
// (it is guaranteed that 'timerTick' will get executed ALWAYS right after notificationReceived)
function timerTick(uniqueId)
{
	//debug('timerTick ['+uniqueId+']');
}
//----------------------------------------------------------------------------- 
