<commit_before>
_ = require 'lodash'
Chief = require 'behavior3-chief'
data = require './trees/tree.json'
memory = require './memory'
treeList = require './treeList'
nodeConfig = require './nodeConfig'
behaviorList = require './behaviorList'
alertify = require('./alertify').get()
keyboard = require './keyboard'

treeConfig = {
	container: '#treant',
	rootOrientation: 'NORTH',
	nodeAlign: 'TOP',
	levelSeparation: 50,
	siblingSeparation: 50,
	padding: 50,
	node: {
		collapsable: true
	}
	animation: {
		nodeSpeed: 100,
		connectorsSpeed: 0
	}
	connectors: {
		type: 'stepRounded',
		style: {
			'stroke-width': 7,
			'stroke': '#414141'
		}
	}
}

activeChief = null
tActiveTree = null
tActiveTreeHasRoot = null
tActiveNodeId = null
cActiveTree = null
cActiveNode = null
$container = null
highlightedEl = null
nodeMap = {}
$config = $('#commandConfig')
$erase = $('#commandErase')
$left = $('#commandMoveLeft')
$right = $('#commandMoveRight')
$contextmenu = $('#contextmenu')


clearDisables = ->
	$config.removeClass 'disabled'
	$left.removeClass 'disabled'
	$right.removeClass 'disabled'
	$erase.removeClass 'disabled'

clearHighlight = ->
	if highlightedEl
		highlightedEl.classList.remove 'highlight'
		highlightedEl.classList.remove 'highlightOrange'

registerClick = (treantConfig, callback) ->
	$container = $(treantConfig.container)
	$container.on 'click', (evt) ->
		if evt.target.classList.contains 'node'
			evt.preventDefault()
			cNodeId = evt.target.getAttribute 'cnodeid'
			cNode = cActiveTree.getNode cNodeId
			behavior = activeChief.getBehavior cNode.getBehaviorId()
			type = behavior.getType()
			if type is 'SUBTREE'
				config = cNode.getBehaviorConfig()
				treeList.openTree config.treeId
			else if behavior.isNative is false
				behaviorList.openBehavior behavior
		else
			tActiveNodeId = null
			nodeConfig.hideEditor()
			memory.disable '#tab-nodeEditor'
			$contextmenu.hide()
			clearHighlight()
			clearDisables()

