/*
SEQUENCE GROUPING MANAGEMENT MODULE

this module builds a representation of a sequence in values using containers
It allows to create groups of keys, a group being a cue and one key per layer.
In a group, all keys sync their time on cue's time, only value can be modified

The sequence with grouping can then be exported and reloaded.

The module checks periodicaly if timeline sequence structure (cues, layers and keys) and
module values structure are in sync. If out of sync, you may either rebuild values structure 
from sequence or rebuild sequence from values

*/
var syncRatems = 100;
var syncDelta = 0.;
var doSync = false ;
var inibValuesChanged = false ;

var saveFile = script.addFileParameter("auto save sequence","");
var saveRatems = 30;
var saveDelta = 0.;

var debug = true;
var debugFile;

var parametersPath = local.parameters ;

var sequence = '' ;
var sequencePath = local.getChild("parameters").sequence ;
var file ;
var filePath = local.parameters.sequenceFile ;


var newGroupLayers = local.values.newGroup.layers ;
// var groups = local.getChild("values").groups ;
var cues = local.getChild("values").keys.cues ;
// var cuesList = []; //holds cues containers reference
var layers = local.getChild("values").keys.layers ;
// var layerList = {}; //holds layer container as object with reference and an array of keys containers references



var rebuildValues = script.addTrigger("rebuild values", "adds a key at current cursor position" );
var refreshKeys = script.addTrigger("refresh keys", "truc");
var printKeys = script.addTrigger("printKeys","truc");
var clearSeq = script.addTrigger("clear Sequence","truc");


var sequence_structure = {	params: {}, 
							groups:{},
							keys:{
								cues:{},
								layers:{}
							}
						};
						 //WAS tl_groups
	/*group0 : { inCue : {pan : "key", tilt : "key", zoom : "key", dim : "key", focus : "key"},
							 							outCue : {pan : "key", tilt : "key", zoom : "key", dim : "key", focus : "key"}
													}*/
								
/////////////////////		SCRIPT FUNCTIONS	//////////////////////////////


function init() {
	script.log("LOADED SEQUENCE GROUPING MANAGEMENT MODULE ");
	
	//adapt update rate
	updateSyncRate();
	updateSynchronize();

	saveFile.set("sequence_autosave.json");
	saveFile.setAttribute("readonly", true);
	importSequenceFile(saveFile);
	// layers = local.getChild("values").keys.layers ;
	// printMethodsAndProperties(local.getChild("values").groups.group0.cue.get());
	// script.log(local.getChild("values").groups.group0.cue.get());
	//test if a sequence is already choosen else refresh and unlock sequence enum
	sequence = local.getChild("parameters").sequence.getKey();
	// var sequenceIndex = local.getChild("parameters").sequence.get();
	// script.log(sequenceIndex + "  " + sequence);
	
	if(sequence == ""){refreshSequenceEnum();}
	else{
		sequencePath.removeOptions();
		sequencePath.addOption(sequence,0);
		sequencePath.setAttribute("readonly", true);
	}
	sequence = local.getChild("parameters").sequence.getKey();

}

function scriptParameterChanged(param){
	
	if (param.is(printKeys) ){printKeys();}

	else if(param.is(rebuildValues)){struct_buildValuesFromSeq();}

	else if (param.is(refreshKeys)){
		script.log("refreshKeys");
		refreshKeysList();
	}

	

	else {script.log("scriptparamchanged" + param.name);}
}



function update(deltaTime){
	if(sequence!=""){
		// script.log(doSync);
		if(doSync){
			syncDelta += deltaTime ;
			// script.log(doSync);
			if (syncDelta >= syncRatems){
				syncDelta = 0. ;
				var autosave = struct_buildValuesFromSeq();
				if(autosave){exportSequenceFile(saveFile);}
			}
		}	

		saveDelta += deltaTime ;
		if (saveDelta >= saveRatems){
			saveDelta = 0. ;
			exportSequenceFile(saveFile);
			script.log("sequence autosave");
		}

	}
}




///////////////////////////		HELPERS		/////////////////////////////////

