(function (context, $) { "use strict"; context.JK = context.JK || {}; context.JK.ConfigureTracksHelper2 = function (app) { var logger = context.JK.logger; var ASSIGNMENT = context.JK.ASSIGNMENT; var VOICE_CHAT = context.JK.VOICE_CHAT; var MAX_TRACKS = context.JK.MAX_TRACKS; var MAX_OUTPUTS = context.JK.MAX_OUTPUTS; var gearUtils = context.JK.GearUtils; var $parent = null; var $templateAssignablePort = null; var $templateTrackTarget = null; var $templateOutputTarget = null; var $unassignedInputsHolder = null; var $unassignedOutputsHolder = null; var $tracksHolder = null; var $outputChannelHolder = null; var $instrumentsHolder = null; var isDragging = false; // inputChannelFilter is an optional argument that is used by the Gear Wizard. // basically, if an input channel isn't in there, it's not going to be displayed function loadChannels(forceInputsToUnassign, inputChannelFilter) { var musicPorts = jamClient.FTUEGetChannels(); $unassignedInputsHolder.empty(); $unassignedOutputsHolder.empty(); var inputChannels = musicPorts.inputs; var outputChannels = musicPorts.outputs; // uncomment to add a bunch of bogus channels //inputChannels = inputChannels.concat(inputChannels.concat(inputChannels.concat(inputChannels))) context._.each(inputChannels, function (inputChannel) { if(inputChannelFilter && !(inputChannelFilter.indexOf(inputChannel.id) > -1)) { // skipping input channel because it's not in the filter return; } var $channel = $(context._.template($templateAssignablePort.html(), $.extend({}, inputChannel, {direction:'in'}), { variable: 'data' })); if(forceInputsToUnassign || inputChannel.assignment == ASSIGNMENT.UNASSIGNED) { unassignInputChannel($channel); } else if(inputChannel.assignment == ASSIGNMENT.CHAT) { // well, we can't show it as unused... if there were a place to show chat inputs, we would put it there. // but we don't have it, so just skip logger.debug("skipping chat channel ", inputChannel) return; } else { // find the track this belongs in var trackNumber = inputChannel.assignment - 1; // plop down a track holder on the UI addChannelToTrack($channel, trackNumber); } }) var outputAssignment = 0; context._.each(outputChannels, function (outputChannel, index) { var $channel = $(context._.template($templateAssignablePort.html(), $.extend({}, outputChannel, {direction:'out'}), { variable: 'data' })); if(outputChannel.assignment == ASSIGNMENT.UNASSIGNED) { unassignOutputChannel($channel); } else { var $output = $outputChannelHolder.find('.output[data-num="' + outputAssignment + '"]'); outputAssignment++; if($output.length == 0) { context.JK.alertSupportedNeeded('Unable to find an output holder for channel: ' + outputChannel.id + ' with assignment ' + outputChannel.assignment); return false; } addChannelToOutput($channel, $output.find('.output-target')); } }); } // iterates through the dom and returns a pure data structure for track associations and output channels function getCurrentState() { var state = {}; state.tracks = []; state.unassignedChannels = []; state.outputs = []; var $unassignedInputChannels = $unassignedInputsHolder.find('.ftue-input'); var $unassignedOutputChannels = $unassignedOutputsHolder.find('.ftue-input'); var $tracks = $tracksHolder.find('.track-target'); var $outputs = $outputChannelHolder.find('.output-target'); context._.each($unassignedInputChannels, function($unassignedInput) { $unassignedInput = $($unassignedInput); var channelId = $unassignedInput.attr('data-input-id'); state.unassignedChannels.push(channelId); }) context._.each($unassignedOutputChannels, function($unassignedOutput) { $unassignedOutput = $($unassignedOutput); var channelId = $unassignedOutput.attr('data-input-id'); state.unassignedChannels.push(channelId); }) context._.each($tracks, function($track, index) { $track = $($track); var $assignedChannels = $track.find('.ftue-input'); var track = {index: index, channels:[]}; context._.each($assignedChannels, function($assignedChannel) { $assignedChannel = $($assignedChannel); track.channels.push($assignedChannel.attr('data-input-id')) }); // sparse array if(track.channels.length > 0) { state.tracks.push(track); } var $instrument = $instrumentsHolder.find('[data-num="' + index + '"]').find('.icon-instrument-select'); track.instrument_id = $instrument.data('instrument_id'); }) context._.each($outputs, function($output, index) { $output = $($output); var $assignedChannel = $output.find('.ftue-input'); // this is overkill since there should only be 1 or 0 .ftue-inputs in a given .output var outputSlot = {index: index, channels:[]}; context._.each($assignedChannel, function($assignedChannel) { $assignedChannel = $($assignedChannel); outputSlot.channels.push($assignedChannel.attr('data-input-id')) }); // sparse array if(outputSlot.channels.length > 0) { state.outputs.push(outputSlot); } }) return state; } function validate(tracks) { // there must be at least one assigned channel if(tracks.tracks.length == 0) { logger.debug("ConfigureTracks validation error: must have assigned at least one input port to a track."); context.JK.Banner.showAlert('Must have assigned at least one input port to a track.'); return false; } // there must be some instruments context._.each(tracks.tracks, function(track) { if(!track.instrument_id) { logger.debug("ConfigureTracks validation error: all tracks with ports assigned must specify an instrument."); context.JK.Banner.showAlert('Please use the instrument icons to choose what you plan to play on each track.'); return false; } }); // there must be exactly 2 output channels assigned if(tracks.outputs.length != 2 || (tracks.outputs[0].channels.length != 1 && track.outputs[1].channels.length != 1)) { logger.debug("ConfigureTracks validation error: must have assigned exactly two output ports"); context.JK.Banner.showAlert('Must have assigned exactly 2 output ports.'); return false; } return true; } function save(state) { context._.each(state.unassignedChannels, function(unassignedChannelId) { context.jamClient.TrackSetAssignment(unassignedChannelId, true, ASSIGNMENT.UNASSIGNED); }); // save input/tracks context._.each(state.tracks, function(track, index) { var trackNumber = index + 1; context._.each(track.channels, function(channelId) { context.jamClient.TrackSetAssignment(channelId, true, trackNumber); }); logger.debug("context.jamClient.TrackSetInstrument(trackNumber, track.instrument_id)", trackNumber, track.instrument_id); context.jamClient.TrackSetInstrument(trackNumber, context.JK.instrument_id_to_instrument[track.instrument_id].client_id); }); // save outputs context._.each(state.outputs, function(output, index) { context._.each(output.channels, function(channelId) { context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.OUTPUT); }); }); var result = context.jamClient.TrackSaveAssignments(); if(!result || result.length == 0) { // success return true; } else { context.JK.Banner.showAlert('Unable to save assignments. ' + result); return false; } } function loadTrackInstruments(forceInputsToUnassign) { var $trackInstruments = $instrumentsHolder.find('.track-instrument'); context._.each($trackInstruments, function(trackInstrument) { var $trackInstrument = $(trackInstrument); var trackIndex = parseInt($trackInstrument.attr('data-num')) + 1; var clientInstrument = context.jamClient.TrackGetInstrument(trackIndex); var instrument = context.JK.client_to_server_instrument_map[clientInstrument]; $trackInstrument.instrumentSelectorSet(instrument ? instrument.server_id : instrument); }); } function trySave() { var state = getCurrentState(); if(!validate(state)) { return false; } var saved = save(state); if(saved) { context.JK.GA.trackConfigureTracksCompletion(context.JK.detectOS()); } return saved; } function reset(forceInputsToUnassign, inputChannelFilter) { loadChannels(forceInputsToUnassign, inputChannelFilter); loadTrackInstruments(forceInputsToUnassign); } function unassignOutputChannel($channel) { var $originallyAssignedTrack = $channel.closest('.output-target'); $unassignedOutputsHolder.append($channel); $originallyAssignedTrack.attr('output-count', $originallyAssignedTrack.find('.ftue-input:not(.ui-draggable-dragging)').length); } function unassignInputChannel($channel) { var $originallyAssignedTrack = $channel.closest('.track-target'); $unassignedInputsHolder.append($channel); $originallyAssignedTrack.attr('track-count', $originallyAssignedTrack.find('.ftue-input:not(.ui-draggable-dragging)').length); } function addChannelToTrack($channel, $track) { var $originallyAssignedTrack = $channel.closest('.track-target'); $track.append($channel); $track.attr('track-count', $track.find('.ftue-input:not(.ui-draggable-dragging)').length); $originallyAssignedTrack.attr('track-count', $originallyAssignedTrack.find('.ftue-input:not(.ui-draggable-dragging)').length) } function addChannelToOutput($channel, $slot) { var $originallyAssignedTrack = $channel.closest('.output-target'); $slot.append($channel); $slot.attr('output-count', $slot.find('.ftue-input:not(.ui-draggable-dragging)').length); $originallyAssignedTrack.attr('output-count', $originallyAssignedTrack.find('.ftue-input:not(.ui-draggable-dragging)').length) } function initialize(_$parent) { $parent = _$parent; } this.initialize = initialize; this.trySave = trySave; this.reset = reset; return this; }; })(window, jQuery);