registerRightClick = (treantConfig, callback) ->
	$container = $(treantConfig.container)

	$container.on 'contextmenu', (evt) ->
		if evt.target.classList.contains 'node'
			# visual changes
			clearDisables()
			evt.preventDefault()
			clearHighlight()
			evt.target.classList.add 'highlight'
			highlightedEl = evt.target

			# id's and positions
			cNodeId = evt.target.getAttribute 'cnodeid'
			tNodeId = parseInt evt.target.getAttribute 'tnodeid'
			$contextmenu.attr 'cnodeid', cNodeId
			$contextmenu.attr 'tnodeid', tNodeId
			$contextmenu.show().css({
				top: evt.clientY - 20,
				left: evt.clientX - 20
			})

			leftNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'leftNeighborId'
			rightNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'rightNeighborId'
			unless leftNeighborTId
				$left.addClass 'disabled'
			unless rightNeighborTId
				$right.addClass 'disabled'

	$erase.on 'click', (evt) ->
		if $erase.hasClass 'disabled' then return
		that = $(this)
		alertify.confirm 'Delete node?', ->
			# user clicked "ok"
			cNodeId = that.parent().attr 'cnodeid'
			tNodeId = parseInt that.parent().attr 'tnodeid'
			parentId = tActiveTree.getNodeAttribute(tNodeId, 'parentId')
			tActiveTree.removeNode tNodeId
			if parentId is -1 then tActiveTreeHasRoot = false
			callback {action: 'removeNode', cNodeId: cNodeId}
			$contextmenu.hide()
		, ->
			# user clicked "cancel"
			$contextmenu.hide()

	$left.on 'click', (evt) ->
		if $left.hasClass 'disabled' then return
		cNodeIdA = $(this).parent().attr 'cnodeid'
		tNodeId = parseInt $(this).parent().attr 'tnodeid'
		leftNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'leftNeighborId'
		cNodeIdB = tActiveTree.getNodeAttribute leftNeighborTId, 'cNodeId'
		tActiveTree.switchIndexes tNodeId, leftNeighborTId
		callback {action: 'switchNodes', cNodeIdA: cNodeIdA, cNodeIdB: cNodeIdB}
		$contextmenu.hide()

	$right.on 'click', (evt) ->
		if $right.hasClass 'disabled' then return
		cNodeIdA = $(this).parent().attr 'cnodeid'
		tNodeId = parseInt $(this).parent().attr 'tnodeid'
		rightNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'rightNeighborId'
		cNodeIdB = tActiveTree.getNodeAttribute rightNeighborTId, 'cNodeId'
		tActiveTree.switchIndexes tNodeId, rightNeighborTId
		callback {action: 'switchNodes', cNodeIdA: cNodeIdA, cNodeIdB: cNodeIdB}
		$contextmenu.hide()

	$config.on 'click', (evt) ->
		if $config.hasClass 'disabled' then return
		tNodeId = $(this).parent().attr 'tnodeid'
		tNode = tActiveTree.getNode(tNodeId).nodeDOM

		if tActiveNodeId != tNodeId
			if tActiveNodeId then tNode.classList.remove 'highlight'
			if tActiveNodeId then tNode.classList.remove 'highlightOrange'
			highlightedEl = tNode
			tActiveNodeId = tNodeId
			tNode.classList.add 'highlight'
			cNodeId = $(this).parent().attr 'cnodeid'
			cActiveNode = cActiveTree.getNode cNodeId
			callback {action: 'showNodeMemory', cNodeId: cNodeId}
			memory.activate '#tab-nodeEditor'
			nodeConfig.load cActiveNode
			nodeConfig.positionEditor tNode
			nodeConfig.showEditor()
		else
			highlightedEl = null
			tActiveNodeId = null
			nodeConfig.hideEditor()
			tNode.classList.remove 'highlight'
			tNode.classList.remove 'highlightOrange'
		$contextmenu.hide()

	window.addEventListener 'resize', (evt) ->
		if tActiveTree
			tActiveTree.resize()


dragNode = (evt) ->
	transfer = JSON.stringify
		type: 'change',
		tid: evt.target.getAttribute('tnodeid'),
		cid: evt.target.getAttribute('cnodeid')

	evt.originalEvent.dataTransfer.setData 'text/plain', transfer

registerDragAndDrop = (treantConfig, callback) ->
	$container = $(treantConfig.container)
	$container.on 'dragover', (evt) ->
		if tActiveTreeHasRoot is false
			evt.preventDefault()
		else if evt.target.classList.contains 'node'
			# check if accepts children
			parentCId = evt.target.getAttribute 'cnodeid'
			if cActiveTree.canNodeAcceptChild parentCId
				evt.preventDefault()
				if evt.ctrlKey
					evt.target.classList.add 'highlightOrange'
					evt.target.classList.remove 'highlight'
				else
					evt.target.classList.add 'highlight'
					evt.target.classList.remove 'highlightOrange'

	$container.on 'dragleave', (evt) ->
		if evt.target.classList.contains 'node'
			evt.target.classList.remove 'highlight'
			evt.target.classList.remove 'highlightOrange'

	$container.on 'drop', (evt) ->
		if tActiveTreeHasRoot is false
			evt.preventDefault()
			obj = JSON.parse evt.originalEvent.dataTransfer.getData 'text'
			callback {action: 'createRoot', behaviorId: obj.behaviorId}

		else if evt.target.classList.contains 'node'

			evt.preventDefault()
			evt.target.classList.remove 'highlight'
			evt.target.classList.remove 'highlightOrange'

			obj = JSON.parse evt.originalEvent.dataTransfer.getData 'text'
			parentCId = evt.target.getAttribute 'cnodeid'
			parentTId = parseInt evt.target.getAttribute 'tnodeid'

			if evt.ctrlKey
				# change node type
				callback {action: 'replaceNode', behaviorId: obj.behaviorId, parentCId: parentCId, parentTId: parentTId}
			else
				# add node
				switch obj.type<commit_msg>Override of AcceptsChildren for replace<commit_after>