function printMethodsAndProperties(obj){
	script.log(" ");
	var name = obj.getControlAddress() == undefined ? "object" : obj.getControlAddress();
	// var name = "object";
	script.log("  METHODS OF " + name);
	var methods = util.getObjectMethods(obj);
	for(var i=0 ; i<methods.length ; i++){
		script.log("  "+ methods[i]);
	}
	script.log("  PARAMETERS OF " + name);
	var props = util.getObjectProperties(obj, true, false);
	for(var i=0 ; i<props.length ; i++){
		script.log("  "+ props[i]);
	}
	script.log("  OBJECTS OF " + name);
	var props = util.getObjectProperties(obj, false, true);
	for(var i=0 ; i<props.length ; i++){
		script.log("  "+ props[i]);
	}
}


function printKeys(){

	var seq = root.sequences.sequence.layers.mapping.automation.getItems() ;
	if(seq.length){
		for(var i=0; i<seq.length; i++){
			script.log (">> "+seq[i].name + "  " + seq[i].position.get() + "  " + seq[i].listSize.get() );
		}
	}
	else{script.log("nothing to print");}
}




///////////////////////		 PARAMETERS FUNCTIONS	///////////////////////

// Module callback
function moduleParameterChanged(param){
	

	if (param.is(parametersPath.importExport.sequenceFile)) {}

	else if (param.is(parametersPath.importExport.importSequence)){importSequenceFile(parametersPath.importExport.sequenceFile);}
	
	else if (param.is(parametersPath.importExport.exportSequence)) { 
		exportSequenceFile(parametersPath.importExport.sequenceFile);
		exportSequenceFile(saveFile);
	}

	else if (param.is(parametersPath.synchronize)){updateSynchronize();}

	else if (param.is(parametersPath.syncRate)){updateSyncRate();}

	else if (param.is(parametersPath.clearSequence)){seq_clearSequence();}

	else if (param.is(parametersPath.reorderSequence)){seq_reorderSequence();}

	else if (param.is(parametersPath.changeSequence)){refreshSequenceEnum();}

	else if (param.is(parametersPath.sequence)){
		sequence = sequencePath.getKey();
		if(sequence!=""){
			script.log("watching "+ sequence);
			local.parameters.sequence.setAttribute("readonly",true);

		}
		
	}

	else{script.log("received module param :" + param.name);}
}

function updateSynchronize(){
	doSync = parametersPath.synchronize.get();
	script.log(doSync ? "sync ON" : "sync OFF" );
}

function updateSyncRate(){
	syncRatems = parametersPath.syncRate.get() / 1000.;
	script.log("new sync rate : " + syncRatems);
	// script.setUpdateRate(syncRatems);

}

//refresh Enum
function refreshSequenceEnum(){
	script.log("refresh list of sequences");
	local.parameters.sequence.setAttribute("readonly",false);
	
	if(root.sequences.getItems().length){		
		local.parameters.sequence.removeOptions();
		local.parameters.sequence.addOption("", 0);
		for(var i=0 ; i<root.sequences.getItems().length ; i++ ){
			local.parameters.sequence.addOption(root.sequences.getItems()[i].name,i+1);
		}
	}

}

