//-----------------------------------------------------------------------------
//-------- Copyright (c)2003-2012. All Rights Reserved. -----------------------
//-----------------------------------------------------------------------------
// file implementing MIDI controller 'Zomo MC1000'
//----------------------------------------------------------------------------- 
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 "Zomo MC-1000";
}
//----------------------------------------------------------------------------- 
// 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 "002079200C";// short 5-bytes sysex (we don't use this since it's same as 'Reloop Mixage IE')
	return "002079200C102031";// a bit longer 8-bytes sysex id
	
	// ATTN: normally we will only use 5 bytes (10 hexa characters) but there are cases when 2 otherwise 
	// very different controllers from different companies have the exact same sysex id for the first 5 bytes
	// example:
	//return "002079200C102031313800F7";// full sysex id reply from 'Zomo MC1000'
	//return "002079200C101701000000F7";// full sysex id reply from 'Reloop Mixage IE'
	//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)
{
	//return "ZOMO MC-1000 MIDI";
	return false;
}
//----------------------------------------------------------------------------- 
function getSupportedMidiDeviceNameForOutput(osId)
{
	//return "ZOMO MC-1000 MIDI";
	return false;
}
//----------------------------------------------------------------------------- 
//----------------------------------------------------------------------------- 
// some variables necessary only for this particular script

