//-----------------------------------------------------------------------------
//-------- Copyright (c)2003-2011. All Rights Reserved. -----------------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller 'Vestax VCI-400'
//----------------------------------------------------------------------------- 
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 "Novation Dicer";
}
//----------------------------------------------------------------------------- 
// 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 (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;
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// 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==1) return false;
	
	//return "0040022001";
	
	return false;
}
//----------------------------------------------------------------------------- 
// 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; -1 unknown
function getSupportedMidiDeviceNameForInput(osId)
{
	if(osId==0) return "Novation Dicer";
	if(osId==1) return "Dicer Novation Dicer";
	
	
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	if(osId==0) return "Novation Dicer";
	if(osId==1) return "Dicer Novation Dicer";
	//return false;
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// some variables necessary only for this particular script
var previousAutoLoopLightLed=[-1,-1,];// 2 decks leds

//----------------------------------------------------------------------------- 
// 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 Dicer ['+uniqueId+']');// this outputs a string to DebugView app on Win
	for(var i=0; i<2; i++)
	{
		
		//sendMidi(uniqueId,0x90,i,0x22,(getValue('play', i) ? 0x7F : 0x00));// play-pause
		
		//sendMidi(uniqueId,0x90,i,0x01,(getValue('cuepos1', i) ? 0x7F : 0x00));// cue 1
		//sendMidi(uniqueId,0x90,i,0x02,(getValue('cuepos2', i) ? 0x7F : 0x00));// cue 2
		//sendMidi(uniqueId,0x90,i,0x03,(getValue('cuepos3', i) ? 0x7F : 0x00));// cue 3
		//sendMidi(uniqueId,0x90,i,0x03,(getValue('cuepos4', i) ? 0x7F : 0x00));// cue 4
		//sendMidi(uniqueId,0x90,i,0x03,(getValue('cuepos4', i) ? 0x7F : 0x00));// cue 5
		
		
		
		call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	}
}
//----------------------------------------------------------------------------- 
// 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 Dicer ['+uniqueId+']');
	
	for(var i=0; i<4; i++)
	{
		
		//sendMidi(uniqueId,0x90,i,0x22,0x00);// play-pause
		
		sendMidi(uniqueId,0x90,i+10,0x3C,0x00);// cue 1
		sendMidi(uniqueId,0x90,i+10,0x3D,0x00);// cue 2
		sendMidi(uniqueId,0x90,i+10,0x3E,0x00);// cue 3
		sendMidi(uniqueId,0x90,i+10,0x3F,0x00);// cue 4
		sendMidi(uniqueId,0x90,i+10,0x40,0x00);// cue 5

		
		
		
		

		call('sleep', 10);// delay for 10ms to allow the MIDI out buffer to flush
	}
}
//----------------------------------------------------------------------------- 
// 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(data1)
		{
		// global
		//case 0x23: call('lbMoveCursor', data2==0x41 ? 1:-1); break; //library curser up down		

		// decks
		//case 17: call('setDeckVolume', channel-2, data2); break; //volume slider
		//case 18: call('setDeckPitch', channel-2, data2); break; //pitch slider
		//case 13: call('setDeckEqHigh', channel-2, data2); break; // eq high
		//case 14: call('setDeckEqMid', channel-2, data2); break; // eq mid
		//case 15: call('setDeckEqLow', channel-2, data2); break; // eq low
		
		//case 0x05: call('setDeckCutoff', channel, data2); break; // Hp filter
				

		default: messageNotProcessed = true;
		}
		break;
	//-----------------------------------------------
	// note on/off: buttons, switches ('pressing' things)
	
	case 0x90:
		//if(status==0x90) data2 = 0x7F;
		//if(status==0x80) data2 = 0;
		switch(data1)
		{
		// global
		
		//case 0x00: if((status==0x90)&&(data2>0x3F)) call('lbToggleSelect', data2); break;
		//case 0x59: if(data2>0x3F) call('lbBrowserSelect', data2); break;
		//case 0x5A: if(data2>0x3F) call('lbListSelect', data2); break;

		
		// decks
		

		
		//case 0x22: call('deckPlayPause', channel, data2); break; //play pause 1/2
		
		//case 0x09: call('deckLBLoad', channel, data2); break; //load deck
		
	
		//case 0x0F: call('deckSync', channel, data2); break; //sync
		
		case 0x3C: if(channel==10) call('deckCuePos1', 0, data2); else if(channel==13) call('deckCuePos1', 1, data2); else
				   if(channel==11) call('deckFxBeatwaw', 0, data2); else if(channel==14) call('deckFxBeatwaw', 1, data2); else
				   if(channel==12) call('deckLoop1', 0, data2); else if(channel==15) call('deckLoop1', 1, data2); break; //button 1 per channel
				   
		case 0x3D: if(channel==10) call('deckCuePos2', 0, data2); else if(channel==13) call('deckCuePos2', 1, data2); else
					if(channel==11) call('deckReverse', 0, data2); else if(channel==14) call('deckReverse', 1, data2); else
					if(channel==12) call('deckLoop2', 0, data2); else if(channel==15) call('deckLoop2', 1, data2); break; //button 2
					
		case 0x3E: if(channel==10) call('deckCuePos3', 0, data2); else if(channel==13) call('deckCuePos3', 1, data2); else
					if(channel==11) call('deckBrake', 0, data2); else if(channel==14) call('deckBrake', 1, data2); else
					if(channel==12) call('deckLoop4', 0, data2); else if(channel==15) call('deckLoop4', 1, data2); break; //button 3
					
		case 0x3F: if(channel==10) call('deckCuePos4', 0, data2); else if(channel==13) call('deckCuePos4', 1, data2); else 
					if(channel==11) call('deckFxFlanger', 0, data2); else if(channel==14) call('deckFxFlanger', 1, data2); else
					if(channel==12) call('deckLoop8', 0, data2); else if(channel==15) call('deckLoop8', 1, data2); break; //button 4
		
		case 0x40: if(channel==10) call('deckCuePos5', 0, data2); else if(channel==13) call('deckCuePos5', 1, data2); else
					if(channel==11) call('deckFxEcho', 0, data2); else if(channel==14) call('deckFxEcho', 1, data2); else
					if(channel==12) call('deckLoop16', 0, data2); else if(channel==15) call('deckLoop16', 1, data2); break; //button 5
		
		case 0x41:  if(channel==10) call('deckCuePosClear', 0, data2); else if(channel==13) call('deckCuePosClear', 1, data2); break; //cue delete
		
		
		
		
		//case 0x0D: call('deckBendDown', channel, data2); break; //pitch bend down
		//case 0x0C: call('deckBendUp', channel, data2); break; //pitch bend up

		

		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);
	if(deck==0)
	{
		//if(name=='cue') 		 sendMidi(uniqueId,0x90,2+deck,0x0E,(param1 ? 0x7F : 0x00)); // cue
		//if(name=='play') 		 sendMidi(uniqueId,0x90,deck,0x0E,(param1 ? 0x7F : 0x00)); //play
	
		
		
		if(name=='cuepos1') 	 sendMidi(uniqueId,0x90,10,0x3C,(param1 ? 0x0F : 0x00)); //cue 1
		if(name=='cuepos2') 	 sendMidi(uniqueId,0x90,10,0x3D,(param1 ? 0x0F : 0x00)); //cue 2
		if(name=='cuepos3') 	 sendMidi(uniqueId,0x90,10,0x3E,(param1 ? 0x0F : 0x00)); //cue 3
		if(name=='cuepos4') 	 sendMidi(uniqueId,0x90,10,0x3F,(param1 ? 0x0F : 0x00)); //cue 3
		if(name=='cuepos5') 	 sendMidi(uniqueId,0x90,10,0x40,(param1 ? 0x0F : 0x00)); //cue 3

		if(name=='loopSize')
		{
		// turn off last led (if any is on)
		if(previousAutoLoopLightLed[deck]>-1)
			sendMidi(uniqueId,0x90,12,previousAutoLoopLightLed[deck],0x00);
		// calculate the new led to power on
		switch(param1)
		{

		case   64: previousAutoLoopLightLed[deck] = 0x3C; break;// 1 beat
		case  128: previousAutoLoopLightLed[deck] = 0x3D; break;// 2 beats
		case  256: previousAutoLoopLightLed[deck] = 0x3E; break;// 4 beats
		case  512: previousAutoLoopLightLed[deck] = 0x3F; break;// 8 beats
		case 1024: previousAutoLoopLightLed[deck] = 0x40; break;// 16 beats
		default:   previousAutoLoopLightLed[deck] = -1;
		}
		// actually light the led
		if(previousAutoLoopLightLed[deck]>-1)	
			sendMidi(uniqueId,0x90,12,previousAutoLoopLightLed[deck],0x5F);
		}


		if(name=='fxBeatwaw') 	 sendMidi(uniqueId,0x90,11,0x3C,(param1 ? 0x6F : 0x00)); //beatwaw
		if(name=='reverse') 	 sendMidi(uniqueId,0x90,11,0x3D,(param1 ? 0x6F : 0x00)); //reverse
		if(name=='brake') 	     sendMidi(uniqueId,0x90,11,0x3E,(param1 ? 0x6F : 0x00)); //brake
		if(name=='fxFlanger') 	 sendMidi(uniqueId,0x90,11,0x3F,(param1 ? 0x6F : 0x00)); //flanger
		if(name=='fxEcho') 	     sendMidi(uniqueId,0x90,11,0x40,(param1 ? 0x6F : 0x00)); //echo	
		

	}
	if(deck==1)
	{
		//if(name=='cue') 		 sendMidi(uniqueId,0x90,2+deck,0x0E,(param1 ? 0x7F : 0x00)); // cue
		//if(name=='play') 		 sendMidi(uniqueId,0x90,deck,0x0E,(param1 ? 0x7F : 0x00)); //play
	
		
		
		if(name=='cuepos1') 	 sendMidi(uniqueId,0x90,13,0x3C,(param1 ? 0x0F : 0x00)); //cue 1
		if(name=='cuepos2') 	 sendMidi(uniqueId,0x90,13,0x3D,(param1 ? 0x0F : 0x00)); //cue 2
		if(name=='cuepos3') 	 sendMidi(uniqueId,0x90,13,0x3E,(param1 ? 0x0F : 0x00)); //cue 3
		if(name=='cuepos4') 	 sendMidi(uniqueId,0x90,13,0x3F,(param1 ? 0x0F : 0x00)); //cue 3
		if(name=='cuepos5') 	 sendMidi(uniqueId,0x90,13,0x40,(param1 ? 0x0F : 0x00)); //cue 3
		
		
		
		if(name=='loopSize')
	{
		// turn off last led (if any is on)
		if(previousAutoLoopLightLed[deck]>-1)
			sendMidi(uniqueId,0x90,15,previousAutoLoopLightLed[deck],0x00);
		// calculate the new led to power on
		switch(param1)
		{

		case   64: previousAutoLoopLightLed[deck] = 0x3C; break;// 1 beat
		case  128: previousAutoLoopLightLed[deck] = 0x3D; break;// 2 beats
		case  256: previousAutoLoopLightLed[deck] = 0x3E; break;// 4 beats
		case  512: previousAutoLoopLightLed[deck] = 0x3F; break;// 8 beats
		case 1024: previousAutoLoopLightLed[deck] = 0x40; break;// 16 beats
		default:   previousAutoLoopLightLed[deck] = -1;
		}
		// actually light the led
		if(previousAutoLoopLightLed[deck]>-1)	
			sendMidi(uniqueId,0x90,15,previousAutoLoopLightLed[deck],0x5F);
	}

		if(name=='fxBeatwaw') 	 sendMidi(uniqueId,0x90,14,0x3C,(param1 ? 0x6F : 0x00)); //beatwaw
		if(name=='reverse') 	 sendMidi(uniqueId,0x90,14,0x3D,(param1 ? 0x6F : 0x00)); //reverse
		if(name=='brake') 	     sendMidi(uniqueId,0x90,14,0x3E,(param1 ? 0x6F : 0x00)); //brake
		if(name=='fxFlanger') 	 sendMidi(uniqueId,0x90,14,0x3F,(param1 ? 0x6F : 0x00)); //flanger
		if(name=='fxEcho') 	     sendMidi(uniqueId,0x90,14,0x40,(param1 ? 0x6F : 0x00)); //echo	

		
		//if(name=='looping') 	 sendMidi(uniqueId,0x90,2+deck,0x03,(param1 ? 0x7F : 0x00)); //Dex FX 1
		//if(name=='looping') 	 sendMidi(uniqueId,0x90,2+deck,0x04,(param1 ? 0x7F : 0x00)); //Dex FX 2
		
		

	}
}
//----------------------------------------------------------------------------- 

//----------------------------------------------------------------------------- 
// 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+']');


	for(var i=0; i<2; i++)
	{
	
	}
}
//----------------------------------------------------------------------------- 