function importSequenceFile(loadFile){

	doSync = false ;
	script.log("loading file");
	loadData = loadFile.readFile(true);

	//load parameters
	var parameters = local.getChild("parameters");
	parameters.syncRate.set(loadData.parameters.SyncRate);
	parameters.synchronize.set(loadData.parameters.Synchronize);
	sequence = loadData.parameters.Sequence;
	if(1){

		parameters.sequence.removeOptions();
		parameters.sequence.addOption(sequence,0);
		parameters.sequence.setAttribute("readonly", true);
		// script.log(parameters.synchronize.get());
		// 
		//check if Sequence already exists in sequences manager, else create it
		var tl_sequence = root.sequences.getItemWithName(sequence) ;
		if(tl_sequence == undefined){
			tl_sequence = root.sequences.addItem();
			tl_sequence.setName(sequence);
		}

		//recreate cues
		tl_sequence.cues.removeAll();
		var cuesList = util.getObjectProperties(loadData.values.keys.cues, true, false);
		if(cuesList.length){
			for(var i=0; i<cuesList.length; i++){
				var cue = tl_sequence.cues.addItem();
				cue.setName(cuesList[i]);
				cue.time.set(loadData.values.keys.cues[cuesList[i]].time);
			}
		}

		//recreate layers and keys
		tl_sequence.layers.removeAll();
		var layersList = util.getObjectProperties(loadData.values.keys.layers, true, false);
		if(layersList.length){
			for(var i=0; i<layersList.length; i++ ){
				var layer = tl_sequence.layers.addItem("Mapping");
				layer.setName(layersList[i]);
				var keysList = util.getObjectProperties(loadData.values.keys.layers[layersList[i]], true, false);
				if(keysList.length){
					for(var j=0; j<keysList.length; j++){
						var key = layer.automation.addItem();
						key.setName(keysList[j]);
						key.value.set(loadData.values.keys.layers[layersList[i]][keysList[j]].value);
						key.position.set(loadData.values.keys.layers[layersList[i]][keysList[j]].time);
					}
				}
				layer.automation.reorderItems();
			}
		}

		//recreate groups
		var groupList = util.getObjectProperties(loadData.values.groups, true, false);
		if(groupList.length){
			for(var i=0; i<groupList.length; i++){
				var group = local.getChild("Values").groups.addContainer(groupList[i]);
				var groupLayers = util.getObjectProperties(loadData.values.groups[groupList[i]], true, false);
				var cue = group.addFloatParameter("cue", "", 0., 0.);
				group.setName(groupList[i]);
				cue.set(loadData.values.groups[groupList[i]].time);

				var groupKeysList = util.getObjectProperties(loadData.values.groups[groupList[i]].groupKeys, true, false);
				if (groupKeysList.length){
					var keysContainer = group.addContainer("keys");
					keysContainer.setCollapsed(true);
					for (var j=0; j<groupKeysList.length; j++){
						group.addFloatParameter(groupKeysList[j], "", 0., 0., 1.);
						keysContainer.addStringParameter(groupKeysList[j], "", loadData.values.groups[groupList[i]]['groupKeys'][groupKeysList[j]]['key']);
					}
				}
			}
		}

		// script.log(layersList[0]);
		doSync = true;
		// updateSynchronize() ;
	}


}

function exportSequenceFile(fileObj){
	script.log("exporting file");
	var exportData = {parameters:{}, values:{groups:{}, keys:{cues:{}, layers:{}}}};

	//collect parameters 
	var parameters = local.getChild("parameters");
	exportData.parameters["Sequence"] = parameters.sequence.getKey();
	exportData.parameters["Synchronize"] = parameters.synchronize.get();
	exportData.parameters["Sync Rate"] = parameters.syncRate.get();

	//collect values
	var values = local.getChild("values");
	var groups = values.groups;
	var groupsList=util.getObjectProperties(groups, true, false);
	if(groupsList.length){
		for(var i=0; i<groupsList.length; i++){
			var exportGroup = exportData.values.groups[groupsList[i]] = {cue:"", time:0., groupKeys:{}};
			var currentGroup = groups.getChild(groupsList[i]);
			exportGroup.cue = currentGroup.cue.name;
			exportGroup.time = currentGroup.cue.get();
			var currentGroupLayers = util.getObjectProperties(currentGroup.keys, true, false);
			if (currentGroupLayers.length){
				for(var j=0; j<currentGroupLayers.length; j++){
					// script.log(groupsList[i]+ "  "+ currentGroupLayers[j]);
					exportGroup.groupKeys[currentGroupLayers[j]] = {key:"", value:0};
					exportGroup.groupKeys[currentGroupLayers[j]].value = currentGroup.getChild(currentGroupLayers[j]).get();
					exportGroup.groupKeys[currentGroupLayers[j]].key = currentGroup.keys.getChild(currentGroupLayers[j]).get();
				}
			}
		}
	}

	var cues = values.keys.cues;
	var cuesList=util.getObjectProperties(cues, true, false);
	if(cuesList.length){
		for(var i=0; i<cuesList.length; i++){
			var exportCue = exportData.values.keys.cues[cuesList[i]] = {cue:"", time:0.};
			exportCue.cue = cuesList[i];
			exportCue.time = cues.getChild(cuesList[i]).time.get();
			
		}
	}

	var layers = values.keys.layers;
	var layersList=util.getObjectProperties(layers, true, false);
	if(layersList.length){
		for(var i=0; i<layersList.length; i++){
			var exportLayer = exportData.values.keys.layers[layersList[i]] = {};
			var currentLayer = layers.getChild(layersList[i]);
			var currentLayersKeys = util.getObjectProperties(currentLayer, true, false);
			if (currentLayersKeys.length){
				for(var j=0; j<currentLayersKeys.length; j++){
					// script.log(groupsList[i]+ "  "+ currentGroupLayers[j]);
					exportLayer[currentLayersKeys[j]] = {key:"", value:0., time:0.};
					exportLayer[currentLayersKeys[j]].value = currentLayer.getChild(currentLayersKeys[j]).value.get();
					exportLayer[currentLayersKeys[j]].key = currentLayer.getChild(currentLayersKeys[j]).name;
					exportLayer[currentLayersKeys[j]].time = currentLayer.getChild(currentLayersKeys[j]).time.get();
				}
			}
		}
	}

	// exportData.groups
	fileObj.writeFile(JSON.stringify(exportData), true);
}




