var sync_controller = function () {

//TODO: some of the public 'that' functions are actually private, no 'that' needed

//TODO: check if currently implemented behavior described below is appropriate:
// If a handler wants to set the media time, running of handlers is halted
// control passes back to syncer, media time is set, 
// handlers won't be run until next iteration of controller,
// and based on the newly set time plus syncer interval  

	var that = this;
	var handlers = new Array();
	//set defaults that setters can overwrite
	that.syncData;
	
	that.run = function (newSyncTime){
		that.syncData.checkUnsortedData(handlers, newSyncTime);
		return runHandlers(newSyncTime);
	};
	
	//Multiple data sources not part of framework in this version
	that.setData = function (dataSrc){
		that.syncData = dataSrc;
	};	
	
	that.addHandler = function (handlerRun){
		//TODO check for duplicates
		handlers.push(new syncHandler(handlerRun));
		return handlers.length;
	};
	
	that.insertHandler = function (handler, index){
		splice(index, 0, handler);
	};
	
	that.removeHandler = function (index){
		//TODO to keep sparseness in check if(length > ARBITRARY_NUMBER)rewrite array	
		handlers.splice(index, 1);	
	};
	
	that.getHandlers = function (){
		return that.handlers;
	};
	
	runHandlers = function (mediaTime){
	//http://stackoverflow.com/questions/500504/javascript-for-in-with-arrays
	//for..in isn't guaranteed to preserve element ordering whereas
	//this allows running handlers in a set order 
		for(i=0;i<handlers.length;i++){
			//check undefined in case of handler deletions in the middle
			//assumes possibility of dynamic deletion
			if( !(handlers[i] == undefined) ){
				//TODO test what happens if either are undefined
				if( (handlers[i].getActiveId == undefined) || (handlers[i].getSyncId() != handlers[i].getActiveId())){
					record = that.syncData.getDataRecord(handlers[i].getDataIndex());
					if (record['handler'] == 'notification') {
						record['data']['timecode'] = record['timecode'];
						handlers[i].run(mediaTime, record['data']);
					} else {
						handlers[i].setActiveId(handlers[i].getSyncId());
						newTime = handlers[i].run(mediaTime, record);
						if(!(newTime == undefined) && (newTime != null)){
							return newTime;
						}
					}
				}
		 	}
		}
	};
	
	return that;
};
