'use strict'; var AudioControls = function() { }; AudioControls.prototype.groups = { "audio-select": ["btns_audio_tools", "btns_fade"] }; AudioControls.prototype.classes = { "btn-state-active": "btn btn-mini active", "btn-state-default": "btn btn-mini", "disabled": "disabled", "active": "active" }; AudioControls.prototype.events = { "btn_rewind": { click: "rewindAudio" }, "btn_play": { click: "playAudio" }, "btn_stop": { click: "stopAudio" }, "btn_cursor": { click: "changeState" }, "btn_select": { click: "changeState" }, "btn_shift": { click: "changeState" }, "btn_fadein": { click: "changeState" }, "btn_fadeout": { click: "changeState" }, "btns_fade": { click: "createFade" }, "btn_save": { click: "save" }, "btn_open": { click: "open" }, "btn_trim_audio": { click: "trimAudio" }, "time_format": { change: "changeTimeFormat" }, "audio_start": { blur: "validateCueIn" }, "audio_end": { blur: "validateCueOut" }, "audio_pos": { }, "audio_resolution": { change: "changeResolution" } }; AudioControls.prototype.validateCue = function(value) { var validators, regex, result; validators = { "seconds": /^\d+$/, "thousandths": /^\d+\.\d{3}$/, "hh:mm:ss": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]$/, "hh:mm:ss.u": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{1}$/, "hh:mm:ss.uu": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{2}$/, "hh:mm:ss.uuu": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{3}$/ }; regex = validators[this.timeFormat]; result = regex.test(value); return result; }; AudioControls.prototype.cueToSeconds = function(value) { var converter, func, seconds; function clockConverter(value) { var data = value.split(":"), hours = parseInt(data[0], 10) * 3600, mins = parseInt(data[1], 10) * 60, secs = parseFloat(data[2]), seconds; seconds = hours + mins + secs; return seconds; } converter = { "seconds": function(value) { return parseInt(value, 10); }, "thousandths": function(value) { return parseFloat(value); }, "hh:mm:ss": function(value) { return clockConverter(value); }, "hh:mm:ss.u": function(value) { return clockConverter(value); }, "hh:mm:ss.uu": function(value) { return clockConverter(value); }, "hh:mm:ss.uuu": function(value) { return clockConverter(value); } }; func = converter[this.timeFormat]; seconds = func(value); return seconds; }; AudioControls.prototype.cueFormatters = function(format) { function clockFormat(seconds, decimals) { var hours, minutes, secs, result; hours = parseInt(seconds / 3600, 10) % 24; minutes = parseInt(seconds / 60, 10) % 60; secs = seconds % 60; secs = secs.toFixed(decimals); result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (secs < 10 ? "0" + secs : secs); return result; } var formats = { "seconds": function (seconds) { return seconds.toFixed(0); }, "thousandths": function (seconds) { return seconds.toFixed(3); }, "hh:mm:ss": function (seconds) { return clockFormat(seconds, 0); }, "hh:mm:ss.u": function (seconds) { return clockFormat(seconds, 1); }, "hh:mm:ss.uu": function (seconds) { return clockFormat(seconds, 2); }, "hh:mm:ss.uuu": function (seconds) { return clockFormat(seconds, 3); } }; return formats[format]; }; AudioControls.prototype.init = function(config) { var that = this, className, event, events = this.events, tmpEl, func, state, container, tmpBtn; makePublisher(this); this.ctrls = {}; this.config = config; container = this.config.getContainer(); state = this.config.getState(); tmpBtn = document.getElementsByClassName("btn_"+state)[0]; if (tmpBtn) { this.activateButton(tmpBtn); } for (className in events) { tmpEl = container.getElementsByClassName(className)[0]; this.ctrls[className] = tmpEl; for (event in events[className]) { if (tmpEl) { func = that[events[className][event]].bind(that); tmpEl.addEventListener(event, func); } } } if (this.ctrls["time_format"]) { this.ctrls["time_format"].value = this.config.getTimeFormat(); } if (this.ctrls["audio_resolution"]) { this.ctrls["audio_resolution"].value = this.config.getResolution(); } this.timeFormat = this.config.getTimeFormat(); //Kept in seconds so time format change can update fields easily. this.currentSelectionValues = undefined; this.onCursorSelection({ start: 0, end: 0 }); }; AudioControls.prototype.changeTimeFormat = function(e) { var format = e.target.value, func, start, end; format = (this.cueFormatters(format) !== undefined) ? format : "hh:mm:ss"; this.config.setTimeFormat(format); this.timeFormat = format; if (this.currentSelectionValues !== undefined) { func = this.cueFormatters(format); start = this.currentSelectionValues.start; end = this.currentSelectionValues.end; if (this.ctrls["audio_start"]) { this.ctrls["audio_start"].value = func(start); } if (this.ctrls["audio_end"]) { this.ctrls["audio_end"].value = func(end); } } }; AudioControls.prototype.changeResolution = function(e) { var res = parseInt(e.target.value, 10); this.config.setResolution(res); this.fire("changeresolution", res); }; AudioControls.prototype.validateCueIn = function(e) { var value = e.target.value, end, startSecs; if (this.validateCue(value)) { end = this.currentSelectionValues.end; startSecs = this.cueToSeconds(value); if (startSecs <= end) { this.notifySelectionUpdate(startSecs, end); this.currentSelectionValues.start = startSecs; return; } } //time entered was otherwise invalid. e.target.value = this.cueFormatters(this.timeFormat)(this.currentSelectionValues.start); }; AudioControls.prototype.validateCueOut = function(e) { var value = e.target.value, start, endSecs; if (this.validateCue(value)) { start = this.currentSelectionValues.start; endSecs = this.cueToSeconds(value); if (endSecs >= start) { this.notifySelectionUpdate(start, endSecs); this.currentSelectionValues.end = endSecs; return; } } //time entered was otherwise invalid. e.target.value = this.cueFormatters(this.timeFormat)(this.currentSelectionValues.end); }; AudioControls.prototype.activateButtonGroup = function(id) { var el = document.getElementById(id), btns, classes = this.classes, i, len; if (el === null) { return; } btns = el.getElementsByTagName("a"); for (i = 0, len = btns.length; i < len; i++) { btns[i].classList.remove(classes["disabled"]); } }; AudioControls.prototype.deactivateButtonGroup = function(id) { var el = document.getElementById(id), btns, classes = this.classes, i, len; if (el === null) { return; } btns = el.getElementsByTagName("a"); for (i = 0, len = btns.length; i < len; i++) { btns[i].classList.add(classes["disabled"]); } }; AudioControls.prototype.activateAudioSelection = function() { var ids = this.groups["audio-select"], i, len; for (i = 0, len = ids.length; i < len; i++) { this.activateButtonGroup(ids[i]); } }; AudioControls.prototype.deactivateAudioSelection = function() { var ids = this.groups["audio-select"], i, len; for (i = 0, len = ids.length; i < len; i++) { this.deactivateButtonGroup(ids[i]); } }; AudioControls.prototype.save = function() { this.fire('playlistsave', this); }; AudioControls.prototype.open = function() { this.fire('playlistrestore', this); }; AudioControls.prototype.rewindAudio = function() { this.fire('rewindaudio', this); }; AudioControls.prototype.playAudio = function() { this.fire('playaudio', this); }; AudioControls.prototype.stopAudio = function() { this.fire('stopaudio', this); }; AudioControls.prototype.activateButton = function(el) { if (el) { el.classList.add(this.classes["active"]); } }; AudioControls.prototype.deactivateButton = function(el) { if (el) { el.classList.remove(this.classes["active"]); } }; AudioControls.prototype.enableButton = function(el) { if (el) { el.classList.remove(this.classes["disabled"]); } }; AudioControls.prototype.disableButton = function(el) { if (el) { el.classList.add(this.classes["disabled"]); } }; AudioControls.prototype.changeState = function(e) { var el = e.currentTarget, prevEl = el.parentElement.getElementsByClassName('active')[0], state = el.dataset.state; this.deactivateButton(prevEl); this.activateButton(el); this.config.setState(state); this.fire('changestate', this); }; AudioControls.prototype.zeroCrossing = function(e) { var el = e.target, disabled, classes = this.classes; disabled = el.classList.contains(classes["disabled"]); if (!disabled) { this.fire('trackedit', { type: "zeroCrossing" }); } }; AudioControls.prototype.trimAudio = function(e) { var el = e.target, disabled, classes = this.classes; disabled = el.classList.contains(classes["disabled"]); if (!disabled) { this.fire('trackedit', { type: "trimAudio" }); } }; AudioControls.prototype.removeAudio = function(e) { var el = e.target, disabled, classes = this.classes; disabled = el.classList.contains(classes["disabled"]); if (!disabled) { this.fire('trackedit', { type: "removeAudio" }); } }; AudioControls.prototype.createFade = function(e) { var el = e.target, shape = el.dataset.shape, type = el.dataset.type, disabled, classes = this.classes; disabled = el.classList.contains(classes["disabled"]); if (!disabled) { this.fire('trackedit', { type: "createFade", args: { type: type, shape: shape } }); } }; AudioControls.prototype.onAudioSelection = function() { this.activateAudioSelection(); }; AudioControls.prototype.onAudioDeselection = function() { this.deactivateAudioSelection(); }; /* start, end in seconds */ AudioControls.prototype.notifySelectionUpdate = function(start, end) { this.fire('changeselection', { start: start, end: end }); }; /* start, end in seconds */ AudioControls.prototype.onCursorSelection = function(args) { var startFormat = this.cueFormatters(this.timeFormat)(args.start), endFormat = this.cueFormatters(this.timeFormat)(args.end), start = this.cueToSeconds(startFormat), end = this.cueToSeconds(endFormat); this.currentSelectionValues = { start: start, end:end }; if (this.ctrls["audio_start"]) { this.ctrls["audio_start"].value = startFormat; } if (this.ctrls["audio_end"]) { this.ctrls["audio_end"].value = endFormat; } }; /* args {seconds, pixels} */ AudioControls.prototype.onAudioUpdate = function(args) { if (this.ctrls["audio_pos"]) { this.ctrls["audio_pos"].innerHTML = this.cueFormatters(this.timeFormat)(args.seconds); } };