///////////////////////		 VALUES FUNCTIONS		///////////////////////
/* Values hold all keys, presented in group containers
a nogroup container shows keys that are not grouped
*/

// Value callback
function moduleValueChanged(value){
	if(!inibValuesChanged){
		doSync = false;

		script.log(value.getParent().name);

		doSync = true;
	
	}

	if (value.is(local.values.newGroup.create)){createNewGroup();}
	// script.log(value.getParent().name);
	// if(value.getParent().name = "cue"){script.log("changed");}
	if (value.name == "addGroup"){createNewGroup();}
}


//rebuild values.keys structure from sequence
function struct_buildValuesFromSeq(){
	
	inibValuesChanged = true;
	var hasUpdated = false ;
	
	var tl_seq = root.sequences.getItemWithName(sequence);
	
	if(tl_seq.name!="undefined"){
		//build cues if needed
		var tl_cues = tl_seq.cues.getItems();
		cues = local.getChild("values").keys.cues ;
		var cuesList = util.getObjectProperties(cues, true, false);
		// script.log("cueList : " +cuesList.length);
		// script.log("tl List : " +tl_cues.length);
		if (cuesList.length != tl_cues.length){
			
			var delta = cuesList.length-tl_cues.length;
			var addRemove = delta > 0 ? false : true ; //0 to remove, 1 to add
			
			delta = Math.abs(delta);
			script.log("cues "+ delta + (addRemove ? " up" : " down"));
			for(var i=0; i<delta; i++){
				// script.log(i);
				if(addRemove){
					var newCue = cues.addContainer("newCue"+i);
					newCue.addFloatParameter("time", "position in time", 0., 0.);
					newCue.setCollapsed(true);
				}
				else {
					script.log(util.getObjectProperties(cues, true, false)[0]);
					cues.removeContainer(util.getObjectProperties(cues, true, false)[0]);
				}
				// cuesList = ;
				
			}
			hasUpdated = true;
		}

		//update cues
		cues = local.getChild("values").keys.cues ;
		var cuesList = util.getObjectProperties(cues, true, false);
		if(tl_cues.length){
			for (var i=0; i<tl_cues.length; i++){
				var currentCue = cues.getChild(cuesList[i]);
				currentCue.setName(tl_cues[i].name);
				currentCue.time.set(tl_cues[i].time.get());
			}
		}

		
		//build layers if needed
		var layersChanged = false ;
		var tl_layers = tl_seq.layers.getItems();
		layers = local.getChild("values").keys.layers ;
		var layersList = util.getObjectProperties(layers, true, false);
		if (layersList.length != tl_layers.length){
			layersChanged = true ;
			var delta = layersList.length-tl_layers.length;
			var addRemove = delta > 0 ? false : true ; //0 to remove, 1 to add
			delta = Math.abs(delta);
			script.log("layers "+ delta + (addRemove ? " up" : " down"));
			for(var i=0; i<delta; i++){
				// script.log(i);
				if(addRemove){
					var newLayer = layers.addContainer("newLayer"+i);
					// newLayer.addFloatParameter("time", "position in time", 0., 0.);
					newLayer.setCollapsed(true);
					local.getChild("values").newGroup.layers.addFloatParameter("newLayer"+i, "value for this layer at group creation", 0., 0., 1.);
				}
				else {
					script.log(util.getObjectProperties(layers, true, false)[0]);
					layers.removeContainer(util.getObjectProperties(layers, true, false)[0]);
					local.getChild("values").newGroup.layers.removeContainer(util.getObjectProperties(layers, true, false)[0]);
				}
				// cuesList = ;
				
			}
			hasUpdated = true;
		}
		//update layers value if there was a change in structure
		if(layersChanged){
			layers = local.getChild("values").keys.layers ;
			var layerList = util.getObjectProperties(layers, true, false);
			var template = local.getChild("values").newGroup.layers;
			var layerTemplate = util.getObjectProperties(template, true, false);

			if(tl_layers.length){
				for (var i=0; i<tl_layers.length; i++){
					var currentLayer = layers.getChild(layerList[i]);
					currentLayer.setName(tl_layers[i].name);
					var currentTemplate = template.getChild(layerTemplate[i]) ;
					currentTemplate.setName(tl_layers[i].name);
				}
			}
		}

		//build keys if needed
		layers = local.getChild("values").keys.layers ;
		layersList = util.getObjectProperties(layers, true, false);
		
		if(layersList.length){
			for(var layerIndex=0; layerIndex<layersList.length; layerIndex++){

				var currentLayer = layers.getChild(layersList[layerIndex]);
				var keyList = util.getObjectProperties(currentLayer, true, false);

				var tl_lay = tl_seq.layers.getItemWithName(layersList[layerIndex]);
				var tl_keys;
				if(tl_lay.automation!=undefined){tl_keys = tl_lay.automation.getItems();}
				//rebuild key structure for currentLayer
				if (keyList.length != tl_keys.length){
					var delta = keyList.length-tl_keys.length;
					var addRemove = delta > 0 ? false : true ; //0 to remove, 1 to add
					delta = Math.abs(delta);
					script.log("keys "+ delta + (addRemove ? " up" : " down"));
					for(var i=0; i<delta; i++){
						
						// script.log(i);
						if(addRemove){
							var newKey = currentLayer.addContainer("newkey"+i);
							newKey.addFloatParameter("time", "position in time", 0., 0.);
							newKey.addFloatParameter("value", "vertical value", 0., 0.);
							newKey.setCollapsed(true);
						}
						else {
							script.log(util.getObjectProperties(currentLayer, true, false)[0]);
							currentLayer.removeContainer(util.getObjectProperties(currentLayer, true, false)[0]);
						}		
						
						
					}
					hasUpdated = true;
				}

				currentLayer = layers.getChild(layersList[layerIndex]);
				keyList = util.getObjectProperties(currentLayer, true, false);
				//update values for currentLayer
				if(tl_keys.length){
					for(var i=0; i<tl_keys.length; i++){
						var currentKey = currentLayer.getChild(keyList[i]);
						currentKey.setName(tl_keys[i].name);
						currentKey.time.set(tl_keys[i].position.get());
						currentKey.value.set(tl_keys[i].value.get());

					}
				}
			}
		}

		//Groups
		tl_seq = root.sequences.getItemWithName(sequence);
		var groups = local.getChild("values").groups ;
		var groupList = util.getObjectProperties(groups, true, false);
		// printMethodsAndProperties(tl_seq.cues.getItemWithName("group0"));
		if(groupList.length){
			for (var i = 0; i<groupList.length; i++){
				//check if cue exist, else remove group
				// script.log(groupList[i]);
				var groupCue = tl_seq.cues.getItemWithName(groupList[i]);
				if(groupCue.name==undefined){
					script.log("cue " + groupList[i] + "not found, removing group (keys survive this)");
					groups.removeContainer(groupList[i]);
					hasUpdated = true;
					break;
				}

				//else check at key level
				else {
					groups = local.getChild("values").groups ;
					groupList = util.getObjectProperties(groups, true, false);
					var currentGroup = groups.getChild(groupList[i]);
					var currentGroupLayers = util.getObjectProperties (currentGroup.keys, true, false);
					//update cue time
					var groupTime = groupCue.time.get();
					currentGroup.cue.set(groupTime);

					if (currentGroupLayers.length){
						// script.log(currentGroupLayers.length);
						for(var j=0; j<currentGroupLayers.length; j++){
							// script.log("in loop" + j);
							groups = local.getChild("values").groups ;
							groupList = util.getObjectProperties(groups, true, false);
							currentGroup = groups.getChild(groupList[i]);
							currentGroupLayers = util.getObjectProperties (currentGroup.keys, true, false);
							var tl_layer = tl_seq.layers.getItemWithName(currentGroupLayers[j]);
							var keyName = currentGroup.keys.getChild(tl_layer.name).get();
							// script.log(tl_layer.name + "  " +tl_layer.automation.getItemWithName(keyName).name);
							//if key dosn't exist anymore, remove it from group
							if(tl_layer.automation.getItemWithName(keyName).name == undefined){
								groups = local.getChild("values").groups ;
								groupList = util.getObjectProperties(groups, true, false);
								currentGroup = groups.getChild(groupList[i]);
								currentGroupLayers = util.getObjectProperties (currentGroup.keys, true, false);
								tl_layer = tl_seq.layers.getItemWithName(currentGroupLayers[j]);
								keyName = currentGroup.keys.getChild(tl_layer.name).get();
								script.log("should remove" + currentGroup.name + "  " + currentGroupLayers[j]);
								currentGroup.keys.removeParameter(currentGroupLayers[j]);
								currentGroup.removeParameter(currentGroupLayers[j]);
								currentGroup.setCollapsed(true);
								currentGroup.setCollapsed(false);
								hasUpdated = true;
								
							}
							//if key exists, update value from tl and update time from group cue
							else{
								//apply groupTime
								var tl_key = tl_layer.automation.getItemWithName(keyName);
								tl_key.position.set(groupTime);
								//get tl value
								var keyValue = tl_key.value.get();
								
								var currentKey = currentGroup.getChild(tl_layer.name);
								// script.log(tl_layer.name + "  " +keyName+"  " + keyValue);
								// script.log(currentKey.name + "  " +keyName+"  " + keyValue);
								currentKey.set(keyValue);
								// script.log(currentKey.get());
							}
						}
					}
					// //if cue doesn't exist, remove whole group
					// if(tl_layers.length){
					// 	for (var j=0; j<tl_layers.length; j++){
					// 		if(!tl_layers[j].automation.getItemWithName(groupList[i])){
					// 			script.log("key " + groupList[i] + "not found, removing group (keys survive this)");
					// 			groups.removeContainer(groupList[i]);}
					// 			hasUpdated = true;
					// 	}
					// }

					//update group values
					
					
				}
			}
		}


		inibValuesChanged = false;
		return hasUpdated;
	}
	

}