_ = require 'lodash'
Chief = require 'behavior3-chief'
data = require './trees/tree.json'
memory = require './memory'
treeList = require './treeList'
nodeConfig = require './nodeConfig'
behaviorList = require './behaviorList'
alertify = require('./alertify').get()
keyboard = require './keyboard'

treeConfig = {
	container: '#treant',
	rootOrientation: 'NORTH',
	nodeAlign: 'TOP',
	levelSeparation: 50,
	siblingSeparation: 50,
	padding: 50,
	node: {
		collapsable: true
	}
	animation: {
		nodeSpeed: 100,
		connectorsSpeed: 0
	}
	connectors: {
		type: 'stepRounded',
		style: {
			'stroke-width': 7,
			'stroke': '#414141'
		}
	}
}

activeChief = null
tActiveTree = null
tActiveTreeHasRoot = null
tActiveNodeId = null
cActiveTree = null
cActiveNode = null
$container = null
highlightedEl = null
nodeMap = {}
$config = $('#commandConfig')
$erase = $('#commandErase')
$left = $('#commandMoveLeft')
$right = $('#commandMoveRight')
$contextmenu = $('#contextmenu')


clearDisables = ->
	$config.removeClass 'disabled'
	$left.removeClass 'disabled'
	$right.removeClass 'disabled'
	$erase.removeClass 'disabled'

clearHighlight = ->
	if highlightedEl
		highlightedEl.classList.remove 'highlight'
		highlightedEl.classList.remove 'highlightOrange'

registerClick = (treantConfig, callback) ->
	$container = $(treantConfig.container)
	$container.on 'click', (evt) ->
		if evt.target.classList.contains 'node'
			evt.preventDefault()
			cNodeId = evt.target.getAttribute 'cnodeid'
			cNode = cActiveTree.getNode cNodeId
			behavior = activeChief.getBehavior cNode.getBehaviorId()
			type = behavior.getType()
			if type is 'SUBTREE'
				config = cNode.getBehaviorConfig()
				treeList.openTree config.treeId
			else if behavior.isNative is false
				behaviorList.openBehavior behavior
		else
			tActiveNodeId = null
			nodeConfig.hideEditor()
			memory.disable '#tab-nodeEditor'
			$contextmenu.hide()
			clearHighlight()
			clearDisables()

registerRightClick = (treantConfig, callback) ->
	$container = $(treantConfig.container)

	$container.on 'contextmenu', (evt) ->
		if evt.target.classList.contains 'node'
			# visual changes
			clearDisables()
			evt.preventDefault()
			clearHighlight()
			evt.target.classList.add 'highlight'
			highlightedEl = evt.target

			# id's and positions
			cNodeId = evt.target.getAttribute 'cnodeid'
			tNodeId = parseInt evt.target.getAttribute 'tnodeid'
			$contextmenu.attr 'cnodeid', cNodeId
			$contextmenu.attr 'tnodeid', tNodeId
			$contextmenu.show().css({
				top: evt.clientY - 20,
				left: evt.clientX - 20
			})

			leftNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'leftNeighborId'
			rightNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'rightNeighborId'
			unless leftNeighborTId
				$left.addClass 'disabled'
			unless rightNeighborTId
				$right.addClass 'disabled'

	$erase.on 'click', (evt) ->
		if $erase.hasClass 'disabled' then return
		that = $(this)
		alertify.confirm 'Delete node?', ->
			# user clicked "ok"
			cNodeId = that.parent().attr 'cnodeid'
			tNodeId = parseInt that.parent().attr 'tnodeid'
			parentId = tActiveTree.getNodeAttribute(tNodeId, 'parentId')
			tActiveTree.removeNode tNodeId
			if parentId is -1 then tActiveTreeHasRoot = false
			callback {action: 'removeNode', cNodeId: cNodeId}
			$contextmenu.hide()
		, ->
			# user clicked "cancel"
			$contextmenu.hide()

	$left.on 'click', (evt) ->
		if $left.hasClass 'disabled' then return
		cNodeIdA = $(this).parent().attr 'cnodeid'
		tNodeId = parseInt $(this).parent().attr 'tnodeid'
		leftNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'leftNeighborId'
		cNodeIdB = tActiveTree.getNodeAttribute leftNeighborTId, 'cNodeId'
		tActiveTree.switchIndexes tNodeId, leftNeighborTId
		callback {action: 'switchNodes', cNodeIdA: cNodeIdA, cNodeIdB: cNodeIdB}
		$contextmenu.hide()

	$right.on 'click', (evt) ->
		if $right.hasClass 'disabled' then return
		cNodeIdA = $(this).parent().attr 'cnodeid'
		tNodeId = parseInt $(this).parent().attr 'tnodeid'
		rightNeighborTId = parseInt tActiveTree.getNodeAttribute tNodeId, 'rightNeighborId'
		cNodeIdB = tActiveTree.getNodeAttribute rightNeighborTId, 'cNodeId'
		tActiveTree.switchIndexes tNodeId, rightNeighborTId
		callback {action: 'switchNodes', cNodeIdA: cNodeIdA, cNodeIdB: cNodeIdB}
		$contextmenu.hide()

	$config.on 'click', (evt) ->
		if $config.hasClass 'disabled' then return
		tNodeId = $(this).parent().attr 'tnodeid'
		tNode = tActiveTree.getNode(tNodeId).nodeDOM

		if tActiveNodeId != tNodeId
			if tActiveNodeId then tNode.classList.remove 'highlight'
			if tActiveNodeId then tNode.classList.remove 'highlightOrange'
			highlightedEl = tNode
			tActiveNodeId = tNodeId
			tNode.classList.add 'highlight'
			cNodeId = $(this).parent().attr 'cnodeid'
			cActiveNode = cActiveTree.getNode cNodeId
			callback {action: 'showNodeMemory', cNodeId: cNodeId}
			memory.activate '#tab-nodeEditor'
			nodeConfig.load cActiveNode
			nodeConfig.positionEditor tNode
			nodeConfig.showEditor()
		else
			highlightedEl = null
			tActiveNodeId = null
			nodeConfig.hideEditor()
			tNode.classList.remove 'highlight'
			tNode.classList.remove 'highlightOrange'
		$contextmenu.hide()

	window.addEventListener 'resize', (evt) ->
		if tActiveTree
			tActiveTree.resize()


