/* global Metamaps, $, Hogan, Bloodhound */
import React from 'react'
import ReactDOM from 'react-dom'
import DataModel from './DataModel'
import Engine from './Engine'
import MetacodeSelect from '../components/MetacodeSelect'
import Mouse from './Mouse'
import Selected from './Selected'
import Synapse from './Synapse'
import Topic from './Topic'
import Util from './Util'
import Visualize from './Visualize'
import GlobalUI from './GlobalUI'
const Create = {
isSwitchingSet: false, // indicates whether the metacode set switch lightbox is open
selectedMetacodeSet: null,
selectedMetacodeSetIndex: null,
selectedMetacodeNames: [],
newSelectedMetacodeNames: [],
selectedMetacodes: [],
newSelectedMetacodes: [],
recentMetacodes: [],
mostUsedMetacodes: [],
init: function (serverData) {
var self = Create
self.newTopic.init(serverData)
self.newSynapse.init()
// // SWITCHING METACODE SETS
$('#metacodeSwitchTabs').tabs({
active: self.selectedMetacodeSetIndex
}).addClass('ui-tabs-vertical ui-helper-clearfix')
$('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
$('.customMetacodeList li').click(self.toggleMetacodeSelected) // within the custom metacode set tab
},
toggleMetacodeSelected: function() {
var self = Create
if ($(this).attr('class') !== 'toggledOff') {
$(this).addClass('toggledOff')
var valueToRemove = $(this).attr('id')
var nameToRemove = $(this).attr('data-name')
self.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
self.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
} else if ($(this).attr('class') === 'toggledOff') {
$(this).removeClass('toggledOff')
self.newSelectedMetacodes.push($(this).attr('id'))
self.newSelectedMetacodeNames.push($(this).attr('data-name'))
}
},
updateMetacodeSet: function(set, index, custom) {
if (custom && Create.newSelectedMetacodes.length === 0) {
window.alert('Please select at least one metacode to use!')
return false
}
var codesToSwitchToIds
var metacodeModels = new DataModel.MetacodeCollection()
Create.selectedMetacodeSetIndex = index
Create.selectedMetacodeSet = 'metacodeset-' + set
if (!custom) {
codesToSwitchToIds = $('#metacodeSwitchTabs' + set).attr('data-metacodes').split(',')
$('.customMetacodeList li').addClass('toggledOff')
console.log(codesToSwitchToIds)
Create.selectedMetacodes = codesToSwitchToIds
Create.selectedMetacodeNames = DataModel.Metacodes.filter(m => codesToSwitchToIds.indexOf(m.id) > -1).map(m => m.get('name'))
Create.newSelectedMetacodes = codesToSwitchToIds
Create.newSelectedMetacodeNames = DataModel.Metacodes.filter(m => codesToSwitchToIds.indexOf(m.id) > -1).map(m => m.get('name'))
} else if (custom) {
// uses .slice to avoid setting the two arrays to the same actual array
Create.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
Create.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
codesToSwitchToIds = Create.selectedMetacodes.slice(0)
}
// sort by name
codesToSwitchToIds.forEach(id => {
const metacode = DataModel.Metacodes.get(id)
metacodeModels.add(metacode)
$('.customMetacodeList #' + id).removeClass('toggledOff')
})
metacodeModels.sort()
$('#metacodeImg').removeData('cloudcarousel')
var newMetacodes = ''
metacodeModels.each(function(metacode) {
newMetacodes += ''
})
$('#metacodeImg').empty().append(newMetacodes).CloudCarousel({
yRadius: 40,
xRadius: 190,
xPos: 170,
yPos: 40,
speed: 0.3,
bringToFront: true
})
Create.newTopic.setMetacode(metacodeModels.models[0].id)
GlobalUI.closeLightbox()
$('#topic_name').focus()
var mdata = {
'metacodes': {
'value': custom ? Create.selectedMetacodes.toString() : Create.selectedMetacodeSet
}
}
$.ajax({
type: 'POST',
dataType: 'json',
url: '/user/updatemetacodes',
data: mdata,
success: function(data) {
console.log('selected metacodes saved')
},
error: function() {
console.log('failed to save selected metacodes')
}
})
},
cancelMetacodeSetSwitch: function() {
var self = Create
self.isSwitchingSet = false
if (self.selectedMetacodeSet === 'metacodeset-custom') {
// reset it to the current actual selection
$('.customMetacodeList li').addClass('toggledOff')
for (var i = 0; i < self.selectedMetacodes.length; i++) {
$('#' + self.selectedMetacodes[i]).removeClass('toggledOff')
}
// uses .slice to avoid setting the two arrays to the same actual array
self.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0)
self.newSelectedMetacodes = self.selectedMetacodes.slice(0)
}
$('#metacodeSwitchTabs').tabs('option', 'active', self.selectedMetacodeSetIndex)
$('#topic_name').focus()
},
newTopic: {
init: function (serverData) {
const DOWN_ARROW = 40
const ESC = 27
if (!serverData.ActiveMapper) return
$('#topic_name').keyup(function (e) {
Create.newTopic.name = $(this).val()
if (e.which == DOWN_ARROW && !Create.newTopic.name.length) {
Create.newTopic.openSelector()
}
if (e.keyCode === ESC) {
Create.newTopic.hide()
} // if
})
$('.selectedMetacode').click(function() {
if (Create.newTopic.metacodeSelectorOpen) {
Create.newTopic.hideSelector()
$('#topic_name').focus()
} else Create.newTopic.openSelector()
})
Create.newTopic.initSelector()
var topicBloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/topics/autocomplete_topic?term=%QUERY',
wildcard: '%QUERY'
}
})
// initialize the autocomplete results for the metacode spinner
$('#topic_name').typeahead(
{
highlight: true,
minLength: 2
},
[{
name: 'topic_autocomplete',
limit: 8,
display: function(s) { return s.label },
templates: {
suggestion: function(s) {
return Hogan.compile($('#topicAutocompleteTemplate').html()).render(s)
}
},
source: topicBloodhound
}]
)
// tell the autocomplete to submit the form with the topic you clicked on if you pick from the autocomplete
$('#topic_name').bind('typeahead:select', function(event, datum, dataset) {
Create.newTopic.beingCreated = false
if (datum.rtype === 'topic') {
Topic.getTopicFromAutocomplete(datum.id)
} else if (datum.rtype === 'map') {
Topic.getMapFromAutocomplete({
id: datum.id,
name: datum.label
})
}
})
$('#topic_name').click(function() { Create.newTopic.hideSelector() })
// initialize metacode spinner and then hide it
$('#metacodeImg').CloudCarousel({
yRadius: 40,
xRadius: 190,
xPos: 170,
yPos: 40,
speed: 0.3,
bringToFront: true
})
$('#new_topic').hide()
.css({ left: '50%', top: '50%' })
.attr('oncontextmenu', 'return false') // prevents the mouse up event from opening the default context menu on this element
},
name: null,
newId: 1,
beingCreated: false,
metacodeSelectorOpen: false,
metacode: null,
x: null,
y: null,
addSynapse: false,
pinned: false,
initSelector: function () {
ReactDOM.render(
React.createElement(MetacodeSelect, {
onClick: function (id) {
Create.newTopic.setMetacode(id)
Create.newTopic.hideSelector()
$('#topic_name').focus()
},
close: function () {
Create.newTopic.hideSelector()
$('#topic_name').focus()
},
metacodes: DataModel.Metacodes.filter(m => Create.selectedMetacodes.indexOf(m.id.toString()) > -1)
}),
document.getElementById('metacodeSelector')
)
},
openSelector: function () {
Create.newTopic.initSelector()
$('#metacodeSelector').show()
Create.newTopic.metacodeSelectorOpen = true
$('.metacodeFilterInput').focus()
$('.selectedMetacode').addClass('isBeingSelected')
},
hideSelector: function () {
ReactDOM.unmountComponentAtNode(document.getElementById('metacodeSelector'))
$('#metacodeSelector').hide()
Create.newTopic.metacodeSelectorOpen = false
$('.selectedMetacode').removeClass('isBeingSelected')
},
setMetacode: function (id) {
Create.newTopic.metacode = id
var metacode = DataModel.Metacodes.get(id)
$('.selectedMetacode img').attr('src', metacode.get('icon'))
$('.selectedMetacode span').html(metacode.get('name'))
$.ajax({
type: 'POST',
dataType: 'json',
url: '/user/update_metacode_focus',
data: { value: id },
success: function (data) {},
error: function () {
console.log('failed to save metacode focus')
}
})
},
reset: function() {
$('#topic_name').typeahead('val', '')
Create.newTopic.hideSelector()
},
position: function() {
const pixels = Util.coordsToPixels(Visualize.mGraph, Mouse.newNodeCoords)
$('#new_topic').css({
left: pixels.x,
top: pixels.y
})
}
},
newSynapse: {
init: function() {
var synapseBloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/synapses?term=%QUERY',
wildcard: '%QUERY'
}
})
var existingSynapseBloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2',
prepare: function(query, settings) {
var self = Create.newSynapse
if (Selected.Nodes.length < 2 && self.topic1id && self.topic2id) {
settings.url = settings.url.replace('%TOPIC1', self.topic1id).replace('%TOPIC2', self.topic2id)
return settings
} else {
return null
}
}
}
})
// initialize the autocomplete results for synapse creation
$('#synapse_desc').typeahead(
{
highlight: true,
minLength: 2
},
[{
name: 'synapse_autocomplete',
display: function(s) { return s.label },
templates: {
suggestion: function(s) {
return Hogan.compile("