function struct_rebuildGroupsFromSeq(){


}


// function rebuildValuesStructure() {
// 	script.log("updating values structure");
// 	//empty current structure 
// 	// local.values.removeAll();
// 	local.getChild("Values").removeContainer("newGroup");
// 	local.getChild("Values").removeContainer("groups");
// 	local.getChild("Values").removeContainer("ungrouped");

// 	//rebuild containers
// 	var ng_cont = local.values.addContainer("New group");
// 	var g_cont = local.values.addContainer("groups");
// 	var ug_cont = local.values.addContainer("ungrouped");
	
// 	// rebuild new group
// 	ng_cont.addTrigger("add group", "adds a new group at cursor time with below values");
// 	ng_cont.addFloatParameter("group time", "time position where the group will be created ", 0., 0.);
// 	var layer_cont = ng_cont.addContainer("layers values");
// 	var layers = util.getObjectProperties(sequence_structure.keys.layers) ;
// 	for (var i=0; i<layers.length; i++){
// 		//add a float value in each layer for group creation
// 		layer_cont.addFloatParameter(layers[i], "", 0., 0., 1.);
// 		ug_cont.addContainer(layers[i]);
// 	}

// 	//rebuild keys grouped/ungrouped
// 	//first create group containers in groups 

// 	// //then create layer containers in ungrouped
// 	// var layer_cont = ug_cont.addContainer("layers values");
	