dragNode = (evt) ->
	transfer = JSON.stringify
		type: 'change',
		tid: evt.target.getAttribute('tnodeid'),
		cid: evt.target.getAttribute('cnodeid')

	evt.originalEvent.dataTransfer.setData 'text/plain', transfer

registerDragAndDrop = (treantConfig, callback) ->
	$container = $(treantConfig.container)
	$container.on 'dragover', (evt) ->
		if tActiveTreeHasRoot is false
			evt.preventDefault()
		else if evt.target.classList.contains 'node'
			parentCId = evt.target.getAttribute 'cnodeid'

			if evt.ctrlKey
				evt.target.classList.add 'highlightOrange'
				evt.target.classList.remove 'highlight'
				evt.preventDefault()
			else
				evt.target.classList.remove 'highlightOrange'
				# check if accepts children
				if cActiveTree.canNodeAcceptChild parentCId
					evt.target.classList.add 'highlight'
					evt.preventDefault()

	$container.on 'dragleave', (evt) ->
		if evt.target.classList.contains 'node'
			evt.target.classList.remove 'highlight'
			evt.target.classList.remove 'highlightOrange'

	$container.on 'drop', (evt) ->
		if tActiveTreeHasRoot is false
			evt.preventDefault()
			obj = JSON.parse evt.originalEvent.dataTransfer.getData 'text'
			callback {action: 'createRoot', behaviorId: obj.behaviorId}

		else if evt.target.classList.contains 'node'

			evt.preventDefault()
			evt.target.classList.remove 'highlight'
			evt.target.classList.remove 'highlightOrange'

			obj = JSON.parse evt.originalEvent.dataTransfer.getData 'text'
			parentCId = evt.target.getAttribute 'cnodeid'
			parentTId = parseInt evt.target.getAttribute 'tnodeid'

			if evt.ctrlKey
				# change node type
				callback {action: 'replaceNode', behaviorId: obj.behaviorId, parentCId: parentCId, parentTId: parentTId}
			else
				# add node
				switch obj.type
{'fraction_non_alphanumeric': 0.11899038461538461, 'fraction_numerical': 0.003252262443438914, 'mean_word_length': 4.432027649769585, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '474661', 'n_tokens_mistral': 5179, 'n_tokens_neox': 4734, 'n_words': 1016}