//----------------------------------------------------------------------------- 
// 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 MC1000 ['+uniqueId+']');// this outputs a string to DebugView app on Win
	for(var i=0; i<4; i++)
	{
		
		sendMidi(uniqueId,0x90,i,0x0E,(getValue('play', i) ? 0x7F : 0x00));// play-pause
		sendMidi(uniqueId,0x90,i,0x0F,(getValue('sync', i) ? 0x7F : 0x00));// sync 
		
		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,0x04,(getValue('fxFlanger', i) ? 0x7F : 0x00));// flanger
		sendMidi(uniqueId,0x90,i,0x05,(getValue('fxPhaser', i) ? 0x7F : 0x00));// phaser
		sendMidi(uniqueId,0x90,i,0x06,(getValue('fxReverb', i) ? 0x7F : 0x00));// reverb
		sendMidi(uniqueId,0x90,i,0x07,(getValue('fxBeatwaw', i) ? 0x7F : 0x00));// beatwaw
		
		
		
		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 MC1000 ['+uniqueId+']');
	
	for(var i=0; i<4; i++)
	{
		
		sendMidi(uniqueId,0x90,i,0x0E,0x00);// play-pause
		
		sendMidi(uniqueId,0x90,i,0x01,0x00);// cue 1
		sendMidi(uniqueId,0x90,i,0x02,0x00);// cue 2
		sendMidi(uniqueId,0x90,i,0x03,0x00);// cue 3
		
		sendMidi(uniqueId,0x90,i,0x04,0x00);// Flanger
		sendMidi(uniqueId,0x90,i,0x05,0x00);// phaser
		sendMidi(uniqueId,0x90,i,0x06,0x00);// reverb
		sendMidi(uniqueId,0x90,i,0x07,0x00);// beatwaw

		sendMidi(uniqueId,0x90,i,0x0F,0x00);// sync
		
		
		

		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 0x05: call('setDeckCutoff', channel, data2); break; // Hp filter
		
		case 0x42: call('setDeckEqHigh', channel-2, data2); break; // eq high
		case 0x41: call('setDeckEqMid', channel-2, data2); break; // eq mid
		case 0x40: call('setDeckEqLow', channel-2, data2); break; // eq low
		
		case 0x01: call('deckFxFlangerP1', channel, data2); break; //Flanger
		case 0x02: call('deckFxPhaserP1', channel, data2); break; // phaser
		case 0x03: call('deckFxReverbP1', channel, data2); break; // reverb
		case 0x04: call('deckFxBeatwawP1', channel, data2); break; // beatwaw
		// effects when shift is engaged
		case 0x40: call('deckFxFlangerP2', channel, data2); break; //Flanger
		case 0x41: call('deckFxPhaserP2', channel, data2); break; // phaser
		case 0x42: call('deckFxReverbP2', channel, data2); break; // reverb
		case 0x43: call('deckFxBeatwawP2', channel, data2); break; // beatwaw
		case 0x21: if(data2==0x3F) call('deckLoopLess', channel, data2); else call('deckLoopMore', channel, data2); break; //loop knob x2 or /2 
		case 0x22: if(data2==0x3F) call('deckReverse', channel, data2); else call('deckReverse', channel, data2); break; //fx knob left reverse 	


		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 0x22: call('lbToggleSelect', data2); break; //lb toggle select. HOLD Down to select playlist
		
		//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 0x0E: call('deckPlayPause', channel, data2); break; //play pause 1/2
		// different than midi chart for load deck onsame note channel 0-3
		case 0x09: call('deckLBLoad', 0, data2); break; //load deck 1
		case 0x19: call('deckLBLoad', 1, data2); break; //load deck 2
		
	
		case 0x0F: call('deckSync', channel, data2); break; //sync
		case 0x01: call('deckCuePos1', channel, data2); break; //cue1
		case 0x02: call('deckCuePos2', channel, data2); break; //cue2
		case 0x03: call('deckCuePos3', channel, data2); break; //cue3
		case 0x0D: call('deckBendDown', channel, data2); break; //pitch bend down
		case 0x0C: call('deckBendUp', channel, data2); break; //pitch bend up
		
		case 0x04: call('deckFxFlanger', channel, data2); break; //flanger
		case 0x05: call('deckFxPhaser', channel, data2); break; //phaser
		case 0x06: call('deckFxReverb', channel, data2); break; //reverb
		case 0x07: call('deckFxBeatwaw', channel, data2); break; //beatwaw
		
		case 0x0A: if(!getValue('looping', channel)) call('deckLoopInEnd', channel, data2);else call('deckLoopExit', channel, data2); break; //Loop
		//case 0x08: call('deckLoopExit', channel, data2); break; // loop exit
		
		case 0x4D: call('deckBrake', channel, data2); break; // brake effect shif + play pause
		
		case 0x40: call('deckCuePosClear', channel, data2); break; // clear cue pos 1
		case 0x41: call('deckCuePosClear', channel, data2); break; // clear cue pos 2
		case 0x42: call('deckCuePosClear', channel, data2); break; // clear cue pos 3
		

		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<4)
	{

		if(name=='play') 		 sendMidi(uniqueId,0x90,deck,0x0E,(param1 ? 0x7F : 0x00)); //play
		if(name=='onbeat') 	 	 sendMidi(uniqueId,0x90,deck,0x0F,(param1 ? 0x7F : 0x00)); //sync on beat
	
		
		
		if(name=='cuepos1') 	 sendMidi(uniqueId,0x90,deck,0x01,(param1 ? 0x7F : 0x00)); //cue 1
		if(name=='cuepos2') 	 sendMidi(uniqueId,0x90,deck,0x02,(param1 ? 0x7F : 0x00)); //cue 2
		if(name=='cuepos3') 	 sendMidi(uniqueId,0x90,deck,0x03,(param1 ? 0x7F : 0x00)); //cue 3
		
		if(name=='fxFlanger') 	 sendMidi(uniqueId,0x90,deck,0x04,(param1 ? 0x7F : 0x00)); //flanger
		if(name=='fxPhaser') 	 sendMidi(uniqueId,0x90,deck,0x05,(param1 ? 0x7F : 0x00)); //phaser
		if(name=='fxReverb') 	 sendMidi(uniqueId,0x90,deck,0x06,(param1 ? 0x7F : 0x00)); //reverb
		if(name=='fxBeatwaw') 	 sendMidi(uniqueId,0x90,deck,0x07,(param1 ? 0x7F : 0x00)); //beatwaw

		
		
		

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

//----------------------------------------------------------------------------- 
// 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<4; i++)
	{
	
	}
}
//----------------------------------------------------------------------------- 