// }

///////////////////////		TIMELINE FUNCTIONS		///////////////////////

function seq_clearSequence(){

	var seq = root.sequences.getItemWithName(sequence) ;
	script.log("clearing all keys and cues of sequence : "+seq.name);
	seq.cues.removeAll();
	var layers = seq.layers.getItems();
	if(layers.length){
		for (var i = 0; i<layers.length; i++){
			if(layers[i].automation){layers[i].automation.removeAll();}
		}
	}

	//clear all groups
	var groups = local.getChild("values").groups;
	var groupsList = util.getObjectProperties(groups, true, false);
	if (groupsList.length){
		for(var i=0; i<groupsList.length; i++){
			groups.removeContainer(groupsList[i]);
		}
	}
	
	

}

//use Values structure to rebuild the sequence
function seq_buildSeqFromValues(){}

//use file to rebuild sequence
function seq_buildSeqFromFile(){}


function createNewGroup(){
	script.log("create new group");
	//create a cue and a key in each layer at cursor position in selected sequence
	var groups = local.getChild("values").groups;
	var groupsList = util.getObjectProperties(groups, true, false);
	// var index = groupsList.length == undefined ? 0 : groupsList.length;
	var currentGroup;

	var tl_seq = root.sequences.getItemWithName(sequence);
	var tl_layers = tl_seq.layers.getItems();
	script.log(groupList.length);

	//Get current sequence time position and create cue at this position, with group name
	var currentTime = tl_seq.currentTime.get() ;
	// var currentTime = local.values.newGroup.groupTime.get();
	script.log(currentTime);
	newCue = tl_seq.cues.addItem();
	newCue.time.set(currentTime);
	//test for holes in the sequence to rename the cue

	for (var i=0; i<=groupsList.length+1; i++){
		if(tl_seq.cues.getChild("group"+i)==undefined){
			newCue.setName("group"+i);
			currentGroup = groups.addContainer("group"+i);
			script.log("create new group: group"+i);
			break;
		}
	}
 
	
	
	currentGroup.addFloatParameter(newCue.name, "cue of the group", currentTime, 0.);
	var keysContainer = currentGroup.addContainer("keys");
	keysContainer.setCollapsed(true);
	tl_seq = root.sequences.getItemWithName(sequence);
	tl_layers = tl_seq.layers.getItems();
	// var struc_layers = util.getObjectProperties(sequence_structure.keys.layers);
	if(tl_layers.length){
		for(var i=0;i<tl_layers.length; i++ ){
			if(tl_layers[i].automation!=undefined){//only for mapping layers
				// script.log(sequence_structure.keys.layers[layers[i].name]);
				var newKey = tl_layers[i].automation.addItem();
				newKey.position.set(currentTime);
				script.log([layers[i].name]);  //local.getChild("values").newGroup.layers.getChild().name
				newKey.value.set(local.getChild("values").newGroup.layers.getChild(tl_layers[i].name).get());
				// newKey.value.set(Math.random());
				keysContainer.addStringParameter(tl_layers[i].name, "",newKey.name );
				currentGroup.addFloatParameter(tl_layers[i].name,tl_layers[i].name+" value" , newKey.value.get(), 0., 1.);
				// newKey.addStringParameter("group", "key is part of this group","mongroupe");
				tl_layers[i].automation.reorderItems();
			}
		}
	}
	// seq = seq.getItems();

}